自定义相机截取选取框中的图片
先上一张效果图:
使用自定义相机我们需要知道这3个类:
- android.hardware.Camera //相机的实例
- android.view.SurfaceView //用来展示相机预览画面的控件
- android.view.SurfaceHolder //通过这个类将Camera和SurfaceView之间建立连接
重点要点:
添加权限。
uses-feature android:name=”android.hardware.camera”
uses-feature android:name=”android.hardware.camera.autofocus”
uses-permission android:name=”android.permission.CAMERA”自定义相机要想正常在手机上显示预览画面,点击拍照后能够获取到正常的图片,还需要设置Camera对象的一系列参数。
通过camera.getParameters()获得Parameters对象设置参数。需要明白三种尺寸:
1.Surfaceview的尺寸
Surfaceview是用来展示Camera预览画面的,当它全屏时就是Screen的大小。2.Picturesize的尺寸
这是拍照后得到的照片尺寸。3.Previewsize的尺寸
这是预览时Camera预览画面的尺寸。三种变形 :
1.预览画面的物体长宽失真。原因是Surfaceview和Previewsize的长宽比率不一致,就会导致预览画面上失真。因为camera在显示时会将预览帧数据缩放成Surfaceview大小,当比率不一致必然会物体变形。至于这个缩放算法可能不同手机得到的结果不同。
2.拍照后照片上物体变形。
3.点击拍照瞬间,预览画面上会突然变形然后恢复到正常预览。
2、3两种变形都是因为Previewsize和Picturesize的长宽比率不一致所致。总之一句话,为了保证图片不是真,要保证预览Surfaceview、Previewsize、Picturesize的长宽比率要一直。如果Surfaceview是全屏的话,要获取屏幕长和宽得到比率。
[参考:]http://blog.csdn.net/yanzi1225627/article/details/17652643)
- 在设置setPreviewSize和setPictureSize时个人觉得主要遵循一个原则:保证setPreviewSize,setPictureSize和Surfaceview的分辨率的长宽比三者尽量一致。这样预览的时候就不会变形,得到的照片也许分辨率尺寸不同但是长宽比例是一致的,这样我们就可以根据Surfaceview与照片之间的缩放比计算出实际要截取的位置起点和大小。大家可以根据这个原则去改善获取最佳分辨率的算法,我的是我自己根据这个思路去改写的。但是还是存一些问题。
camera2.xml
自定义相机布局文件
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants"
android:orientation="vertical">
<!-- 显示预览图形 -->
<com.example.camera.MaskSurfaceView
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<include
android:id="@+id/camera_header_bar"
layout="@layout/camera_header_bar" />
<include
android:id="@+id/camera_bottom_bar"
layout="@layout/camera_bottom_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom" />
<ImageView
android:id="@+id/result"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:visibility="gone"/>
</FrameLayout>
CustomCamera2 .java
自定义相机界面
public class CustomCamera2 extends Activity implements View.OnClickListener, OnCaptureCallback {
private MaskSurfaceView surfaceView;
private ImageView flashSwitch;
private ImageView result;
private CameraHelper helper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.camera2);
//获取相机拍取图片类型
Intent intent = getIntent();
// int imagetype = intent.getIntExtra(IMAGE_TYPE, -1);
String imagepatch = intent.getStringExtra("IMAGEPATCH");
//初始化surfaceView,设置照片保存路径
surfaceView = (MaskSurfaceView) findViewById(R.id.container);
surfaceView.setResourceid(R.drawable.idborder1);
// if (imagetype==0){
// surfaceView.setResourceid(R.drawable.idborder1);
// }else if (imagetype==1){
// surfaceView.setResourceid(R.drawable.idborder2);
// }
surfaceView.setMaskSize((int) ScreenUtil.dpToPx(this, 252), (int) ScreenUtil.dpToPx(this, 400));
surfaceView.setOnClickListener(this);
helper = CameraHelper.getInstance();
helper.setPictureSaveDictionaryPath("/storage/emulated/0/DCIM/test");
//拍照结果
result = (ImageView) findViewById(R.id.result);
result.setOnClickListener(this);
//初始化拍照按钮
ImageButton takePicture = (ImageButton) findViewById(R.id.btn_shutter_camera);
takePicture.setOnClickListener(this);
//初始化闪光灯开个按钮
flashSwitch = (ImageView) findViewById(R.id.btn_flash_mode);
flashSwitch.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_shutter_camera:
CameraHelper.getInstance().tackPicture(CustomCamera2.this);
break;
case R.id.btn_flash_mode:
if (helper.getFlashMode() == CameraHelper.FlashMode.ON) {
helper.setFlashMode(CameraHelper.FlashMode.OFF);
flashSwitch.setImageResource(R.drawable.btn_flash_off);
} else if (helper.getFlashMode() == CameraHelper.FlashMode.OFF) {
helper.setFlashMode(CameraHelper.FlashMode.AUTO);
flashSwitch.setImageResource(R.drawable.btn_flash_auto);
} else if (helper.getFlashMode() == CameraHelper.FlashMode.AUTO) {
helper.setFlashMode(CameraHelper.FlashMode.TORCH);
flashSwitch.setImageResource(R.drawable.btn_flash_torch);
} else if (helper.getFlashMode() == CameraHelper.FlashMode.TORCH) {
helper.setFlashMode(CameraHelper.FlashMode.ON);
flashSwitch.setImageResource(R.drawable.btn_flash_on);
}
break;
case R.id.container:
CameraHelper.getInstance().AutoFocus(null);
break;
case R.id.result:
result.setVis