Android 自定义Camera(二)如何实现拍照功能

Android自定义Camera如何实现拍照功能

前言

上篇文章我们讨论了《 自定义Camera(一)如何预览相机》,现在我们继续讨论如何实现拍照功能。

官方API

在这里插入图片描述
在这里插入图片描述翻译后为:

触发异步图像捕获。随着图像捕获的进行,camera服务将启动对应用程序的一系列回调。快门回调发生在图像捕获之后。这可以用来触发一个声音,让用户知道图像已经被捕获。当原始图像数据可用时发生原始回调(注意:如果没有可用的原始图像回调缓冲区,或者原始图像回调缓冲区不够大,无法容纳原始图像,则数据将为null)。postview回调发生在一个缩放的、完全处理的postview映像可用时(注意:并非所有硬件都支持这一点)。jpeg回调在压缩图像可用时发生。如果应用程序不需要特定的回调,可以传递一个null,而不是回调方法。
此方法仅在启用preview(在startPreview()之后)时有效。拍照后停止预览;如果要重新启动预览或拍摄更多照片,调用者必须再次调用startPreview()。在MediaRecorder.start()和MediaRecorder.stop()之间不应该调用这个函数。
在调用此方法之后,必须在JPEG回调返回之前不调用startPreview()或拍摄另一张照片。

实现拍照

1> 创建拍照按钮及图片显示容器
在这里插入图片描述
2>调用takePicture

case R.id.take_photo_btn:
                if(mCamera != null) {
                /**
                         *   相机必须执行在startView之后,并且takePicture
                         *   会导致预览停止
                         *    mTakePhotoBtn.setClickable(false);
                         *    和try{}catch(){}都是为了处理相机状态错误导致的异常
                         */
                    mTakePhotoBtn.setClickable(false);
                    try {
                        mCamera.takePicture(new Camera.ShutterCallback() {
                            @Override
                            public void onShutter() {
                                Log.e(TAG, "用户按下快门时调用");

                            }
                        }, new Camera.PictureCallback() {
                            @Override
                            public void onPictureTaken(byte[] data, Camera camera) {
                                Log.e(TAG, "raw" + data);
                            }
                        }, new Camera.PictureCallback() {
                            @Override
                            public void onPictureTaken(byte[] data, Camera camera) {
                                if(mCamera != null) mCamera.startPreview();
                                mTakePhotoBtn.setClickable(true);
                                /**
                                 * 此处可以将文件保存到sdCard
                                 */
                                /**
                                 * onPictureTaken所回调的data是相当大的,并且是未旋转的角度,不建议直接
                                 * 显示在ImageView上
                                 * 下面处理的Bitmap的角度和固定尺寸压缩
                                 */
                                mPicture.setImageBitmap(BitmapUtils.adjustPhotoRotation(
                                        BitmapUtils.compressScaleBitmap(
                                                BitmapFactory.decodeByteArray(data, 0, data.length),
                                                600, 600), 90));
                            }
                        });
                    } catch (Exception e) {
                        e.printStackTrace();
                        mTakePhotoBtn.setClickable(true);
                    }
                }
                break;
                
/**
     * 旋转反向
     * @param bm
     * @param orientationDegree
     * @return
     */
    public static Bitmap adjustPhotoRotation(Bitmap bm, final int orientationDegree) {

        Matrix m = new Matrix();
        m.setRotate(orientationDegree, (float) bm.getWidth() / 2, (float) bm.getHeight() / 2);
        float targetX, targetY;
        if (orientationDegree == 90) {
            targetX = bm.getHeight();
            targetY = 0;
        } else {
            targetX = bm.getHeight();
            targetY = bm.getWidth();
        }

        final float[] values = new float[9];
        m.getValues(values);

        float x1 = values[Matrix.MTRANS_X];
        float y1 = values[Matrix.MTRANS_Y];

        m.postTranslate(targetX - x1, targetY - y1);

        Bitmap bm1 = Bitmap.createBitmap(bm.getHeight(), bm.getWidth(), Bitmap.Config.ARGB_8888);

        Paint paint = new Paint();
        Canvas canvas = new Canvas(bm1);
        canvas.drawBitmap(bm, m, paint);


        return bm1;
    }


    /**
     * bitmap 尺寸压缩
     * @param bitmap
     * @param width
     * @param height
     * @return
     */
    public static Bitmap compressScaleBitmap(Bitmap bitmap, int width, int height) {
        bitmap = Bitmap.createScaledBitmap(bitmap, width, height, true);
        return bitmap;
    }

结尾

ok,这样就实现了拍照功能了,但是却发现画面的显示有一定程度的拉伸,下篇文章我们继续讨论如何选择合适的相机尺寸。飞机票

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值