1.布局
xml version="1.0" encoding="utf-8"?>xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/viewfinder_mask"> android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_above="@+id/photo_graph_opt_layout"> android:id="@+id/sv_camera" android:layout_width="fill_parent" android:layout_height="fill_parent" /> android:id="@+id/photo_graph_img" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/front" android:layout_margin="@dimen/margin_30"/> android:id="@+id/photograph_img_layout" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@color/Black" android:visibility="gone"> android:id="@+id/photograph_img" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="fitCenter" android:layout_centerInParent="true" android:layout_marginTop="@dimen/margin_10" android:layout_marginBottom="@dimen/margin_10"/> android:id="@+id/photo_graph_opt_layout" android:layout_width="fill_parent" android:layout_height="@dimen/height_80" android:layout_alignParentBottom="true" android:background="@color/Black"> android:id="@+id/photo_graph_take" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="拍照" android:background="@drawable/oval_photo_shape" android:layout_centerInParent="true" android:gravity="center" android:textColor="@color/Black"/> android:id="@+id/photo_graph_delete" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="取消" android:background="@drawable/oval_photo_shape" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:gravity="center" android:textColor="@color/Black" android:layout_marginLeft="@dimen/margin_10" android:visibility="gone"/> android:id="@+id/photo_graph_config" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="确定" android:background="@drawable/oval_photo_shape" android:layout_centerInParent="true" android:gravity="center" android:textColor="@color/Black" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight="@dimen/margin_10" android:visibility="gone"/>
2.用法
import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.graphics.PixelFormat; import android.hardware.Camera; import android.hardware.Camera.PictureCallback; import android.media.ExifInterface; import android.net.Uri; import android.os.Bundle; import android.support.v7.widget.LinearLayoutCompat; import android.util.Log; import android.view.LayoutInflater; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView; import com.tm.eyoukemerchant.R; import com.tm.eyoukemerchant.base.BaseActivity; import com.tm.eyoukemerchant.utils.CameraFileUtil; import com.tm.eyoukemerchant.utils.CameraUtil; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.List; import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; import cmp.com.common.helper.CommonMethods; import cmp.com.common.helper.DialogHelper; import cmp.com.common.helper.ImageCompressHelper; import cmp.com.common.interfaces.ICustomCallBack; public class PhotographActivity extends BaseActivity implements SurfaceHolder.Callback { @BindView(R.id.photo_graph_take) TextView photoGraphTack; @BindView(R.id.photograph_img) ImageView photoGraphImage; @BindView(R.id.photo_graph_delete) TextView photoGraphCancle; @BindView(R.id.photo_graph_config) TextView photoGraphConfig; @BindView(R.id.sv_camera) SurfaceView mySurfaceView; @BindView(R.id.photo_graph_img) ImageView photoGraphFrame; @BindView(R.id.photograph_img_layout) RelativeLayout photoGraphImgLayout; private SurfaceHolder mySurfaceHolder = null; private Camera myCamera = null; private Camera.Parameters myParameters; private Bitmap bm; //拍照图片保存路径 private static final String IMG_PATH = "demo"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_photograph); ButterKnife.bind(this); setToolBarTitle("身份证正面"); if (!getIntent().getStringExtra("direction").equals("front")) { photoGraphFrame.setImageResource(R.mipmap.back); setToolBarTitle("身份证反面"); } mySurfaceView.setZOrderOnTop(false); mySurfaceHolder = mySurfaceView.getHolder(); mySurfaceHolder.setFormat(PixelFormat.TRANSLUCENT); mySurfaceHolder.addCallback(this); mySurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); photoGraphTack.setClickable(false); initCamera(); } @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); Log.i(TAG, "onResume"); if (myCamera == null) { initCamera(); } } @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); Log.i(TAG, "onDestroy"); if (myCamera != null) { myCamera.setPreviewCallback(null); myCamera.stopPreview(); myCamera.release(); myCamera = null; } } @Override public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { // TODO Auto-generated method stub Log.i(TAG, "surfaceChanged"); } @Override public void surfaceCreated(SurfaceHolder holder) { // TODO Auto-generated method stub Log.i(TAG, "surfaceCreated"); try { if (myCamera == null) { return; } setCameraParams(myCamera, PhotographActivity.this.getWindowManager().getDefaultDisplay().getWidth(), PhotographActivity.this.getWindowManager().getDefaultDisplay().getHeight()); myCamera.setPreviewDisplay(mySurfaceHolder); myCamera.startPreview(); photoGraphTack.setClickable(true); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void surfaceDestroyed(SurfaceHolder holder) { // TODO Auto-generated method stub Log.i(TAG, "surfaceDestroyed"); try { if (myCamera != null) { myCamera.setPreviewCallback(null); myCamera.stopPreview(); myCamera.release(); myCamera = null; } } catch (Exception e) { e.printStackTrace(); } } /** * 拍照后经过压缩处理的图片 */ PictureCallback myjpegCalback = new PictureCallback() { public void onPictureTaken(byte[] data, Camera camera) { // TODO Auto-generated method stub if (data != null) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 2; Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options); /*myCamera.stopPreview(); myCamera.release(); myCamera = null;*/ bm = bitmap; /*Bitmap sizeBitmap = Bitmap.createScaledBitmap(bitmap, topView.getViewWidth(), topView.getViewHe ight(), true); bm = Bitmap.createBitmap(sizeBitmap, topView.getRectLeft(), topView.getRectTop(), topView.getRectRight() - topView.getRetctLeft(), topView.getRectBottom() - topView.getRectTop());// 截取*/ photoGraphImage.setImageBitmap(bitmap); photoGraphCancle.setVisibility(View.VISIBLE); photoGraphConfig.setVisibility(View.VISIBLE); photoGraphTack.setVisibility(View.GONE); photoGraphFrame.setVisibility(View.GONE); photoGraphImgLayout.setVisibility(View.VISIBLE); } } }; // 初始化摄像头 public void initCamera() { if (myCamera == null) { myCamera = CameraUtil.getCameraInstance(PhotographActivity.this); } if (myCamera != null) { myParameters = myCamera.getParameters(); myParameters.setPictureFormat(PixelFormat.JPEG); myParameters.set("rotation", 90); if (CameraUtil.getCameraFocusable(myParameters) != null) { myParameters.setFocusMode(CameraUtil.getCameraFocusable(myParameters)); } myCamera.setDisplayOrientation(90);//这个就是设置屏幕需要旋转90度,一般没这句话屏幕内的东西都是纵向的... myCamera.setParameters(myParameters); } else { DialogHelper.Alert(PhotographActivity.this, "打开相机失败,请检查拍照权限", "去设置", "取消", new ICustomCallBack() { @Override public void Confirm() { CommonMethods.intentSettingClick(PhotographActivity.this); } @Override public void Cancle() { PhotographActivity.this.finish(); } }); } } private String TAG = "log"; /** * 根据不同的机型去设置相机拍照的图片大小 否则拍出来的图片会被缩放 * * @param camera * @param width * @param height */ private void setCameraParams(Camera camera, int width, int height) { if (myCamera == null) { myCamera = CameraUtil.getCameraInstance(PhotographActivity.this); } if (myCamera != null) { myParameters = myCamera.getParameters(); myParameters.setPictureFormat(PixelFormat.JPEG); myParameters.set("rotation", 90); if (CameraUtil.getCameraFocusable(myParameters) != null) { myParameters.setFocusMode(CameraUtil.getCameraFocusable(myParameters)); } myCamera.setDisplayOrientation(90);//这个就是设置屏幕需要旋转90度,一般没这句话屏幕内的东西都是纵向的... Log.i(TAG, "setCameraParams width=" + width + " height=" + height); Camera.Parameters parameters = camera.getParameters(); // 获取摄像头支持的PictureSize列表 ListpictureSizeList = parameters.getSupportedPictureSizes(); for (Camera.Size size : pictureSizeList) { Log.i(TAG, "pictureSizeList size.width=" + size.width + " size.height=" + size.height); } /**从列表中选取合适的分辨率*/ Camera.Size picSize = getProperSize(pictureSizeList, ((float) height / width)); if (null == picSize) { Log.i(TAG, "null == picSize"); picSize = parameters.getPictureSize(); } Log.i(TAG, "picSize.width=" + picSize.width + " picSize.height=" + picSize.height); // 根据选出的PictureSize重新设置SurfaceView大小 float w = picSize.width; float h = picSize.height; parameters.setPictureSize(picSize.width, picSize.height); // 获取摄像头支持的PreviewSize列表 List previewSizeList = parameters.getSupportedPreviewSizes(); for (Camera.Size size : previewSizeList) { Log.i(TAG, "previewSizeList size.width=" + size.width + " size.height=" + size.height); } Camera.Size preSize = getProperSize(previewSizeList, ((float) height) / width); if (null != preSize) { Log.i(TAG, "preSize.width=" + preSize.width + " preSize.height=" + preSize.height); parameters.setPreviewSize(preSize.width, preSize.height); } parameters.setJpegQuality(100); // 设置照片质量 if (CameraUtil.getCameraFocusable(myParameters) != null) { myParameters.setFocusMode(CameraUtil.getCameraFocusable(myParameters)); } camera.cancelAutoFocus();//自动对焦。 camera.setDisplayOrientation(90);// 设置PreviewDisplay的方向,效果就是将捕获的画面旋转多少度显示 camera.setParameters(parameters); } else { DialogHelper.Alert(PhotographActivity.this, "打开相机失败,请检查拍照权限", "去设置", "取消", new ICustomCallBack() { @Override public void Confirm() { CommonMethods.intentSettingClick(PhotographActivity.this); } @Override public void Cancle() { PhotographActivity.this.finish(); } }); } } /** * 从列表中选取合适的分辨率 * 默认w:h = 4:3 * 注意:这里的w对应屏幕的height * h对应屏幕的width */ private Camera.Size getProperSize(List pictureSizeList, float screenRatio) { Log.i(TAG, "screenRatio=" + screenRatio); Camera.Size result = null; for (Camera.Size size : pictureSizeList) { float currentRatio = ((float) size.width) / size.height; if (currentRatio - screenRatio == 0) { result = size; break; } } if (null == result) { for (Camera.Size size : pictureSizeList) { float curRatio = ((float) size.width) / size.height; if (curRatio == 4f / 3) { // 默认w:h = 4:3 result = size; break; } } } return result; } @OnClick({R.id.photo_graph_take, R.id.photo_graph_delete, R.id.photo_graph_config}) public void onClick(View view) { switch (view.getId()) { case R.id.photo_graph_take://拍照 myCamera.takePicture(null, null, myjpegCalback); break; case R.id.photo_graph_delete://拍照后预览取消 重新拍照 photoGraphCancle.setVisibility(View.GONE); photoGraphConfig.setVisibility(View.GONE); photoGraphTack.setVisibility(View.VISIBLE); photoGraphImgLayout.setVisibility(View.GONE); photoGraphFrame.setVisibility(View.VISIBLE); if (myCamera == null) { initCamera(); } // 重新拍照 try { setCameraParams(myCamera, PhotographActivity.this.getWindowManager().getDefaultDisplay().getWidth(), PhotographActivity.this.getWindowManager().getDefaultDisplay().getHeight()); myCamera.setPreviewDisplay(mySurfaceHolder); myCamera.startPreview(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } break; case R.id.photo_graph_config://拍照后预览确定 File file = CameraFileUtil.getOutputMediaFile(PhotographActivity.this, IMG_PATH); if (file != null && bm != null) { FileOutputStream fout; try { fout = new FileOutputStream(file); BufferedOutputStream bos = new BufferedOutputStream( fout); bm.compress(Bitmap.CompressFormat.JPEG, 100, bos); bos.flush(); bos.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } //返回数据 Intent intent = new Intent(); intent.putExtra("IDCardImageLocation", file.getAbsolutePath()); setResult(PhotographActivity.RESULT_OK, intent); } PhotographActivity.this.finish(); break; } } }
public class CameraFileUtil { /** * 创建文件用来保存图片 */ public static File getOutputMediaFile(Context context,String savePackage) { File mediaStorageDir = null; if (Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED)) { mediaStorageDir = new File( Environment .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), savePackage); if (!mediaStorageDir.exists()) { if (!mediaStorageDir.mkdirs()) { return null; } } } else { Toast.makeText(context, "没有sd卡", Toast.LENGTH_SHORT).show(); return null; } String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss") .format(new Date()); File mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg"); return mediaFile; } }
import android.content.Context; import android.content.pm.PackageManager; import android.hardware.Camera; import android.util.Log; import java.util.List; public class CameraUtil { /** * 判断设备是否支持相机硬件 */ private static boolean checkCameraHardware(Context context) { return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA); } /** * 安全启动相机 */ public static Camera getCameraInstance(Context context) { Camera c = null; try { if (getCameraId(context) >= 0) { c = Camera.open(getCameraId(context)); // attempt to get a Camera } else { return null; } } catch (Exception e) { Log.e("getCameraInstance", e.toString()); } return c; } /** * 摄像机前后摄像头判断 取后摄像头 * @return */ private static int getCameraId(Context context) { if (!checkCameraHardware(context)) { return -1; } int cNum = Camera.getNumberOfCameras(); int defaultCameraId = -1; Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); for (int i = 0; i < cNum; i++) { Camera.getCameraInfo(i, cameraInfo); if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) { defaultCameraId = i; } } return defaultCameraId; } /** * 获取相机的对焦方式 * * @return */ public static String getCameraFocusable(Camera.Parameters myParameters) { ListfocusModes = myParameters.getSupportedFocusModes(); if (focusModes .contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) { return Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE; } else if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) { return Camera.Parameters.FOCUS_MODE_AUTO; } return null; } }