zoukankan      html  css  js  c++  java
  • 19、照相机技术

    照相机有哪些功能

         Android SDK支持操作Android设备内置的照相机。从Android2.3开始,支持操作多个摄像头(主要指前置摄像头和后置照相机)。通过照相机可以拍照和录像。

    编写拍照程序需要考虑哪些方面
    是否支持照相机
     
    快速拍照和定制拍照
     
    存储
    照相机涉及到的主要API
    Camera

    SurfaceView、

    MediaRecorder
    Intent
    拍照和摄像程序可能涉及到的权限和特性

    <uses-permission android:name="android.permission.CAMERA" />

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <uses-permission android:name="android.permission.RECORD_AUDIO" />

    <uses-feature android:name="android.hardware.camera" />

    DEMO1
    拍照Demo
     1 <?xml version="1.0" encoding="utf-8"?>
     2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     3     android:layout_width="fill_parent"
     4     android:layout_height="fill_parent"
     5     android:orientation="vertical" >
     6 
     7     <Button
     8         android:id="@+id/btnTakePicture"
     9         android:layout_width="wrap_content"
    10         android:layout_height="wrap_content"
    11         android:text="拍照" />
    12 
    13     <ImageView
    14         android:id="@+id/imageview"
    15         android:layout_width="320dp"
    16         android:layout_height="240dp" />
    17 
    18 </LinearLayout>
     1 import android.app.Activity;
     2 import android.content.Intent;
     3 import android.graphics.Bitmap;
     4 import android.os.Bundle;
     5 import android.provider.MediaStore;
     6 import android.view.View;
     7 import android.view.View.OnClickListener;
     8 import android.widget.Button;
     9 import android.widget.ImageView;
    10 
    11 public class Main extends Activity implements OnClickListener {
    12     private ImageView imageView;
    13 
    14     @Override
    15     public void onCreate(Bundle savedInstanceState) {
    16         super.onCreate(savedInstanceState);
    17         setContentView(R.layout.main);
    18 
    19         Button btnTakePicture = (Button) findViewById(R.id.btnTakePicture);
    20         btnTakePicture.setOnClickListener(this);
    21 
    22         imageView = (ImageView) findViewById(R.id.imageview);
    23     }
    24 
    25     public void onClick(View view) {
    26         // 调用系统拍照
    27         Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    28         // 显示拍照窗口
    29         startActivityForResult(intent, 1);
    30     }
    31     
    32     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    33         if (requestCode == 1) {
    34             if (resultCode == Activity.RESULT_OK) {
    35                 Bitmap cameraBitmap = (Bitmap) data.getExtras().get("data");
    36                 imageView.setImageBitmap(cameraBitmap);
    37             }
    38         }
    39     }
    40 
    41 }
     1 <?xml version="1.0" encoding="utf-8"?>
     2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     3     package="cn.eoe.system.camera" android:versionCode="1"
     4     android:versionName="1.0">
     5     <application android:icon="@drawable/icon" android:label="@string/app_name">
     6         <activity android:name=".Main" android:label="@string/app_name">
     7             <intent-filter>
     8                   <action android:name="android.intent.action.MAIN" />
     9                 <category android:name="android.intent.category.LAUNCHER" />
    10             </intent-filter>
    11         </activity>    
    12     </application>
    13     <uses-sdk android:minSdkVersion="7" />
    14 </manifest> 
    录像Demo
     1 <?xml version="1.0" encoding="utf-8"?>
     2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     3     android:layout_width="fill_parent"
     4     android:layout_height="fill_parent"
     5     android:orientation="vertical" >
     6 
     7     <Button
     8         android:id="@+id/btnTakePicture"
     9         android:layout_width="wrap_content"
    10         android:layout_height="wrap_content"
    11         android:text="录像" />
    12 
    13     <VideoView
    14         android:id="@+id/videoview"
    15         android:layout_width="wrap_content"
    16         android:layout_height="wrap_content" />
    17 
    18 </LinearLayout>
     1 import android.app.Activity;
     2 import android.content.Intent;
     3 import android.database.Cursor;
     4 import android.net.Uri;
     5 import android.os.Bundle;
     6 import android.provider.MediaStore;
     7 import android.view.View;
     8 import android.view.View.OnClickListener;
     9 import android.widget.Button;
    10 import android.widget.MediaController;
    11 import android.widget.VideoView;
    12 
    13 public class Main extends Activity implements OnClickListener {
    14     public VideoView videoView;
    15 
    16     @Override
    17     public void onCreate(Bundle savedInstanceState) {
    18         super.onCreate(savedInstanceState);
    19         setContentView(R.layout.main);
    20         Button btnTakePicture = (Button) findViewById(R.id.btnTakePicture);
    21         btnTakePicture.setOnClickListener(this);
    22 
    23         videoView = (VideoView) findViewById(R.id.videoview);
    24 
    25     }
    26     
    27     public void onClick(View view) {
    28         Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
    29         startActivityForResult(intent, 1);
    30     }
    31 
    32     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    33         if (requestCode == 1) {
    34             if (resultCode == Activity.RESULT_OK) {
    35                 Uri uri = data.getData();
    36                 Cursor cursor = this.getContentResolver().query(uri, null,
    37                         null, null, null);
    38 
    39                 if (cursor.moveToFirst()) {
    40                     // 取出路径
    41                     String videoPath = cursor.getString(cursor
    42                             .getColumnIndex("_data"));
    43                     // 加载
    44                     videoView.setVideoURI(Uri.parse(videoPath));
    45                     // 设置视频控制控件(停止,快进等)。
    46                     videoView.setMediaController(new MediaController(this));
    47                     // 播放。
    48                     videoView.start();
    49                 }
    50             }
    51         }
    52     }
    53 
    54 }
     1 <?xml version="1.0" encoding="utf-8"?>
     2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     3     package="cn.eoe.record.video" android:versionCode="1"
     4     android:versionName="1.0">
     5     <application android:icon="@drawable/icon" android:label="@string/app_name">
     6         <activity android:name="Main" android:label="@string/app_name">
     7             <intent-filter>
     8                   <action android:name="android.intent.action.MAIN" />
     9                 <category android:name="android.intent.category.LAUNCHER" />
    10             </intent-filter>
    11         </activity>    
    12     </application>
    13     <uses-sdk android:minSdkVersion="7" />
    14 </manifest> 
     
    定制拍照程序的步骤
    打开照相机:Camera.open
     
    创建SurfaceView对象
     
    添加回调事件监听器(SurfaceHolder.addCallback)
     
    预览(Camera.startPreview)
     
    拍照(Camera.takePicture)
    检测Android设备是否支持照相机

    private boolean checkCameraHardware(Context context) {

        if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA))

        {  return true; }  else  {   return false; }

    }

    DEMO2
      1 package cn.eoe.custom.camera;
      2 
      3 import java.io.File;
      4 import java.io.FileOutputStream;
      5 import java.util.List;
      6 
      7 import android.app.Activity;
      8 import android.content.Context;
      9 import android.hardware.Camera;
     10 import android.hardware.Camera.PictureCallback;
     11 import android.hardware.Camera.Size;
     12 import android.os.Bundle;
     13 import android.view.SurfaceHolder;
     14 import android.view.SurfaceView;
     15 import android.view.View;
     16 import android.view.View.OnClickListener;
     17 import android.view.ViewGroup;
     18 import android.view.Window;
     19 import android.view.WindowManager;
     20 
     21 public class CustomCameraActivity extends Activity {
     22     private Camera mCamera;
     23     private Preview mPreview;
     24 
     25     @Override
     26     protected void onCreate(Bundle savedInstanceState) {
     27         super.onCreate(savedInstanceState);
     28         // 设置为全屏
     29         requestWindowFeature(Window.FEATURE_NO_TITLE);
     30         getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
     31         mPreview = new Preview(this);
     32         setContentView(mPreview);
     33     }
     34 
     35     protected void onResume() {
     36         super.onResume();
     37         // 打开照相机
     38         mCamera = Camera.open();
     39         mPreview.setCamera(mCamera);
     40     }
     41 
     42     protected void onPause() {
     43         super.onPause();
     44 
     45         if (mCamera != null) {
     46             mCamera.release();
     47             mCamera = null;
     48             mPreview.setCamera(null);
     49         }
     50     }
     51 
     52     class Preview extends ViewGroup implements SurfaceHolder.Callback,
     53             OnClickListener {
     54 
     55         SurfaceView mSurfaceView;
     56         SurfaceHolder mHolder; // 存储事件回掉
     57         Size mPreviewSize;  // 当前窗口预览尺寸
     58         List<Size> mSupportedPreviewSizes; // 相机中的预览尺寸
     59         Camera mCamera;
     60         Context mContext;  
     61 
     62         public Preview(Context context) {
     63             super(context);
     64             mContext = context;
     65             mSurfaceView = new SurfaceView(context);
     66             addView(mSurfaceView);
     67             mHolder = mSurfaceView.getHolder();
     68             mHolder.addCallback(this);
     69 
     70         }
     71 
     72         public void setCamera(Camera camera) {
     73             mCamera = camera;
     74             if (mCamera != null) {
     75                 // 获得当前相机可支持预览的尺寸。
     76                 mSupportedPreviewSizes = mCamera.getParameters()
     77                         .getSupportedPictureSizes();
     78                 // 调整布局。
     79                 requestLayout();
     80             }
     81         }
     82 
     83         private PictureCallback mPictureCallback = new PictureCallback() {
     84 
     85             @Override
     86             public void onPictureTaken(byte[] data, Camera camera) {
     87                 mCamera.startPreview();
     88                 File pictureFile = new File("/sdcard/image.jpg");
     89                 try {
     90                     FileOutputStream fos = new FileOutputStream(pictureFile);
     91                     fos.write(data);
     92                     fos.close();
     93                 } catch (Exception e) {
     94                     // TODO: handle exception
     95                 }
     96 
     97             }
     98         };
     99 
    100         public void onClick(View view) {
    101             mCamera.takePicture(null, null, mPictureCallback);
    102         }
    103 
    104         @Override
    105         public void surfaceChanged(SurfaceHolder holder, int format, int width,
    106                 int height) {
    107             // 设置预览的尺寸(不支持比如:200 200这种尺寸)。
    108             Camera.Parameters parameters = mCamera.getParameters();
    109             parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
    110 
    111             mCamera.setParameters(parameters);
    112             mCamera.startPreview();  // 预览
    113 
    114         }
    115 
    116         @Override
    117         public void surfaceCreated(SurfaceHolder holder) {
    118             try {
    119                 if (mCamera != null) {
    120                     // 将 Camera和SurfaceView进行一个关联。
    121                     mCamera.setPreviewDisplay(holder);
    122                 }
    123             } catch (Exception e) {
    124                 // TODO: handle exception
    125             }
    126 
    127         }
    128 
    129         @Override
    130         public void surfaceDestroyed(SurfaceHolder holder) {
    131             // TODO Auto-generated method stub
    132             if (mCamera != null) {
    133                 // 停止预览
    134                 mCamera.stopPreview();
    135             }
    136         }
    137 
    138         @Override  // 调整预览尺寸。
    139         protected void onLayout(boolean changed, int l, int t, int r, int b) {
    140             if (changed && getChildCount() > 0) {  //子视图
    141                 // 获得子视图。
    142                 final View child = getChildAt(0);
    143 
    144                 // viewGroup
    145                 int width = r - l;    
    146                 int height = b - t;    
    147 
    148                 // 实际窗口尺寸。
    149                 int previewWidth = width;
    150                 int previewHeight = height;
    151 
    152                 // mPreviewSize 图像产生的。
    153                 if (mPreviewSize != null) { 
    154                     // 把前两个初始值覆盖。 
    155                     previewWidth = mPreviewSize.width;
    156                     previewHeight = mPreviewSize.height;
    157                 }
    158                 // 手机屏幕的宽高比大于采集图像的宽高比。
    159                 if (width * previewHeight > height * previewWidth) {
    160                     final int scaledChildWidth = previewWidth * height
    161                             / previewHeight;
    162                     // child.layout((width - scaledChildWidth)/2,
    163                     // 0,(width+scaledChildWidth)/2,height);
    164 
    165                     child.layout(100, 100, 340, 240);
    166                 } else {
    167                     final int scaledChildHeight = previewHeight * width
    168                             / previewWidth;
    169                     child.layout(0, (height - scaledChildHeight) / 2, width,
    170                             (height + scaledChildHeight) / 2);
    171                 }
    172 
    173             }
    174 
    175         }
    176 
    177         private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
    178             double ASPECT_TOLERANCE = 0.1;
    179             double targetRatio = (double) w / h;
    180             if (sizes == null)
    181                 return null;
    182 
    183             Size optimalSize = null;
    184             double minDiff = Double.MAX_VALUE;
    185             int targetHeight = h;
    186 
    187             for (Size size : sizes) {
    188                 double ratio = (double) size.width / size.height;
    189                 if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) {
    190                     continue;
    191                 }
    192                 if (Math.abs(size.height - targetHeight) < minDiff) {
    193                     optimalSize = size;
    194                     minDiff = Math.abs(size.height - targetHeight);
    195                 }
    196             }
    197 
    198             if (optimalSize == null) {
    199                 minDiff = Double.MAX_VALUE;
    200                 for (Size size : sizes) {
    201                     if (Math.abs(size.height - targetHeight) < minDiff) {
    202                         optimalSize = size;
    203                         minDiff = Math.abs(size.height - targetHeight);
    204                     }
    205                 }
    206             }
    207             return optimalSize;
    208         }
    209 
    210         protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    211             int width = resolveSize(getSuggestedMinimumWidth(),
    212                     widthMeasureSpec);
    213             int height = resolveSize(getSuggestedMinimumHeight(),
    214                     heightMeasureSpec);
    215 
    216             setMeasuredDimension(width, height);
    217 
    218             if (mSupportedPreviewSizes != null) {
    219                 mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes,
    220                         width, height);
    221             }
    222         }
    223 
    224     }
    225 
    226 }
     
  • 相关阅读:
    实验十四 团队项目评审&个人学习总结
    实验四 附加实验项目互评
    201671010401 包稚潼+《英文文本统计分析》结队项目报告
    201671010401包稚潼 实验二 词频统计软件项目报告
    201671010401包稚潼 实验三作业互评与改进
    阅读《构建之法》提出的相关问题
    201671010404+陈润菊 实验十四 团队项目评审课程&学习总结
    201671010404+陈润菊 实验四 附加作业-项目互评
    201671010404+陈润菊 实验四《英文文本统计分析》结对项目报告
    201671010404+陈润菊 实验二软件工程项目
  • 原文地址:https://www.cnblogs.com/androidsj/p/3869892.html
Copyright © 2011-2022 走看看