自定义相机在保存图像的同时保留纵向/横向

时间:2015-04-17 11:21:37

标签: android image android-camera surfaceview exif

所以我使用以下方法设置相机 -

private void configureCamera(int previewWidth, int previewHeight) {
    if(null != camera && null != surfaceHolder.getSurface()) {
        Camera.CameraInfo info = new Camera.CameraInfo();

        Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_BACK, info);
        parameters = camera.getParameters();
        parameters.set("jpeg-quality", 100);
        parameters.setPictureFormat(ImageFormat.JPEG);

        Camera.Size previewSize = getBestPreviewSize(parameters);
        parameters.setPreviewSize(previewSize.width, previewSize.height);

        Camera.Size pictureSize = getBestPictureSize(parameters);
        parameters.setPictureSize(pictureSize.width, pictureSize.height);

        if(isBackCamera && btnFlash.isSelected())
            parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
        else
            parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);

        if(parameters.isZoomSupported()) {
            MAX_ZOOM_LEVEL = parameters.getMaxZoom();
            parameters.setZoom(currentZoomLevel);
        }

        if (previewSize != null) {

            Display display = getWindowManager().getDefaultDisplay();
            /*switch (display.getRotation()) {
                case Surface.ROTATION_0: // This is display orientation
                    cameraDisplayOrientation = 90; // This is camera orientation
                    break;
                case Surface.ROTATION_90:
                    cameraDisplayOrientation = 0;
                    break;
                case Surface.ROTATION_180:
                    cameraDisplayOrientation = 270;
                    break;
                case Surface.ROTATION_270:
                    cameraDisplayOrientation = 180;
                    break;
                default:
                    cameraDisplayOrientation = 90;
                    break;
            }*/
            int degrees = 0;
            switch (display.getRotation()) {
                case Surface.ROTATION_0: degrees = 0; break;
                case Surface.ROTATION_90: degrees = 90; break;
                case Surface.ROTATION_180: degrees = 180; break;
                case Surface.ROTATION_270: degrees = 270; break;
            }


            cameraDisplayOrientation= (info.orientation - degrees + 360) % 360;
            Logger.debug("Angle : " + cameraDisplayOrientation);
            Logger.debug("Display Orientation is " + display.getRotation());
            Logger.debug("Info Orientation " + info.orientation);
            if(!isBackCamera) {
                cameraDisplayOrientation = 270;
            }

            camera.setDisplayOrientation(cameraDisplayOrientation);
            parameters.setRotation(cameraDisplayOrientation);
            camera.setParameters(parameters);
        }
    }
}

如您所见,我已在相机参数上使用setRoation()来实际指定图像方向,并在相机本身上使用setDisplayOrientation()来处理表面预览中的方向更改。 (评论和未评论的代码似乎都没有保留方向。当我检查Exif数据时,它返回0)

执行此操作后,在onPictureTaken回调中,我甚至尝试使用Matrix保存图像。

private void handlePictureFormation(byte[] data) {
    stopCameraPreview();

    String parentDirPath = null;
    if(FileHelper.isExternalStorageWritable()) {

        parentDirPath = myApp.getFileHelper().getDataDir();
    } else {
        File parentDir = getDir("MYAPP", MODE_PRIVATE);
        parentDirPath = parentDir.getAbsolutePath();
    }

    boolean isWriteSuccess = false;
    File pictureFile = new File(parentDirPath, new Date().getTime() + ".jpg");
    if(null != pictureFile) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = false;
        options.inSampleSize = 2;
        imageBitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);

        Matrix matrix = new Matrix();
        matrix.postRotate(cameraDisplayOrientation);
        imageBitmap = Bitmap.createBitmap(imageBitmap, 0, 0, imageBitmap.getWidth(), imageBitmap.getHeight(), matrix, true);

        try {
            FileOutputStream fos = new FileOutputStream(pictureFile);
            imageBitmap.compress(CompressFormat.JPEG, 100, fos);
            fos.flush();
            fos.close();

            isWriteSuccess = true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        Logger.debug("FilePath: " + pictureFile.getAbsolutePath());
    }

    if(isWriteSuccess) {
        Intent intent = new Intent(this, PreviewActivity.class);
        intent.putExtra("IMAGE_FILE_PATH", pictureFile.getAbsolutePath());
        startActivity(intent);      
    } else {
        // TODO: Convey user that image file saving failed
        startCameraPreview();
    }
}

实际问题

  1. 当我以肖像模式拍照时,它没问题。看来是这样的。

  2. 但是当我以风景模式拍照时(逆时针转动手机90度)。现在这张图片也被视为肖像。事实上,它应该是横向的。我检查了Exif数据,并且未使用横向模式保存图像。

  3. 现在我期待的是 如果我以横向模式捕捉图像(表面预览在此处运行良好),它应该以横向显示。 (要参考我的意思,如果你在横向模式下在Instagram中捕捉图像,在应用效果的同时在下一个屏幕上显示为横向。如果图像被视为肖像,则它看起来像是肖像。我想要类似的东西。

    活动应仅处于纵向模式。所以这已经在清单中设置了。

    这里缺少的是昨晚给我带来的麻烦。 :(

1 个答案:

答案 0 :(得分:0)

您有两个选择:

  1. 在保存文件时听取设备轮换并自行设置exif数据(缺点:exif不支持Android上的所有图像编辑应用程序)
  2. 在保存之前聆听设备旋转并旋转图像数据
相关问题