Android calls Camera to get the image in the preview frame

Reprinted from http://blog.csdn.net/u013869488/article/details/49853217

1:  It is not difficult to describe
Android development to realize Camera customization. The main steps are as follows:

  • Open the camera, that is, instantiate the Camera object, Camera camera = Camera.open();
  • Set the relevant parameters of the Camera, Camera.Parameters parameters = camera.getParameters();
  • Open the preview, camera.setPreviewDisplay(surfaceholder); camera.startPreview();
  • Get the picture, here just get it from the preview so use, camera.setPreviewCallback(new Camera.PreviewCallback(){……..});
  • Stop the preview, release the camera, camera.stopPreview();camera.release();

2: So the question is, is this enough? 
Of course, we also need a place to display the image previewed by the Camera. So you need a control called SurfaceView, and a SurfaceHolder to control the display. Proceed as follows:

  • 定义SurfaceView控件; SurfaceView mySurfaceView = (SurfaceView)findViewById(R.id.id_mySurfaceView);
  • Instantiate SurfaceHolder, which is where the preview processing is implemented. When the camera opens the preview, set camera.setPreviewDisplay(surfaceholder); to indicate that the preview is implemented on the SurfaceHolder. Of course the instantiation is implemented like this: SurfaceHolder surfaceHolder = mySurfaceView .getHolder();
  • Set a callback for the SurfaceHolder, which is similar to monitoring, except that it mainly monitors the relevant status of the Camera; surfaceHolder.addCallback(this);
  • Implement the SurfaceHolder.Callback interface, similar to the implementation of the corresponding monitoring interface when monitoring is scheduled. Then there are three methods to implement.

3: Explain in detail the three functions corresponding to the SurfaceHolder.Callback interface: 
(1) surfaceCreated method:

@Override
    public void surfaceCreated(SurfaceHolder holder) {
    //一般在这里实现相机打开
    //相机在这里设置相关参数也是可以的
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

(2) surfaceChanged method:

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
//在这里也可以设置Camera的参数
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

(3) surfaceDestroyed method:

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
    //主要在这里实现Camera的释放
        if (camera!=null) {
            camera.release();
            camera=null;
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

4: Where to get pictures? 
If this is our main task, it seems that we don't need to open the camera if we don't get pictures. 
You can define a button to get the picture, and call the method to get the picture, so let's start to get the method of getting the preview frame picture:

private void getPreViewImage() {

camera.setPreviewCallback(new Camera.PreviewCallback(){

@Override
public void onPreviewFrame(byte[] data, Camera camera) {
 Size size = camera.getParameters().getPreviewSize();          
 try{  
     YuvImage image = new YuvImage(data, ImageFormat.NV21, size.width, size.height, null);  
     if(image!=null){  
                     ByteArrayOutputStream stream = new ByteArrayOutputStream();  
                    image.compressToJpeg(new Rect(0, 0, size.width, size.height), 80, stream); 

                   Bitmap bmp = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size());  

                    //**********************
                    //因为图片会放生旋转,因此要对图片进行旋转到和手机在一个方向上
                    rotateMyBitmap(bmp);
                    //**********************************

         stream.close();  
    }  
 }catch(Exception ex){  
  Log.e("Sys","Error:"+ex.getMessage());  
  }  
}   
});
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

Here is the image rotation function:

public void rotateMyBitmap(Bitmap bmp){
  //*****旋转一下
Matrix matrix = new Matrix();
 matrix.postRotate(90);

 Bitmap bitmap = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), Bitmap.Config.ARGB_8888);

Bitmap nbmp2 = Bitmap.createBitmap(bmp, 0,0, bmp.getWidth(),  bmp.getHeight(), matrix, true);

//*******显示一下
imageView.setImageBitmap(nbmp2);

};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

5: At this point, it seems that the preview frame acquisition of the picture is also realized. 
But there are still several problems: 
(1) Camera parameter settings:

public void initCamera(){
//CameraID表示0或者1,表示是前置摄像头还是后置摄像头
camera = Camera.open(CameraID);
camera.setDisplayOrientation(90);
//参数设置
Camera.Parameters parameters = camera.getParameters();
//设置放大倍数
parameters.setZoom(12);
//开启闪光灯         parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); 
//参数设置赋给Camera对象
camera.setParameters(parameters);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

(2) The problem of obtaining the preview frame 
camera.setPreviewCallback(new Camera.PreviewCallback(){……..}); 
The obtained preview frame is the image obtained by the camera in real time, but in fact I just want to obtain one picture in one second The picture is only, so set

    Handler handle = new Handler(){ 
        public void handleMessage(android.os.Message msg) {
            switch(msg.what){

            case BUFFERTAG:
                if(isGetBuffer){
                    getPreViewImage();
                    btnGetBuffer.setText("开始图片1");
                    handler.sendEmptyMessageDelayed(BUFFERTAG1, 300);

                }else{
                    camera.setPreviewCallback(null);
                }
                break;
            case BUFFERTAG1:
                camera.setPreviewCallback(null);
                handler.sendEmptyMessageDelayed(BUFFERTAG, 5000);
                break ;


            }

        };
        };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

(3) When switching 
the camera, first release the existing camera, and then turn it on again; 
(4) The problem of turning off the flash 
is to set the corresponding parameters of the Camera and reset it again.

            Camera.Parameters parameters = camera.getParameters();

            //开启闪光灯
            parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); 
    //关闭摄像头  //parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); 
            camera.setParameters(parameters);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

6: At the end 
of this, you can selectively obtain the picture of the preview frame of the camera.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325809133&siteId=291194637