当前位置: 首页 > 知识库问答 >
问题:

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

公羊俊德
2023-03-14

所以我用下面的方法设置了摄像头-

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()来实际指定图像方向,并在摄像机本身上使用了setDisplayOriation()来处理表面预览中的方向更改。(注释和未注释的代码似乎都没有保留方向。当我检查Exif数据时,它返回0)

之后,在回调中,我甚至尝试使用矩阵保存具有方向的图像。

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();
    }
}

实际问题

>

  • 当我在肖像模式下拍照时,一切正常。它看起来像是被拿走了。

    但是当我在风景模式下拍照时(逆时针旋转手机90度)。现在这个图像也被视为肖像。事实上,它应该是以景观为导向的。我检查了Exif数据,图像没有用横向模式保存。

    现在我期望发生的是,如果我在横向模式下捕获图像(表面预览在这里工作得很好),它应该出现在横向。(参考我的意思,如果你在风景模式下在Instagram中捕捉图像,在下一个屏幕上应用效果时,它会出现在风景中。如果图像被当作肖像,它看起来就像肖像。我想要类似的东西。

    活动应该仅处于纵向模式。所以这已经被列入清单了。

    从昨晚起,这里少了什么给我带来这么多麻烦的东西(

  • 共有1个答案

    封景曜
    2023-03-14

    你有2个选择:

    1. 监听设备旋转,并在保存文件时自行设置exif数据(缺点:android上的所有图像编辑应用程序都不支持exif)
    2. 监听设备旋转并在保存图像数据之前旋转图像数据
     类似资料:
    • 我在响应式站点上设置了flexSlider。我正在创建的滑块可以拍摄横向和纵向图像。我设置了,以便调整高度以适应图像。 在最大的媒体查询中,flexslider容器的宽度为750px。这对于横向图像很好,但纵向图像太大了。肖像图像的宽度设置为与容器相同的大小-750px宽,因此高度至少是容器宽度的两倍,因此如果不滚动,则无法查看整个图像。 在css中,我尝试设置最大高度:750px,这解决了高度问

    • 问题内容: 我有一个移动Web应用程序,其无序列表包含多个列表项,每个li内都有一个超链接: …我的问题是如何格式化超链接,以使它们在iPhone上查看时不会改变大小,并且加速计从纵向切换为横向?现在,我将超链接的字体大小指定为14px,但是切换到横向时,它会炸裂到20px。我希望字体大小保持不变。这是代码: 问题答案: 您可以通过CSS属性禁用此行为:

    • 问题内容: 目前,我正在使用: 尽管此方法可行,但最终得到的图像大小不同(有些是纵向的,有些是横向的),但是我希望所有图像都具有精确的尺寸。也许是明智的选择? 更新: 我不介意裁剪图像的一小部分。当我说明智的耕作时,我的意思是这样的算法: 问题答案: 这是我对图像进行填充拟合的观点: 它首先使用缩略图操作将图像降低到原始范围内并保留宽高比。然后将其裁剪掉以实际填充边界的大小(因为除非原始图像为正方

    • 使用CSS flex box模型,如何强制图像保持其纵横比? JS小提琴:http://jsfiddle.net/xLc2Le0k/2/ 请注意,为了填充容器的宽度,图像会拉伸或收缩。这很好,但是我们也能让它拉伸或收缩高度来保持图像比例吗? HTML CSS

    • 我正在使用jQuery创建一个图片库。是否有任何可能性使用jQuery计算图像是风景还是肖像? 感谢您的支持。

    • 我使用Owl Carousel在带有Javascript和jQuery的Carousel中显示图像。我有肖像和风景图片,还有CSS: 横向图像遵守宽度的100%限制,全图显示在屏幕上;肖像图像不符合100%的高度限制,图片显示在一个或两个屏幕上,需要向下滚动。我希望纵向图片能够调整大小,并在横向屏幕上完全显示,就像我希望横向图片能够在纵向屏幕上完全显示一样。 我用CSS尝试了最大高度和最大宽度的解