【问题标题】:Android - ImageView Orientation changes depending on deviceAndroid - ImageView 方向因设备而异
【发布时间】: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/内存资源非常低

【问题讨论】:

    标签: android android-camera android-imageview exif android-bitmap


    【解决方案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 标志来定位图片。图片以正确的方向本地保存。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-10-28
        • 2016-09-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-02
        • 2012-02-03
        相关资源
        最近更新 更多