【问题标题】:Is this bug in ExifInterface?这是 ExifInterface 中的错误吗?
【发布时间】:2017-01-05 15:58:41
【问题描述】:

我的问题是,在某些设备上,从图库中挑选的一些图像在 ImageView 中旋转。我找到了很多使用ExifInterface来解决这个问题的信息,所以我尝试使用它。但是当我尝试使用图像路径创建 ExifInterface 实例时出现奇怪的异常。

W/ExifInterface: Invalid image
java.io.IOException: Invalid marker: 89
at android.media.ExifInterface.getJpegAttributes(ExifInterface.java:1598)
at android.media.ExifInterface.loadAttributes(ExifInterface.java:1334)
at android.media.ExifInterface.<init>(ExifInterface.java:1052)
at com.igeotrack.igeo.ui.fragment.ProfileFragment.modifyOrientation(ProfileFragment.java:554)
at com.igeotrack.igeo.ui.fragment.ProfileFragment.setLogo(ProfileFragment.java:515)
at com.igeotrack.igeo.ui.fragment.ProfileFragment.onViewCreated(ProfileFragment.java:186)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1127)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1290)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:801)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1677)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:536)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5433)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
at dalvik.system.NativeStart.main(Native Method)

我的路径没有错,因为我之前使用过它并且它有效。这是我的代码。

        private void setLogo() {
        File mediaStorageDir = new File(Environment.getExternalStorageDirectory()
                + "/Android/data/"
                + getActivity().getPackageName()
                + "/Files");

        String mImageName="iGeoTrackUserAvatar.jpg";

        File mediaFile = new File(mediaStorageDir.getPath() + File.separator + mImageName);

//        if (mediaFile.exists()) {
//            Glide.with(getActivity())
//                    .load(mediaFile)
//                    .transform(new SystemUtils.CircleTransform(getActivity()))
//                    .diskCacheStrategy(DiskCacheStrategy.NONE)
//                    .skipMemoryCache(true)
//                    .into(mUserLogo);
//        }

        Bitmap bitmap = BitmapFactory.decodeFile(mediaFile.getPath());

        try {
            bitmap = modifyOrientation(bitmap, mediaFile.getAbsolutePath());
        } catch (IOException e) {
            e.printStackTrace();
        }

        mUserLogo.setImageBitmap(bitmap);
    }

我从 stackoverflow.com 上的许多答案中找到了这段代码

public static Bitmap modifyOrientation(Bitmap bitmap, String image_absolute_path) throws IOException {
    ExifInterface ei = new ExifInterface(image_absolute_path);
    int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

    switch (orientation) {
        case ExifInterface.ORIENTATION_ROTATE_90:
            return rotate(bitmap, 90);

        case ExifInterface.ORIENTATION_ROTATE_180:
            return rotate(bitmap, 180);

        case ExifInterface.ORIENTATION_ROTATE_270:
            return rotate(bitmap, 270);

        case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
            return flip(bitmap, true, false);

        case ExifInterface.ORIENTATION_FLIP_VERTICAL:
            return flip(bitmap, false, true);

        default:
            return bitmap;
    }
}

public static Bitmap rotate(Bitmap bitmap, float degrees) {
    Matrix matrix = new Matrix();
    matrix.postRotate(degrees);
    return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}

public static Bitmap flip(Bitmap bitmap, boolean horizontal, boolean vertical) {
    Matrix matrix = new Matrix();
    matrix.preScale(horizontal ? -1 : 1, vertical ? -1 : 1);
    return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}

我没有发现任何关于这个问题的信息,但我发现 Jake Wharton 的 mention 可能是 Android 中的错误。你能帮助我吗?因为我不明白如何解决这个问题。

【问题讨论】:

  • “我的路径没有错”——你肯定是在奇怪地组装它。你所拥有的几乎就是你从getExternalFilesDir() 得到的,除了你在Files 中有一个大写F,通常是files。如果您还没有这样做,请切换到the support version of ExifInterface,如the SDK one has security flaws。它也可能有助于解决这个问题。
  • Invalid marker: 89 我假设图像包含未知或损坏的 exif 标记“89”。如果您将 jpg 复制到 PC 并使用 exiftools 查看会发生什么?我有两台数码相机,它们将损坏的 exif 数据写入它们的 jpg-s。你有可能有一些损坏的 jpg-s 吗?
  • 您是否尝试用android.googlesource.com/platform/frameworks/base/+/… 的android-7.1-s 源代码版本替换ExifInterface?
  • @CommonsWare 谢谢!当我使用 Gradle 'com.android.support:exifinterface:25.1.0' 编译时,这个类已经开始工作而不是标准实现。尽管我在最终实现中没有使用 ExifInterface,但您的建议对我有所帮助,所以请添加完整的答案并为其他人解释。

标签: android android-imageview android-file


【解决方案1】:

CommonsWare 的建议非常好。当我使用 Gradle com.android.support:exifinterface:25.1.0 编译时,这个类已经开始工作,而不是标准实现。

【讨论】:

  • 您好,您的问题通过实现这个库解决了吗?还是有什么需要做的?我还发现了错误“无效标记:89”。
  • @HasibAkter 我通过添加这个依赖解决了它
猜你喜欢
  • 1970-01-01
  • 2013-05-04
  • 2011-09-28
  • 2017-07-23
  • 2012-09-15
  • 2017-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多