当前位置 : 主页 > 编程语言 > java >

相机拍照代码

来源:互联网 收集:自由互联 发布时间:2021-06-28
TakePhotoActivity.java import android.app.Activity;import android.content.Intent;import android.graphics.ImageFormat;import android.hardware.Camera;import android.os.Bundle;import android.support.annotation.Nullable;import android.view.Surf
TakePhotoActivity.java
import android.app.Activity;
import android.content.Intent;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;

import com.alibaba.fastjson.util.IOUtils;
import com.github.yoojia.fast.view.AutoView;
import com.github.yoojia.fast.view.ViewFinder;
import com.parkingwang.app.Const;
import com.parkingwang.app.R;
import com.parkingwang.app.support.BugReport;
import com.parkingwang.app.support.FileUtils;
import com.parkingwang.app.support.MessageProxy;
import com.parkingwang.widget.BaseActivity;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

/**
 * 拍摄行驶证的界面
 *
 * @author 浩码农 (msdx.android@qq.com)
 * @version 2015-12-28
 * @since 2015-12-28
 */
public class TakePhotoActivity extends BaseActivity implements SurfaceHolder.Callback, View.OnClickListener {

    @AutoView(viewId = R.id.surface_view)
    private SurfaceView mSurfaceView;
    @AutoView(viewId = R.id.viewfinder)
    private View mViewfinder;
    @AutoView(viewId = R.id.cancel)
    private View mCancel;
    @AutoView(viewId = R.id.take_photo)
    private View mTakePhoto;

    private boolean mWaitForTakePhoto;
    private boolean mIsSurfaceReady;

    private Camera.Size mBestPictureSize;
    private Camera.Size mBestPreviewSize;

    @Nullable
    private Camera mCamera;

    private String mOutput;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_take_photo);
        ViewFinder.inject(this);

        mViewfinder.setOnClickListener(this);
        mCancel.setOnClickListener(this);
        mTakePhoto.setOnClickListener(this);

        SurfaceHolder holder = mSurfaceView.getHolder();
        holder.addCallback(this);

        mOutput = PhotoActionHelper.getOutputPath(getIntent());
    }

    private void openCamera() {
        if (mCamera == null) {
            try {
                mCamera = Camera.open();
            } catch (RuntimeException e) {
                if ("Fail to connect to camera service".equals(e.getMessage())) {
                    MessageProxy.showError(this, R.string.msg_camera_invalid_permission_denied);
                } else if ("Camera initialization failed".equals(e.getMessage())) {
                    MessageProxy.showError(this, R.string.msg_camera_invalid_initial_failed);
                } else {
                    MessageProxy.showError(this, R.string.msg_camera_invalid_unknown_error);
                }
                finish();
                return;
            }
        }

        final Camera.Parameters cameraParams = mCamera.getParameters();
        cameraParams.setPictureFormat(ImageFormat.JPEG);
        cameraParams.setRotation(90);
        cameraParams.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
        mCamera.setParameters(cameraParams);

        // 短边比长边
        final float ratio = (float) mSurfaceView.getWidth() / mSurfaceView.getHeight();

        // 设置pictureSize
        List
 
   pictureSizes = cameraParams.getSupportedPictureSizes();
        if (mBestPictureSize == null) {
            mBestPictureSize =findBestPictureSize(pictureSizes, cameraParams.getPictureSize(), ratio);
        }
        cameraParams.setPictureSize(mBestPictureSize.width, mBestPictureSize.height);

        // 设置previewSize
        List
  
    previewSizes = cameraParams.getSupportedPreviewSizes(); if (mBestPreviewSize == null) { mBestPreviewSize = findBestPreviewSize(previewSizes, cameraParams.getPreviewSize(), mBestPictureSize, ratio); } cameraParams.setPreviewSize(mBestPreviewSize.width, mBestPreviewSize.height); setSurfaceViewSize(mBestPreviewSize); try { mCamera.setParameters(cameraParams); } catch (RuntimeException e) { reportBug(cameraParams, e); } if (mIsSurfaceReady) { startPreview(); } } private void reportBug(Camera.Parameters cameraParams, RuntimeException e) { final List
   
     pictureSizes = cameraParams.getSupportedPictureSizes(); final List
    
      previewSizes = cameraParams.getSupportedPreviewSizes(); final StringBuilder sb = new StringBuilder(); sb.append("surface[").append(mSurfaceView.getWidth()).append(",").append(mSurfaceView.getHeight()).append("]\n"); buildSizesLog("picture", pictureSizes, sb); buildSizesLog("preview", previewSizes, sb); BugReport.report(new Exception("无法匹配合适大小:" + sb.toString(), e)); } private void buildSizesLog(String tag, List
     
       sizes, StringBuilder sb) { sb.append(tag).append("{"); for(Camera.Size size : sizes) { sb.append("[").append(size.width).append(",").append(size.height).append("],"); } sb.deleteCharAt(sb.length() - 1); sb.append("}\n"); } private void setSurfaceViewSize(Camera.Size size) { ViewGroup.LayoutParams params = mSurfaceView.getLayoutParams(); params.height = mSurfaceView.getWidth() * size.width / size.height; mSurfaceView.setLayoutParams(params); } /** * 找到短边比长边大于于所接受的最小比例的最大尺寸 * * @param sizes 支持的尺寸列表 * @param defaultSize 默认大小 * @param minRatio 相机图片短边比长边所接受的最小比例 * @return 返回计算之后的尺寸 */ private Camera.Size findBestPictureSize(List
      
        sizes, Camera.Size defaultSize, float minRatio) { final int MIN_PIXELS = 320 * 480; sortSizes(sizes); Iterator
       
         it = sizes.iterator(); while (it.hasNext()) { Camera.Size size = it.next(); //移除不满足比例的尺寸 if ((float) size.height / size.width <= minRatio) { it.remove(); continue; } //移除太小的尺寸 if (size.width * size.height < MIN_PIXELS) { it.remove(); } } // 返回符合条件中最大尺寸的一个 if (!sizes.isEmpty()) { return sizes.get(0); } // 没得选,默认吧 return defaultSize; } /** * @param sizes * @param defaultSize * @param pictureSize 图片的大小 * @param minRatio preview短边比长边所接受的最小比例 * @return */ private Camera.Size findBestPreviewSize(List
        
          sizes, Camera.Size defaultSize, Camera.Size pictureSize, float minRatio) { final int pictureWidth = pictureSize.width; final int pictureHeight = pictureSize.height; boolean isBestSize = (pictureHeight / (float)pictureWidth) > minRatio; sortSizes(sizes); Iterator
         
           it = sizes.iterator(); while (it.hasNext()) { Camera.Size size = it.next(); if ((float) size.height / size.width <= minRatio) { it.remove(); continue; } // 找到同样的比例,直接返回 if (isBestSize && size.width * pictureHeight == size.height * pictureWidth) { return size; } } // 未找到同样的比例的,返回尺寸最大的 if (!sizes.isEmpty()) { return sizes.get(0); } // 没得选,默认吧 return defaultSize; } private static void sortSizes(List
          
            sizes) { Collections.sort(sizes, new Comparator
           
            () { @Override public int compare(Camera.Size a, Camera.Size b) { return b.height * b.width - a.height * a.width; } }); } private void startPreview() { if (mCamera == null) { return; } try { mCamera.setPreviewDisplay(mSurfaceView.getHolder()); mCamera.setDisplayOrientation(90); mCamera.startPreview(); } catch (IOException e) { e.printStackTrace(); BugReport.report(e); } } private void stopPreview() { if (mCamera != null) { mCamera.stopPreview(); } } private void closeCamera() { if (mCamera == null) { return; } mCamera.cancelAutoFocus(); stopPreview(); mCamera.release(); mCamera = null; } /** * 请求自动对焦 */ private void requestFocus() { if (mCamera == null || mWaitForTakePhoto) { return; } mCamera.autoFocus(null); } /** * 拍照 */ private void takePhoto() { if (mCamera == null || mWaitForTakePhoto) { return; } mWaitForTakePhoto = true; mCamera.takePicture(null, null, new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { onTakePhoto(data); mWaitForTakePhoto = false; } }); } private void onTakePhoto(byte[] data) { final String tempPath = mOutput + "_"; FileOutputStream fos = null; try { fos = new FileOutputStream(tempPath); fos.write(data); fos.flush(); PhotoActionHelper.clipImage(this) .extra(getIntent()) .output(mOutput).input(tempPath) .requestCode(Const.Request.CLIP_IMAGE).start(); } catch (Exception e) { BugReport.report(e); } finally { IOUtils.close(fos); } } @Override protected void onResume() { super.onResume(); mSurfaceView.post(new Runnable() { @Override public void run() { openCamera(); } }); } @Override protected void onPause() { super.onPause(); closeCamera(); } @Override public void surfaceCreated(SurfaceHolder holder) { mIsSurfaceReady = true; startPreview(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { mIsSurfaceReady = false; } @Override public void onClick(View v) { final int id = v.getId(); switch (id) { case R.id.viewfinder: requestFocus(); break; case R.id.cancel: cancelAndExit(); break; case R.id.take_photo: takePhoto(); break; default:// do nothing } } @Override public void onBackPressed() { cancelAndExit(); } private void cancelAndExit() { setResult(Activity.RESULT_CANCELED); finish(); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == Const.Request.CLIP_IMAGE) { String tempPath = PhotoActionHelper.getInputPath(data); if (tempPath != null) { FileUtils.delete(tempPath); } if (resultCode == Activity.RESULT_OK) { setResult(Activity.RESULT_OK, data); finish(); } } super.onActivityResult(requestCode, resultCode, data); } }
           
          
         
        
       
      
     
    
   
  
 
网友评论