最近项目中使用了开源裁剪库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-cropclone我的官方fork版本。
example中相比原始项目增加了拍照后裁剪的demo。
所有评论(0)