当前位置: 代码迷 >> Android >> android相机
  详细解决方案

android相机

热度:167   发布时间:2016-04-28 06:41:07.0
android照相机



    使用相机的两种方式:
    1  使用Intent跳转到系统相机,action为:android.media.action.STILL_IMAGE_CAMERA 这中方法一般是最常用的 方便简单 毕竟自定义相机比较复杂 而且花费时间比较长
    代码片段,双击复制
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    packagebarry.android.c;
     
    importjava.io.File;
    importjava.io.FileNotFoundException;
    importjava.io.FileOutputStream;
    importjava.io.IOException;
     
    importandroid.app.Activity;
    importandroid.content.Intent;
    importandroid.graphics.Bitmap;
    importandroid.os.Bundle;
    importandroid.os.Environment;
    importandroid.provider.MediaStore;
    importandroid.util.Log;
    importandroid.view.View;
    importandroid.view.View.OnClickListener;
    importandroid.widget.Button;
    importandroid.widget.ImageView;
    /**
     *                 * @title MyCaremaActivity.java
                    * @package barry.android.c
                    * <a href="\"http://www.eoeandroid.com/home.php?mod=space&uid=100488\"" target="\"_blank\"">@email</a> <a href="\"mailto:[email protected]\"" target="\"_blank\"">[email protected]</a>
                    * @author szh
                    * <a href="\"http://www.eoeandroid.com/home.php?mod=space&uid=572753\"" target="\"_blank\"">@update</a> 2013-1-11 上午9:27:03
                    * @description   
     */
     
    publicclass MyCaremaActivity extendsActivity {
     
            @Override
            publicvoid onCreate(Bundle savedInstanceState) {
                    super.onCreate(savedInstanceState);
                    setContentView(R.layout.main);
     
                    Button button = (Button) findViewById(R.id.button);
     
                    button.setOnClickListener(newOnClickListener() {
     
                            @Override
                            publicvoid onClick(View v) {
                                    Intent intent = newIntent(MediaStore.ACTION_IMAGE_CAPTURE);//open camera
                                    startActivityForResult(intent,1);
                            }
                    });
            }
     
            @Override
            protectedvoid onActivityResult(intrequestCode, intresultCode, Intent data) {
                    super.onActivityResult(requestCode, resultCode, data);
     
                    if(resultCode == Activity.RESULT_OK) {
     
                            String sdStatus = Environment.getExternalStorageState();
                            if(sdStatus.equals(Environment.MEDIA_MOUNTED)) { // 检测sd是否可用
                                    Log.v("TestFile",
                                                    sdStatus+"SD card is not avaiable/writeable right now.");
                            }
     
                            Bundle bundle = data.getExtras();
                            Bitmap bitmap = (Bitmap) bundle.get("data");// 获取相机返回的数据,并转换为Bitmap图片格式
                            FileOutputStream b = null;
                            File file = newFile("/sdcard/myImage/");
                            file.mkdirs();// 创建文件夹
                            String fileName = "/sdcard/myImage/111.jpg";
     
                            try{
                                    b = newFileOutputStream(fileName);
                                    bitmap.compress(Bitmap.CompressFormat.JPEG,100, b);// 把数据写入文件
                            }catch(FileNotFoundException e) {
                                    e.printStackTrace();
                            }finally{
                                    try{
                                            b.flush();
                                            b.close();
                                    }catch(IOException e) {
                                            e.printStackTrace();
                                    }
                            }
     
                            ((ImageView) findViewById(R.id.imageView)).setImageBitmap(bitmap);// 将图片显示在ImageView里
                    }
            }
    }

    2  (1)首先我们要自己创建一个照相,必须考虑用什么控件显示照相机中的预览效果,显然android已经帮我们做好了选择,那就是
    SurfaceView,而控制SurfaceView则需要一个surfaceHolder,他是系统提供的一个用来设置surfaceView的一个对象,而它通过surfaceView.getHolder()这个方法来获得。而Camera提供一个setPreviewDisplay(SurfaceHolder)的方法来连接
    surfaceHolder,并通过他来控制surfaceView,而我们则使用android的Camera类提供了startPreview()和stopPreview()来开启和关闭预览.
    关系如下:
    Camera -- -->SurfaceHolder------>SurfaceView.
         (2)知道怎么预览了,当然也要知道怎么开启相机.Camera.open()这是个静态方法,如果相机没有别人用着,则会返回一个 相机引用,如果被人用着,则会抛出异常。很奇怪的是,这个方法,不能随便放,如放在构造方法或者onCreate()方法中,都会照成没有预览效果.
    (3) SurfaceHolder.Callback,这是个holder用来显示surfaceView 数据的接口,他分别必须实现3个方法
    surfaceCreated()这个方法是surface 被创建后调用的
    surfaceChanged()这个方法是当surfaceView发生改变后调用的
    surfaceDestroyed()这个是当surfaceView销毁时调用的.
    surfaceHolde通过addCallBack()方法将响应的接口绑定到他身上.
    surfaceHolder还必须设定一个setType()方法,查看api的时候,发现这个方法已经过时,但是没有写,又会报错。。各种奇怪。
    (4)
    我用以上知识写了一个MySurfaceView类,他继承于SurfaceView,并在里面实现了照相机的预览功能.这个我觉得最简单的照相机预览代码:
    代码片段,双击复制
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    packagecom.hipikids.mycamerademo;
     
    importjava.io.BufferedOutputStream;
    importjava.io.File;
    importjava.io.FileOutputStream;
    importjava.io.IOException;
    importandroid.app.Activity;
    importandroid.content.pm.ActivityInfo;
    importandroid.graphics.Bitmap;
    importandroid.graphics.BitmapFactory;
    importandroid.graphics.PixelFormat;
    importandroid.hardware.Camera;
    importandroid.hardware.Camera.AutoFocusCallback;
    importandroid.hardware.Camera.PictureCallback;
    importandroid.os.Bundle;
    importandroid.view.SurfaceHolder;
    importandroid.view.SurfaceView;
    importandroid.view.View;
    importandroid.view.Window;
    importandroid.view.SurfaceHolder.Callback;
    importandroid.view.View.OnClickListener;
     
    /**
     * * @title MainActivity.java
     *
     * @package com.hipikids.mycamerademo
     * <a href="\"http://www.eoeandroid.com/home.php?mod=space&uid=100488\"" target="\"_blank\"">@email</a> <a href="\"mailto:[email protected]\"" target="\"_blank\"">[email protected]</a>
     * @author szh
     * <a href="\"http://www.eoeandroid.com/home.php?mod=space&uid=572753\"" target="\"_blank\"">@update</a> 2013-1-10 下午5:21:00
     * @description
     */
    publicclass MainActivity extendsActivity implementsCallback,
                    OnClickListener, AutoFocusCallback {
            SurfaceView mySurfaceView;// surfaceView声明
            SurfaceHolder holder;// surfaceHolder声明
            Camera myCamera;// 相机声明
            String filePath = "/sdcard/wjh.jpg";// 照片保存路径
            booleanisClicked = false;// 是否点击标识
            // 创建jpeg图片回调数据对象
            PictureCallback jpeg = newPictureCallback() {
     
                    @Override
                    publicvoid onPictureTaken(byte[] data, Camera camera) {
                            // TODO Auto-generated method stub
                            try{// 获得图片
                                    Bitmap bm = BitmapFactory.decodeByteArray(data, 0, data.length);
                                    File file = newFile(filePath);
                                    BufferedOutputStream bos = newBufferedOutputStream(
                                                    newFileOutputStream(file));
                                    bm.compress(Bitmap.CompressFormat.JPEG,100, bos);// 将图片压缩到流中
                                    bos.flush();// 输出
                                    bos.close();// 关闭
                            }catch(Exception e) {
                                    e.printStackTrace();
                            }
     
                    }
            };
     
            /** Called when the activity is first created. */
            @Override
            publicvoid onCreate(Bundle savedInstanceState) {
                    super.onCreate(savedInstanceState);
                    requestWindowFeature(Window.FEATURE_NO_TITLE);// 无标题
                    // 设置拍摄方向
                    this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                    setContentView(R.layout.activity_main);
                    // 获得控件
                    mySurfaceView = (SurfaceView) findViewById(R.id.surface);
                    // 获得句柄
                    holder = mySurfaceView.getHolder();
                    // 添加回调
                    holder.addCallback(this);
                    // 设置类型
                    holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
                    // 设置监听
                    mySurfaceView.setOnClickListener(this);
            }
     
            @Override
            publicvoid surfaceChanged(SurfaceHolder holder, intformat, intwidth,
                            intheight) {
                    // TODO Auto-generated method stub
                    // 设置参数并开始预览
                    Camera.Parameters params = myCamera.getParameters();
                    params.setPictureFormat(PixelFormat.JPEG);
                    params.setPreviewSize(640,480);
                    myCamera.setParameters(params);
                    myCamera.startPreview();// open display
     
            }
     
            @Override
            publicvoid surfaceCreated(SurfaceHolder holder) {
                    // TODO Auto-generated method stub
                    // 开启相机
                    if(myCamera == null) {
                            myCamera = Camera.open(); // this method is a static method
                            try{
                                    myCamera.setPreviewDisplay(holder);// connection SurfaceHolder
                            }catch(IOException e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                            }
                    }
     
            }
     
            @Override
            publicvoid surfaceDestroyed(SurfaceHolder holder) {
                    // TODO Auto-generated method stub
                    // 关闭预览并释放资源
                    myCamera.stopPreview();// close display
                    myCamera.release();
                    myCamera = null;
     
            }
     
            @Override
            publicvoid onClick(View v) {
                    // TODO Auto-generated method stub
                    if(!isClicked) {
                            myCamera.autoFocus(this);// 自动对焦
                            isClicked = true;
                    }else{
                            myCamera.startPreview();// 开启预览
                            isClicked = false;
                    }
     
            }
     
            @Override
            publicvoid onAutoFocus(booleansuccess, Camera camera) {
                    // TODO Auto-generated method stub
                    if(success) {
                            // 设置参数,并拍照
                            Camera.Parameters params = myCamera.getParameters();
                            params.setPictureFormat(PixelFormat.JPEG);
                            params.setPreviewSize(640,480);
                            myCamera.setParameters(params);
                            myCamera.takePicture(null,null, jpeg);
                    }
     
            }
    }

    最后别忘了加权限
    代码片段,双击复制
    01
    02
    03
      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
       <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
       <uses-permission android:name="android.permission.CAMERA"/>
      相关解决方案