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.