美文网首页工作
Android 自定义相机

Android 自定义相机

作者: 1a473fcb13b0 | 来源:发表于2019-07-26 11:08 被阅读32次

检测Android设备是否支持照相机

    /**
     * 检测设备是否支持相机
     *
     * @param context
     * @return
     */
    private boolean checkCameraHardware(Context context) {
        if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
            return true;
        }
        return false;
    }

定制拍照程序的步骤:

1、打开相机:Camera.open();
2、创建SurfaceView对象;
3、添加回调监听器(SurfaceHolder.Callback);
4、预览(mCamera.startPreview);
5、拍照(mCamera.takePicture);

网上资料:

网上写的挺详细的具体自定义操作请查阅以下资料:

Android 自定义Camera相机
https://blog.csdn.net/qq_38001118/article/details/81871564

Android: Camera相机开发详解(上) —— 知识储备
https://www.jianshu.com/p/f8d0d1467584
Android: Camera相机开发详解(中) ——实现预览、拍照、保存照片等功能
https://www.jianshu.com/p/e20a2ad6ad9a
Android: Camera相机开发详解(下) —— 实现人脸检测功能
https://www.jianshu.com/p/3bb301c302e8
Android:Camera2开发详解(上):实现预览、拍照、保存照片等功能
https://www.jianshu.com/p/0ea5e201260f

项目中遇到的问题:

魔镜项目中人脸识别需要一个宽高为630x780px的框而相机中给的预览和图片尺寸没有给定与项目接近的值

07-19 17:29:58.280 24520-24520/com.hzy.exampledemo D/mPreviewSizes-0: width:1280--height:720
07-19 17:29:58.280 24520-24520/com.hzy.exampledemo D/mPreviewSizes-1: width:1920--height:1080
07-19 17:29:58.280 24520-24520/com.hzy.exampledemo D/mPreviewSizes-2: width:208--height:144
07-19 17:29:58.280 24520-24520/com.hzy.exampledemo D/mPreviewSizes-3: width:176--height:144
07-19 17:29:58.280 24520-24520/com.hzy.exampledemo D/mPreviewSizes-4: width:352--height:288
07-19 17:29:58.280 24520-24520/com.hzy.exampledemo D/mPreviewSizes-5: width:320--height:240
07-19 17:29:58.280 24520-24520/com.hzy.exampledemo D/mPreviewSizes-6: width:480--height:320
07-19 17:29:58.280 24520-24520/com.hzy.exampledemo D/mPreviewSizes-7: width:640--height:480
07-19 17:29:58.280 24520-24520/com.hzy.exampledemo D/mPreviewSizes-8: width:800--height:480
07-19 17:29:58.280 24520-24520/com.hzy.exampledemo D/mPreviewSizes-9: width:960--height:544
07-19 17:29:58.280 24520-24520/com.hzy.exampledemo D/mPreviewSizes-10: width:960--height:720
07-19 17:29:58.280 24520-24520/com.hzy.exampledemo D/mPreviewSizes-11: width:720--height:720

07-19 17:36:17.400 24520-24520/com.hzy.exampledemo D/mPictureSizes-0: width:320--height:240
07-19 17:36:17.400 24520-24520/com.hzy.exampledemo D/mPictureSizes-1: width:640--height:480
07-19 17:36:17.400 24520-24520/com.hzy.exampledemo D/mPictureSizes-2: width:1280--height:720
07-19 17:36:17.400 24520-24520/com.hzy.exampledemo D/mPictureSizes-3: width:1920--height:1080
07-19 17:36:17.400 24520-24520/com.hzy.exampledemo D/mPictureSizes-4: width:2432--height:2432
07-19 17:36:17.400 24520-24520/com.hzy.exampledemo D/mPictureSizes-5: width:3264--height:2448
07-19 17:36:17.400 24520-24520/com.hzy.exampledemo D/mPictureSizes-6: width:4160--height:2336
07-19 17:36:17.400 24520-24520/com.hzy.exampledemo D/mPictureSizes-7: width:5152--height:2896
07-19 17:36:17.400 24520-24520/com.hzy.exampledemo D/mPictureSizes-8: width:5152--height:3888

解决思路:

1、我们设置图片尺寸和预览尺寸为1920x1080px;
2、在布局中添加一个同样大小位置的蒙层,其中中间通过计算留出630x780px;
3、对拍照的图片通过位置计算进行截取;

1、我们设置图片尺寸和预览尺寸为1920x1080px;
        parameters.setPreviewSize(1920, 1080);
        parameters.setPictureSize(1920, 1080);
2、在布局中添加一个同样大小位置的蒙层,其中中间通过计算留出630x780px;
        <RelativeLayout
            android:id="@+id/camera_container"
            android:layout_width="1280dp"
            android:layout_centerInParent="true"
            android:layout_height="960dp" />

        <com.yx.mirror.third.camera.view.OcclusionView
            android:id="@+id/v_occ"
            android:layout_width="1280dp"
            android:layout_centerInParent="true"
            android:layout_height="960dp"
            android:background="@android:color/transparent" />
package com.yx.mirror.third.camera.view;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.Nullable;

import com.yx.mirror.R;

/**
 * Description 遮挡的View
 *
 * @author hzy
 * Create on 2019/7/23 10:13
 */
public class OcclusionView extends View {

    private Paint mPaint;
    private int mMaskColor; // 取景框外的背景颜色
    private int mCameraWidth;
    private int mCameraHeight;
    private int mPicWidth;
    private int mPicHeight;
    /**
     * 中点距离和marginTop的差值,由于横向是居中,所以不用计算
     */
    private int marginDifference;
    private OcclusionView mOcclusionView;

    public OcclusionView(Context context) {
        super(context);
        initView();
    }

    public OcclusionView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    private void initView() {
        Resources resources = getResources();
        mMaskColor = resources.getColor(R.color.black_back);
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        // 绘制取景框外的暗灰色的表面,分四个矩形绘制
        mPaint.setColor(mMaskColor);
    }

    public void setOcclusionView(OcclusionView mOcclusionView, int mCameraWidth, int mCameraHeight, int mPicWidth, int mPicHeight, int marginDifference) {
        this.mOcclusionView = mOcclusionView;
        this.mCameraWidth = mCameraWidth;
        this.mCameraHeight = mCameraHeight;
        this.mPicWidth = mPicWidth;
        this.mPicHeight = mPicHeight;
        this.marginDifference = marginDifference;
    }

    @Override
    public void onDraw(Canvas canvas) {
        if (mOcclusionView == null) {
            return; // not ready yet, early draw before done configuring
        }

        // 黑色区域
        Path path1 = new Path();
        path1.addRect(new RectF(0, 0, mCameraWidth, mCameraHeight), Path.Direction.CW);

        //透明区域
        Path path2 = new Path();
        path2.addRect(new RectF((mCameraWidth - mPicWidth) / 2, (mCameraHeight - mPicHeight) / 2 + marginDifference, (mCameraWidth + mPicWidth) / 2, (mCameraHeight + mPicHeight) / 2 + marginDifference), Path.Direction.CW);

        //DIFFERENCE,path1减去path1和path2相交部分
        path1.op(path2, Path.Op.DIFFERENCE);
        canvas.drawPath(path1, mPaint);
    }
}

3、对拍照的图片通过位置计算进行截取;
    /**
     * 人脸照片处理
     *
     * @param bmp
     */
    private void showFragment(Bitmap bmp) {
        translateAnimation.cancel();//动画取消
        mImvLine.setVisibility(View.GONE);
        Matrix matrix = new Matrix();
        //镜子效果
        matrix.setScale(-1, 1);
        matrix.postTranslate(bmp.getWidth(), 0);
        //旋转图片
        Bitmap rotateBitmap = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true);
        //截图至当前图片的大小
        Bitmap bitmap = cropBitmap(rotateBitmap, 630, 780);
        photoPath = "/qimg/report/" + DateUtil.getDateYmd() + "/" + System.currentTimeMillis() + ".png";
        writeBitmapToFile(bitmap, photoPath);
        mCameraContainer.setVisibility(View.GONE);
        mPhotoIv.setImageBitmap(bitmap);
        mPhotoIv.setVisibility(View.VISIBLE);
        postImg(bitmap);
    }

    /**
     * 裁剪
     * https://blog.csdn.net/qunqunstyle99/article/details/87869018
     *
     * @param bitmap 原图
     * @return 裁剪后的图像
     */
    private Bitmap cropBitmap(Bitmap bitmap, int picWidth, int picHeight) {
        int w = bitmap.getWidth();
        int h = bitmap.getHeight();
        int x = 0;
        int y = 0;
        if (bitmap.getWidth() < picWidth) {
            Toast.makeText(this, "x + width must be <= bitmap.width()", Toast.LENGTH_SHORT).show();
            return bitmap;
        }
        if (bitmap.getHeight() < picHeight) {
            Toast.makeText(this, "y + height must be <= bitmap.height()", Toast.LENGTH_SHORT).show();
            return bitmap;
        }
        x = (w - picWidth) / 2;
        y = (h - picHeight) / 2;
        return Bitmap.createBitmap(bitmap, x, y, picWidth, picHeight, null, false);
    }

相关文章

  • Android自定义相机

    CustomCamera android自定义相机 功能描述: 主要可自定义相机的各类按钮布局 相机拍照缩放功能 ...

  • Android CameraX结合LibYUV和GPUImage

    目录 前言 之前使用Camera实现了一个自定义相机滤镜(Android自定义相机滤镜[https://www.j...

  • 自定义相机的旋转角度适配

    Android中时常会需要实现自定义的相机。但是应用可以横屏竖屏操作,所以自定义相机需要\设置Orientatio...

  • android 调起相册和相机的问题

    1:调起相册拍照 照片在相机里显示 android 6.0以下适配能在相机里显示时无法给照片自定义命名自定义命名...

  • 13.4 camera

    简介 android中相机使用有两种方式,一是调用系统相机(Intent),二是自定义相机 调用系统相机相册 自定...

  • Android自定义Camera2相机

    Android自定义Camera2相机 写在前面 Google从Android 5.0 L(API 21) 版本,...

  • Android 自定义相机 识别身份证(下)

    上一篇文章Android 自定义相机 识别身份证(上)介绍自定义相机的一些相关技术和步骤,这篇文章主要把代码简单的...

  • Android自定义Camera

    Android自定义Camera相机 转载请表明出处https://www.jianshu.com/p/e7f49...

  • Android 自定义相机

    检测Android设备是否支持照相机 定制拍照程序的步骤: 1、打开相机:Camera.open();2、创建Su...

  • Android Camera旋转角度分析

    开发过Android自定义相机的朋友估计都被相机的各种乱七八糟的旋转角度适配坑过,本文将对Camera的各种角度进...

网友评论

    本文标题:Android 自定义相机

    本文链接:https://www.haomeiwen.com/subject/xnxslctx.html