最近项目中使用了开源裁剪库android-crop,使用过程中遇到了三星手机拍照后裁剪的bug,上官方github里看issues发现果真还是有开发者同样遇到这个问题的。bug描述如下:
用手机拍照(保持竖屏)后进入裁剪界面,裁剪完后的图片是旋转90度的,但是在裁剪预览界面中看的是正常的。

最好到官方github去clone原始项目,运行其中的example程序体验下。

先看修复前bug截图:
1.png

2.png
修复后截图:
Paste_Image.png

Paste_Image.png

修复过程

  1. CropImageActivity.java修改前的saveOutput方法:
private void saveOutput(Bitmap croppedImage) {
    if (saveUri != null) {
        OutputStream outputStream = null;
        try {
            outputStream = getContentResolver().openOutputStream(saveUri);
            if (outputStream != null) {
                croppedImage.compress(saveAsPng ? Bitmap.CompressFormat.PNG : Bitmap.CompressFormat.JPEG,
                        90,     // note: quality is ignored when using PNG
                        outputStream);
            }
        } catch (IOException e) {
            setResultException(e);
            Log.e("Cannot open file: " + saveUri, e);
        } finally {
            CropUtil.closeSilently(outputStream);
        }

        CropUtil.copyExifRotation(
                CropUtil.getFromMediaUri(this, getContentResolver(), sourceUri),
                CropUtil.getFromMediaUri(this, getContentResolver(), saveUri)
        );

        setResultUri(saveUri);
    }

    final Bitmap b = croppedImage;
    handler.post(new Runnable() {
        public void run() {
            imageView.clear();
            b.recycle();
        }
    });

    finish();
}

修改后的saveOutput方法:

private void saveOutput(Bitmap croppedImage) {
    if (saveUri != null) {
        OutputStream outputStream = null;

        Bitmap destBitmap = croppedImage;
        if(exifRotation != 0){
            destBitmap = CropUtil.rotateImage(croppedImage, exifRotation);
        }
        FileInputStream inputStream = null;
        try {
            //save bitmap to file
            outputStream = getContentResolver().openOutputStream(saveUri);
            if (outputStream != null) {
                destBitmap.compress(saveAsPng ? Bitmap.CompressFormat.PNG : Bitmap.CompressFormat.JPEG,
                        90,     // note: quality is ignored when using PNG
                        outputStream);
            }
            destBitmap.recycle();
        } catch (OutOfMemoryError error) {
        } catch (IOException e){
            setResultException(e);
            Log.e("Cannot open file: " + saveUri, e);
        }finally {
            CropUtil.closeSilently(inputStream);
            CropUtil.closeSilently(outputStream);
        }

        CropUtil.copyExifRotation(
                CropUtil.getFromMediaUri(this, getContentResolver(), sourceUri),
                CropUtil.getFromMediaUri(this, getContentResolver(), saveUri)
        );

        setResultUri(saveUri);
    }

    final Bitmap b = croppedImage;
    handler.post(new Runnable() {
        public void run() {
            imageView.clear();
            b.recycle();
        }
    });

    finish();
}

其实只是加入了旋转角度的判定,如果角度不为0则旋转图片再保存

if(exifRotation != 0){
    destBitmap = CropUtil.rotateImage(croppedImage, exifRotation);
}

CropUtil.rotateImage的代码如下:

public static Bitmap rotateImage(Bitmap img, int rotate) {
    Matrix matrix = new Matrix();
    matrix.postRotate(rotate);
    int width = img.getWidth();
    int height = img.getHeight();
    img = Bitmap.createBitmap(img, 0, 0, width, height, matrix, false);
    return img;
}
  1. 在CropImageActivity.java的onSaveClicked方法中的croppedImage = decodeRegionCrop(r, outWidth, outHeight);前加入如下代码:
if(exifRotation != 0 && exifRotation % 90 == 0){
    int tmp = outWidth;
    outWidth = outHeight;
    outHeight = tmp;
}

如果有旋转角度,则在decodeRegionCrop裁剪前,需要对裁剪的宽和高进行交换处理。

写在最后

大家可以在我的github地址android-cropclone我的官方fork版本。
example中相比原始项目增加了拍照后裁剪的demo。

转载于:https://www.cnblogs.com/laoguigame/p/5645124.html

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐