Android - ImageView 方向因设备而异

Posted

技术标签:

【中文标题】Android - ImageView 方向因设备而异【英文标题】:Android - ImageView Orientation changes depending on device 【发布时间】:2013-12-15 15:10:54 【问题描述】:

我做了一个自定义的相机应用程序,我想在 ImageView 上显示图片。我在 3 款不同的手机(HTC Desire Z、Galaxy S4 和 Galaxy S2)上启动了我的程序。 在 HTC 上,图片的方向在 ImageView 中得到尊重,但在 Galaxys 中则没有。

我的程序是这样工作的:

-> 我用自定义相机应用拍照

->我根据手机方向(OrientationEventListener)设置图片的EXIF标志:

switch(getOrientation(rot))
                        case VERTICAL_ENDROIT : params.setRotation(90); break;
                        case HORIZONTAL_ENDROIT : params.setRotation(0); break;
                        case VERTICAL_ENVERS : params.setRotation(270); break;
                        case HORIZONTAL_ENVERS : params.setRotation(180); break;
                    
camera.setParameters(params); 

此功能在所有手机上都运行良好,它们都检测到并分配了正确的方向。

->我保存为JPG格式

-> 我将图片发送到 ImageView

Bitmap bm2 = BitmapFactory.decodeFile(photoItem.getPathPhoto(),options);
imageView.setImageBitmap(bm2);

对于 Galaxy,ImageView 上的 Orientation 总是相同的,对应 params.setRotation(0)。 HTC 没问题。

所以我试图在将图片发送到 ImageView 之前查看图片的 exif 标志:

int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1);

奇怪的是,对于 HTC,orientation 总是为 0 值,而对于三星,orientation 得到了正确的值 (1 3 6 8)。

结论: Galaxy Phones 的 EXIF 方向值可以,但 ImageView 上的方向不好。

对于 HTC 手机,EXIF 方向值是错误的,但方向是可以的。 (wtf?)

感谢您的回答:)

PS:我不想使用矩阵或图像处理的东西,因为我的 CPU/内存资源非常低

【问题讨论】:

【参考方案1】:
try 
        final File f = new File(directory, name);

        ExifInterface ei = new ExifInterface(f.getAbsolutePath());
        int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                ExifInterface.ORIENTATION_NORMAL);

        try 
            switch (orientation) 
            case ExifInterface.ORIENTATION_ROTATE_90:
                b = RotateBitmap(b, 90);
                break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                b = RotateBitmap(b, 180);
                break;
            case ExifInterface.ORIENTATION_ROTATE_270:
                b = RotateBitmap(b, 270);
                break;
            // etc.
            
         catch (OutOfMemoryError err) 

         catch (Exception e) 

        

        return b;
     catch (FileNotFoundException e) 
        e.printStackTrace();
     catch (IOException e) 
        e.printStackTrace();
    

public static Bitmap RotateBitmap(Bitmap source, float angle) 
    Matrix matrix = new Matrix();
    matrix.postRotate(angle);
    source = Bitmap.createBitmap(source, 0, 0, source.getWidth(),
            source.getHeight(), matrix, true);
    if (source != null) 
        b = null;
    
    return source;

此代码将完成您需要的功能。

【讨论】:

是的,它适用于矩阵我试过了,但我遇到了很多内存问题。 :// 使用单个位图 obj 并在任何地方替换该位图。在获取位图时也使用 Bitmap.Config.ARGB_8888;位图选项,会稍微减少这个内存问题。【参考方案2】:

试试下面的代码

 try 
    File f = new File(imagePath);
    ExifInterface exif = new ExifInterface(f.getPath());
    int orientation = exif.getAttributeInt(
            ExifInterface.TAG_ORIENTATION,
            ExifInterface.ORIENTATION_NORMAL);
    int angle = 0;

    if (orientation == ExifInterface.ORIENTATION_ROTATE_90) 
        angle = 90;
     else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) 
        angle = 180;
     else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) 
        angle = 270;
    

    Matrix mat = new Matrix();
    mat.postRotate(angle);
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inSampleSize = 2;

    Bitmap bmp = BitmapFactory.decodeStream(new FileInputStream(f),
            null, options);
    bitmap = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(),
            bmp.getHeight(), mat, true);
    ByteArrayOutputStream outstudentstreamOutputStream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.PNG, 100,
            outstudentstreamOutputStream);
    imageView.setImageBitmap(bitmap);

 catch (IOException e) 
    Log.w("TAG", "-- Error in setting image");
 catch (OutOfMemoryError oom) 
    Log.w("TAG", "-- OOM Error in setting image");

【讨论】:

【参考方案3】:

我发现为什么 Galaxy 和 HTC 的方向不一样。 HTC 不使用 EXIF 标志来定位图片。图片以正确的方向本地保存。

【讨论】:

以上是关于Android - ImageView 方向因设备而异的主要内容,如果未能解决你的问题,请参考以下文章

android设备重启时ImageView不保留图像

在 imageview 中使用时从相机或画廊拍摄的图片其方向发生变化,有时在 Android 中会垂直拉伸

ImageView在布局中显示但不在实际设备上显示

Android - imageView 上方的视图出现在某些设备上,但未出现在 Nexus 4 上

ImageView加载问题:在模拟器中工作,在真实设备中不起作用

android ImageView控件,图片如何铺满整个控件?