Android 自定义相机页面

1.布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">

    <FrameLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_above="@+id/photo_graph_opt_layout">
        <SurfaceView
            android:id="@+id/sv_camera"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" />

        <ImageView
            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"/>

        <RelativeLayout
            android:id="@+id/photograph_img_layout"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:background="@color/Black"
            android:visibility="gone">
            <ImageView
                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"/>
        </RelativeLayout>

    </FrameLayout>

    <RelativeLayout
        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">
        <TextView
            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"/>

        <TextView
            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"/>

        <TextView
            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"/>
    </RelativeLayout>

</RelativeLayout>

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列表
            List<Camera.Size> pictureSizeList = 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<Camera.Size> 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<Camera.Size> 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) {
        List<String> focusModes = 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;
    }


}



  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用自定义相机替代默认相机,需要先在 PictureSelector 中进行如下配置: 1. 在 PictureSelector 的配置类 PictureSelectorConfig 中添加以下参数: ```java // 自定义相机相关配置,用于替换 PictureSelector 自带的相机 private boolean isUseCustomCamera; private Class<? extends Activity> cameraActivityClass; private int cameraRequestCode; ``` 2. 在 PictureSelector 的启动方法中,根据 isUseCustomCamera 判断是否启用自定义相机,并将 cameraActivityClass 和 cameraRequestCode 参数传递给自定义相机页面。 ```java /** * 启动 PictureSelector * * @param activity 调用方 Activity * @param config 配置信息 * @param requestCode 请求码 */ public static void start(Activity activity, PictureSelectorConfig config, int requestCode) { Intent intent = new Intent(activity, PictureSelectorActivity.class); // 将配置信息传递给 PictureSelectorActivity intent.putExtra(EXTRA_CONFIG, config); activity.startActivityForResult(intent, requestCode); // 如果启用自定义相机,则启动自定义相机页面 if (config.isUseCustomCamera()) { Intent cameraIntent = new Intent(activity, config.getCameraActivityClass()); activity.startActivityForResult(cameraIntent, config.getCameraRequestCode()); } } ``` 3. 在自定义相机页面中,拍照完成后将照片路径返回给 PictureSelector。 ```java /** * 拍照完成后返回照片路径 * * @param photoPath 照片路径 */ private void returnPhotoPath(String photoPath) { Intent intent = new Intent(); // 将照片路径作为结果返回给 PictureSelector intent.putExtra(PictureSelector.EXTRA_RESULT, photoPath); setResult(RESULT_OK, intent); finish(); } ``` 通过以上步骤,就可以在 PictureSelector 中调用自定义相机了。注意,在自定义相机页面中拍照完成后,需要将照片路径返回给 PictureSelector,以便 PictureSelector 进行后续处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值