在某些姜饼设备上,使用ACTION_IMAGE_CAPTURE拍摄的图像的ExifInterface.TAG_ORIENTATION始终返回1. [英] Images taken with ACTION_IMAGE_CAPTURE always returns 1 for ExifInterface.TAG_ORIENTATION on some Gingerbread devices

查看:172
本文介绍了在某些姜饼设备上,使用ACTION_IMAGE_CAPTURE拍摄的图像的ExifInterface.TAG_ORIENTATION始终返回1.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用ACTION_IMAGE_CAPTURE活动时出现定向问题.我已使用TAG_ORIENTATION以便相应地旋转图片.但是现在我们发现,在某些较新的设备上,这是行不通的.实际上,它在所有方向上都返回1.

这是我们在上面观察过的设备的列表;

  • 三星Infuse 4G(2.3.3)
  • 三星Galaxy SII X(2.3.5)
  • 索尼Xperia Arc(2.3.3)

有趣的是,一旦此图像成为图库,它就会正确显示,如果我选择它,则会正确填充TAG_ORIENTATION.因此,OS会以某种方式正确填充此信息,但不能在ActivityResult上填充.

确定方向的最可靠方法是什么?另一个问题上有人建议比较高度和宽度,但是在获取高度和宽度时,会根据方向正确切换高度(另一个谜团)

看来这可能与另一个错误有关,在该错误中,操作系统复制了在图库中拍摄的图像(只应将图像保存在我们指定的URL中),原因是该图像在图库中具有ORIENTATION信息,而位于指定位置的信息则没有.

这是错误; http://code.google.com/p/android/issues/detail?id=19268

EDIT-2 :我向Android提交了一个新错误.我很确定这是与上述错误相关的OS错误. http://code.google.com/p/android/issues/detail?id=22822

解决方案

好吧,看来这个针对Android的错误不会在一段时间内得到修复.尽管我找到了一种实现ExifInformation的方法,以便使两个设备(具有正确的Exif标签和不正确的exif标签的设备一起工作).

因此问题出在某些(较新的)设备上,存在一个错误,该错误使拍摄的照片没有适当的exif标签就被保存在您的应用文件夹中,而正确旋转的图像被保存在android默认文件夹中(即使它不应该如此)是).

现在我要做的是,我记录从我的应用程序启动相机应用程序的时间.关于活动结果,我查询媒体提供者以查看在保存此时间戳记之后是否保存了任何图片.这意味着,最有可能的操作系统将正确旋转的图片保存在默认文件夹中,并且当然在媒体存储中放置了一个条目,我们可以使用此行中的旋转信息.现在,确保我们在查看正确的图像,我将该文件的大小与我可以访问的文件大小进行比较(保存在我自己的应用程序文件夹中);

    int rotation =-1;
    long fileSize = new File(filePath).length();

    Cursor mediaCursor = content.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[] {MediaStore.Images.ImageColumns.ORIENTATION, MediaStore.MediaColumns.SIZE }, MediaStore.MediaColumns.DATE_ADDED + ">=?", new String[]{String.valueOf(captureTime/1000 - 1)}, MediaStore.MediaColumns.DATE_ADDED + " desc");

    if (mediaCursor != null && captureTime != 0 && mediaCursor.getCount() !=0 ) {
        while(mediaCursor.moveToNext()){
            long size = mediaCursor.getLong(1);
            //Extra check to make sure that we are getting the orientation from the proper file
            if(size == fileSize){
                rotation = mediaCursor.getInt(0);
                break;
            }
        }
    }

现在,如果此时的旋转度仍为-1,则意味着这是具有正确旋转信息的手机之一.此时,我们可以对返回到onActivityResult的文件使用常规的exif方向

    else if(rotation == -1){
        rotation = getExifOrientationAttribute(filePath);
    }

您可以轻松地找到如何找到exif方向,例如此问题中的答案相机Android中的方向问题

还请注意,ExifInterface仅在Api 5级以后才受支持.因此,如果您想在2.0之前支持电话,则可以使用我为Java提供的这个方便的库,由Drew Noakes提供. http://www.drewnoakes.com/code/exif/

祝你图像旋转好运!

因为有人问我,我用过的意图以及我的开始方式是这样的

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//mediaFile is where the image will be saved
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mediaFile));
startActivityForResult(intent, 1);

I had the orientation issue when working with ACTION_IMAGE_CAPTURE activity. I have used the TAG_ORIENTATION so that I would rotate the picture accordingly. But now we found that on some newer devices this doesn't work. In fact it returns 1 for all orientations.

Here's the list of devices we observed this on;

  • Samsung Infuse 4G (2.3.3)
  • Samsung Galaxy SII X (2.3.5)
  • Sony Xperia Arc (2.3.3)

Interesting thing is that once this image is the gallery it shows up properly and if I select it, the TAG_ORIENTATION is populated properly. So somehow the OS fills this information properly but not on ActivityResult.

What's the most reliable way to figure the orientation? Someone on another question suggested comparing height and width but when getting these, they are properly switched based on orientation (another mystery)

EDIT: It seems that this could be connected to another bug where the OS duplicates the image taken in the gallery (it's only supposed to save the image in the URL specified by us), the thing is this image in gallery has the ORIENTATION information while the one in the specified location doesn't.

This is the bug; http://code.google.com/p/android/issues/detail?id=19268

EDIT-2: I've filed a new bug with Android. I'm pretty sure this is an OS bug related the aforementioned bug. http://code.google.com/p/android/issues/detail?id=22822

解决方案

Ok guys, it seems like this bug for android won't be fixed for a while. Although I found a way to implement the ExifInformation so that both devices (ones with proper Exif tag, and also improper exif tags work together)..

So the issue is on some (newer) devices, there's a bug that makes the picture taken saved in your app folder without proper exif tags while a properly rotated image is saved in the android default folder (even though it shouldn't be)..

Now what I do is, i record the time when I'm starting the camera app from my app. THen on activity result, I query the Media Provider to see if any pictures were saved after this timestamp I saved. That means that, most likely OS saved the properly rotated picture in the default folder and of course put a entry in the media store and we can use the rotation information from this row. Now to make sure we are looking at the right image, i compare the size of this file to the one I have access to (saved in my own app folder);

    int rotation =-1;
    long fileSize = new File(filePath).length();

    Cursor mediaCursor = content.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[] {MediaStore.Images.ImageColumns.ORIENTATION, MediaStore.MediaColumns.SIZE }, MediaStore.MediaColumns.DATE_ADDED + ">=?", new String[]{String.valueOf(captureTime/1000 - 1)}, MediaStore.MediaColumns.DATE_ADDED + " desc");

    if (mediaCursor != null && captureTime != 0 && mediaCursor.getCount() !=0 ) {
        while(mediaCursor.moveToNext()){
            long size = mediaCursor.getLong(1);
            //Extra check to make sure that we are getting the orientation from the proper file
            if(size == fileSize){
                rotation = mediaCursor.getInt(0);
                break;
            }
        }
    }

Now if the rotation at this point is still -1, then that means this is one of the phones with proper rotation information. At this point, we can use the regular exif orientation on the file that's returned to our onActivityResult

    else if(rotation == -1){
        rotation = getExifOrientationAttribute(filePath);
    }

You can easily find out how to find exif orientations like the answer in this question Camera orientation issue in Android

Also note that ExifInterface is only supported after Api level 5.. So if you want to support phones before 2.0, then you can use this handy library I found for java courtesy of Drew Noakes; http://www.drewnoakes.com/code/exif/

Good luck with your image rotating!

EDIT: Because it was asked, the intent I've used and how i started was like this

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//mediaFile is where the image will be saved
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mediaFile));
startActivityForResult(intent, 1);

这篇关于在某些姜饼设备上,使用ACTION_IMAGE_CAPTURE拍摄的图像的ExifInterface.TAG_ORIENTATION始终返回1.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆