平方X 发表于 2018-1-4 15:36:39

[2500]裁剪图片被旋转


使用的库为 (https://github.com/jdamcd/android-crop)
选择它,因为其
> based on code from AOSP

但是小米 6 测试出现了裁剪图片不正常的 bug,表现为图片长宽正常,但相比原图发生了旋转而不能正常显示。
后来发现同一张照片就是会出现问题。

首先想到是不是有 bug,于是查看 (https://github.com/jdamcd/android-crop/issues)
果然有不少人提出了相同的问题,想在 issues 中找找有没有解决方法。
后来着重在 (https://github.com/jdamcd/android-crop/pulls) 中查看。
确实有不少的请求,也有一些给出了解方案,整理如下:

# 解决方案
添加旋转,去除 copyExifRotation ,去除预览。

以下是一些请求

(https://github.com/jdamcd/android-crop/pull/251)

使用了 Support Library ,测试成功,但是不想引入库。
同时提供了注释
>For the same reason (to be protocol independent), the EXIF information is not copied
to the output anymore. Instead, the cropped image is rotated using Matrix.postRotate
(as a result of this, it is not necessary to rewrite the output just to copy the EXIF
rotation as done before).


(https://github.com/jdamcd/android-crop/pull/190)

知道了不需要展示,可以注掉,上面 251 的解决方案,会在裁剪后先展示旋转的图,再返回,不展示以后更好了。
```
      if (croppedImage != null) {
            //imageView.setImageRotateBitmapResetBase(new RotateBitmap(croppedImage, exifRotation), true);
            //imageView.center();
            imageView.highlightViews.clear();
      }
```
后面的处理也是正确的处理,除了包含 copyExifRotation
```
                //if the cutting box are rectangle( outWidth != outHeight ),and the exifRotation is 90 or 270,
                //the outWidth and outHeight should be interchanged
               if (exifRotation==90 || exifRotation==270) {
                     int temp=outWidth;
                     outWidth=outHeight;
                     outHeight=temp;
               }
               ...
                croppedImage = decoder.decodeRegion(rect, new BitmapFactory.Options());
                Matrix matrix = new Matrix();
                if (rect.width() > outWidth || rect.height() > outHeight) {
                  matrix.postScale((float) outWidth / rect.width(), (float) outHeight / rect.height());
                }
                //If the picture's exifRotation !=0 ,they should be rotated to 0 degrees
                //If the picture need not to be scale, they also need to be rotate to 0 degrees
                matrix.postRotate(exifRotation);
                croppedImage = Bitmap.createBitmap(croppedImage, 0, 0, croppedImage.getWidth(), croppedImage.getHeight(), matrix, true);
```

(https://github.com/jdamcd/android-crop/pull/146)

有图,有注释,很棒,但是仍然有 copyExifRotation
可以看到 190 的参考了这个 146 的。
```
                croppedImage = decoder.decodeRegion(rect, new BitmapFactory.Options());
                if (rect.width() > outWidth || rect.height() > outHeight) {
                  Matrix matrix = new Matrix();
                  matrix.postScale((float) outWidth / rect.width(), (float) outHeight / rect.height());

                  //if the picture's exifRotation !=0 ,they should be rotate to 0 degrees
                  matrix.postRotate(exifRotation);
                  croppedImage = Bitmap.createBitmap(croppedImage, 0, 0, croppedImage.getWidth(), croppedImage.getHeight(), matrix, true);
                }else{
                  //if the picture need not to be scale, they also neet to be rotate to 0 degrees
                  Matrix matrix = new Matrix();
                  matrix.postRotate(exifRotation);
                  croppedImage = Bitmap.createBitmap(croppedImage, 0, 0, croppedImage.getWidth(), croppedImage.getHeight(), matrix, true);
                }
```

(https://github.com/jdamcd/android-crop/pull/116)

简单粗暴,注释了 copyExifRotation ,加上了 matrix.setRotate(exifRotation);   
但是应该加到外面才对,而且没有处理交换宽高。

页: [1]
查看完整版本: [2500]裁剪图片被旋转