【问题标题】:Android get Orientation of a camera Bitmap? And rotate back -90 degreesAndroid获取相机位图的方向?并向后旋转-90度
【发布时间】:2011-11-09 08:17:29
【问题描述】:

我有这个代码:

//choosed a picture
public void onActivityResult(int requestCode, int resultCode, Intent data) {

    if (resultCode == RESULT_OK) {
        if (requestCode == ImageHelper.SELECT_PICTURE) {

            String picture           = "";

            Uri selectedImageUri     = data.getData();
            //OI FILE Manager
            String filemanagerstring = selectedImageUri.getPath();
            //MEDIA GALLERY
            String selectedImagePath = ImageHelper.getPath(mycontext, selectedImageUri);

            picture=(selectedImagePath!=null)?selectedImagePath:filemanagerstring;

...

这只是一个图片选择器,来自画廊。这很好,但是当我在 ImageView 上打开这张照片时,用相机在“肖像模式”下拍摄的图像看起来不错,但用相机在“风景模式”下拍摄的图像以 -90 度打开。

如何将这些图片旋转回来?

    Bitmap output       = Bitmap.createBitmap(newwidth, newheight, Config.ARGB_8888);
    Canvas canvas       = new Canvas(output);

我试过了:

Log.e("w h", bitmap.getWidth()+" "+bitmap.getHeight());
if (bitmap.getWidth()<bitmap.getHeight()) canvas.rotate(-90);

但这不起作用,所有图像尺寸为:*2560 1920 像素(肖像和风景模式全部)

我可以做些什么来旋转横向图片?

【问题讨论】:

    标签: android


    【解决方案1】:

    如果使用数码相机或智能手机拍摄照片,旋转通常存储在照片的Exif 数据中,作为图像文件的一部分。您可以使用 Android ExifInterface 读取图像的 Exif 元数据。

    首先,创建ExifInterface

    ExifInterface exif = new ExifInterface(uri.getPath());
    

    接下来,找到当前的旋转:

    int rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);  
    

    将 exif 旋转转换为度数:

    int rotationInDegrees = exifToDegrees(rotation);
    

    在哪里

    private static int exifToDegrees(int exifOrientation) {        
        if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) { return 90; } 
        else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) {  return 180; } 
        else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) {  return 270; }            
        return 0;    
     }
    

    然后使用图像的实际旋转作为参考点,使用Matrix 旋转图像。

    Matrix matrix = new Matrix();
    if (rotation != 0) {matrix.preRotate(rotationInDegrees);}
    

    您使用Bitmap.createBitmap 方法创建新的旋转图像,该方法将Matrix 作为参数:

    Bitmap.createBitmap(Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter)
    

    Matrix m 持有新轮换的位置:

    Bitmap adjustedBitmap = Bitmap.createBitmap(sourceBitmap, 0, 0, width, height, matrix, true);
    

    有关有用的源代码示例,请参阅本教程:

    【讨论】:

    • 很好的答案,但你如何在矩阵中使用 int “旋转”?
    • 感谢您提供如此详尽的回答!
    • @GunnarKarlsson 我希望我能给你的不仅仅是一票!
    • 我收到一个错误,指出它不是文档 E/JHEAD: can't open '/document/image:82297'
    • 很好的答案,谢谢。 @JamesTan 如果您遇到 FILE NOT FOUND 异常,请使用 " private String getPath(Uri uri) { String[] data = { MediaStore.Images.Media.DATA }; CursorLoader loader = new CursorLoader(this, uri, data, null, null , null); 游标 cursor = loader.loadInBackground(); int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); return cursor.getString(column_index); }"
    【解决方案2】:

    如果您使用Jetpack CameraX,在onImageCaptured 方法中,您可以像这样从imageProxy 访问EXIF 数据提供的旋转度数:

    image.imageInfo.rotationDegrees
    

    然后在设置图像时,您可以根据这个度数旋转图像

    【讨论】:

    • 你可以通过getter做的更好。 imageProxy.getImageInfo().getRotationDegrees()。另外,如果您使用的是ImageAnalysis,则代理图像的方式相同
    【解决方案3】:

    最后一个答案在技术上是完美的,但我努力创建一个系统来管理图片、旋转、调整大小、缓存和加载到 ImageViews 中,我可以说这是一个地狱。即使完成所有操作,它有时也会在某些设备中导致 OutOfMemory 崩溃。

    我的观点是不要重新发明轮子,它有一个完美的设计。 Google 本身鼓励您使用Glide。它在一条线上工作,超级好用,体积和功能数量轻巧,默认管理 EXIF,它像魅力一样使用内存.. 它只是黑魔法编码 ;)

    我不确定Picasso 是否也管理 EXIF,但有一个关于它们的快速介绍:

    https://inthecheesefactory.com/blog/get-to-know-glide-recommended-by-google/en

    我的建议:不要浪费你的时间并使用它们。您可以在一行中解决您的问题:

    Glide.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);
    

    【讨论】:

    • 是的,但问题是,如果您已经解码/下采样了一点,或者使用 jpeg 格式压缩。 EXIF 没有被保留,所以您需要将属性重置为新文件。
    • 这不适用于带有 Google 相机的 Google 像素
    • 我不推荐使用 glide。我在 recyclerview 中滚动单个图像时遇到了很大的延迟,一旦我切换到使用滑行而不是处理自己,区别就是白天和黑夜。当然你也可以自己做同样的事情,但是上面的一个班轮是无价的
    猜你喜欢
    • 2021-03-01
    • 2020-03-27
    • 1970-01-01
    • 1970-01-01
    • 2021-04-17
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 2011-09-18
    相关资源
    最近更新 更多