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 }
     
  • 相关阅读:
    Service Name Port Number Transport Protocol tcp udp 端口号16bit
    linux linux 互传文件 win 不通过 ftp sftp 往linux 传文件(文件夹)
    soft deletion Google SRE 保障数据完整性的手段
    Taylor series
    Taylor's theorem
    Moving average
    REQUEST
    Unix file types
    mysqld.sock
    Tunneling protocol
  • 原文地址:https://www.cnblogs.com/androidsj/p/3869892.html
Copyright © 2011-2022 走看看