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

Android相机在某些设备中提供旋转捕获的图像

田佐
2023-03-14

当我捕获图像时,我会旋转捕获的图像。

我正在设置相机参数对象的旋转。

Camera.Parameters params = mCamera.getParameters();
params.setRotation(90);

但它不起作用。我尝试将旋转角度设置为 0、90、270 和 360,但捕获的图像旋转没有变化。

设备:红米手机注5

对于其他设备工作正常,即将旋转角度设置为 90 度会使图像以原始方向旋转。

我至少期望的是,当我将旋转角度的值更改为不同程度时,至少必须有旋转变化。但这似乎没有任何影响。

我做过

mCamera.setDisplayOrientation(rotate);
它会更改相机预览旋转,但不会更改捕获的图像旋转。

另外,我看到了以下帖子,尝试了解决方案,但没有找到任何可行的解决方案。
对于某些设备,Android 相机在捕获时无法解释的旋转(不在 EXIF 中)
为什么使用相机意图拍摄的图像在 Android 上的某些设备上会旋转?
setRotation(90) 以纵向模式拍照在三星设备上不起作用 Android - 相机
预览是横向的 强制相机
始终在Android模式下以纵向模式打开 Android相机在
SurfaceView 上的人像
Android - 拍摄照片
在相机中强制人像模式

共有1个答案

扈高逸
2023-03-14

我面临着同样的问题。我已经尝试过这个并且对我来说工作正常。

private CameraSource.PictureCallback mPicture = new CameraSource.PictureCallback() {
@Override
public void onPictureTaken(byte[] bytes) {
   int orientation = Exif.getOrientation(bytes);
   Bitmap   bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
   switch(orientation) {
       case 90:
           bitmapPicture= rotateImage(bitmap, 90);
           break;
       case 180:
           bitmapPicture= rotateImage(bitmap, 180);
           break;
       case 270:
           bitmapPicture= rotateImage(bitmap, 270);
           break;
       case 0:
           // if orientation is zero we don't need to rotate this
       default:
           break;
   }
   //write your code here to save bitmap 
   }
}

public static Bitmap rotateImage(Bitmap source, float angle) {
    Matrix matrix = new Matrix();
    matrix.postRotate(angle);
    return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
  }

下面的类用于从 byte[] 数据中获取方向。

public class Exif {
private static final String TAG = "CameraExif";

// Returns the degrees in clockwise. Values are 0, 90, 180, or 270.
public static int getOrientation(byte[] jpeg) {
    if (jpeg == null) {
        return 0;
    }

    int offset = 0;
    int length = 0;

    // ISO/IEC 10918-1:1993(E)
    while (offset + 3 < jpeg.length && (jpeg[offset++] & 0xFF) == 0xFF) {
        int marker = jpeg[offset] & 0xFF;

        // Check if the marker is a padding.
        if (marker == 0xFF) {
            continue;
        }
        offset++;

        // Check if the marker is SOI or TEM.
        if (marker == 0xD8 || marker == 0x01) {
            continue;
        }
        // Check if the marker is EOI or SOS.
        if (marker == 0xD9 || marker == 0xDA) {
            break;
        }

        // Get the length and check if it is reasonable.
        length = pack(jpeg, offset, 2, false);
        if (length < 2 || offset + length > jpeg.length) {
            Log.e(TAG, "Invalid length");
            return 0;
        }

        // Break if the marker is EXIF in APP1.
        if (marker == 0xE1 && length >= 8 &&
                pack(jpeg, offset + 2, 4, false) == 0x45786966 &&
                pack(jpeg, offset + 6, 2, false) == 0) {
            offset += 8;
            length -= 8;
            break;
        }

        // Skip other markers.
        offset += length;
        length = 0;
    }

    // JEITA CP-3451 Exif Version 2.2
    if (length > 8) {
        // Identify the byte order.
        int tag = pack(jpeg, offset, 4, false);
        if (tag != 0x49492A00 && tag != 0x4D4D002A) {
            Log.e(TAG, "Invalid byte order");
            return 0;
        }
        boolean littleEndian = (tag == 0x49492A00);

        // Get the offset and check if it is reasonable.
        int count = pack(jpeg, offset + 4, 4, littleEndian) + 2;
        if (count < 10 || count > length) {
            Log.e(TAG, "Invalid offset");
            return 0;
        }
        offset += count;
        length -= count;

        // Get the count and go through all the elements.
        count = pack(jpeg, offset - 2, 2, littleEndian);
        while (count-- > 0 && length >= 12) {
            // Get the tag and check if it is orientation.
            tag = pack(jpeg, offset, 2, littleEndian);
            if (tag == 0x0112) {
                // We do not really care about type and count, do we?
                int orientation = pack(jpeg, offset + 8, 2, littleEndian);
                switch (orientation) {
                    case 1:
                        return 0;
                    case 3:
                        return 180;
                    case 6:
                        return 90;
                    case 8:
                        return 270;
                }
                Log.i(TAG, "Unsupported orientation");
                return 0;
            }
            offset += 12;
            length -= 12;
        }
    }

    Log.i(TAG, "Orientation not found");
    return 0;
}

private static int pack(byte[] bytes, int offset, int length, boolean littleEndian) {
    int step = 1;
    if (littleEndian) {
        offset += length - 1;
        step = -1;
    }

    int value = 0;
    while (length-- > 0) {
        value = (value << 8) | (bytes[offset] & 0xFF);
        offset += step;
    }
    return value;
}
}

我在像Vivo,MI这样的少数设备中面临这个问题。 听说我花了两天时间解决了这个问题。谢谢。

 类似资料:
  • 我正在捕获一个图像并将其设置为图像视图。 但问题是,一些设备上的图像每次被旋转。例如,在三星的设备上,它运行良好,但在索尼的Xperia上,图像会旋转90度,在东芝的Thrive(平板电脑)上旋转180度。

  • 我发现了一个非常有趣的问题。在拍摄相机照片后(我将设备保持在纵向模式,不旋转),给定的照片有时会旋转,但并不总是旋转。我知道,有些设备总是提供旋转的照片,但它可以使用exif或mediastore信息进行旋转。但在这种情况下,exif和mediastore表示方向为0,但图像是旋转的。最令人沮丧的是,这完全是随机发生的。代码非常简单: 有人见过这个问题吗?我在操作系统更新(4.1.1)后体验了Ga

  • 当我捕获照片时,在某些设备中,它会以景观模式存储在某些设备中,它会存储肖像。我想让图像在肖像模式无论如何。为此,我尝试获取图像的数据,并相应地将其旋转到肖像模式。但在一些设备,如三星,VIVO的方向值得到“0”。我不知道该怎么处理那个值。如果我90,那么一些设备将解决此问题,而另一些设备将向上保存照片。 我从Xamarin那里得到这个主意。Andoid图像旋转。但不知怎的,我不能再继续下去了。会有

  • 和onActivityResult 和错误的堆栈跟踪 stack_trace=java.lang.runtimeException:未能将结果ResultInfo{who=null,request=1,result=-1,data=intent{act=inline-data(havs extras)}}传递到活动{com.madhours/com.madhours.activities.acti

  • 我已经被困在相机里6天了,但没有得到任何适当的解决方案。当我通过相机意图捕获图像时,图像正在旋转。我试图修复方向,但有时它没有在onActivityResult()中给出位图值。当我尝试在ImageView中设置图像时,它会显示一个黑色屏幕。这是我的密码请帮帮我- 我得到的图像在横向模式,但不是在potrait模式。相机预览在拍摄图像后自动旋转90度。

  • 在OpenCV上使用class VideoCapture时如何旋转摄像头?(Android上的人脸检测示例)。我正在旋转画布: 但摄像机的图像并没有旋转:人脸检测不起作用。 摄像头从以下位置接收流: 我做了以下更新: 但这是行不通的。当我以portret方向运行程序时(在android设备上)——当我以横向方向运行程序时,程序不会启动——程序工作,但当我旋转设备时,程序工作,但显示屏上的图像不会旋

  • 我在玩谷歌的API2摄像头,我的代码有一些问题。我有两个不同的摄像头,一个用于视频,另一个用于图像。为了提高效率,我将代码更改为使用唯一会话,并使应用程序更高效。 在我这样做之后,我的相机预览不能充分工作。当我使用4:3宽高比时,我的预览会在高处拉伸。换句话说,当我使用16:9的比例时,它看起来很好。在这两种情况下,我的照片看起来都很好,我的意思是,预览不能正确工作,但是我拍的照片有正确的宽高比。

  • 最近,我们在Android应用程序中增加了对Chromecast的支持,但在对各种移动设备(手机和平板电脑)的扩展测试中,发现在许多移动设备上,Flipps应用程序都没有发现Chromecast。在相同的设备上,我们使用了最新版本的官方Chromecast SDK演示应用程序进行测试,该应用程序从https://github.com/googlecast/castvideo-Android下载(主