您的位置:首页 > 移动开发 > Android开发

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

2016-07-05 20:27 555 查看
最近项目中使用了开源裁剪库android-crop,使用过程中遇到了三星手机拍照后裁剪的bug,上官方github里看issues发现果真还是有开发者同样遇到这个问题的。bug描述如下:

用手机拍照(保持竖屏)后进入裁剪界面,裁剪完后的图片是旋转90度的,但是在裁剪预览界面中看的是正常的。

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

先看修复前bug截图:





修复后截图:





修复过程

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;
}


在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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: