开源android-crop裁剪库的bug并修复

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

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

先看修复前bug截图:
开源android-crop裁剪库的bug并修复_第1张图片

开源android-crop裁剪库的bug并修复_第2张图片
修复后截图:
开源android-crop裁剪库的bug并修复_第3张图片

开源android-crop裁剪库的bug并修复_第4张图片

修复过程

  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-crop**clone我的官方fork版本。
example中相比原始项目增加了拍照后裁剪的demo。

你可能感兴趣的:(android开发)