最近項目中使用了開源裁剪庫android-crop,使用過程當中遇到了三星手機拍照後裁剪的bug,上官方github裏看issues發現果然仍是有開發者一樣遇到這個問題的。bug描述以下:
用手機拍照(保持豎屏)後進入裁剪界面,裁剪完後的圖片是旋轉90度的,可是在裁剪預覽界面中看的是正常的。java
最好到官方github去clone原始項目,運行其中的example程序體驗下。android
先看修復前bug截圖:
git
修復後截圖:
github
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方法:post
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則旋轉圖片再保存ui
if(exifRotation != 0){ destBitmap = CropUtil.rotateImage(croppedImage, exifRotation); }
CropUtil.rotateImage的代碼以下:this
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; }
croppedImage = decodeRegionCrop(r, outWidth, outHeight);
前加入以下代碼:if(exifRotation != 0 && exifRotation % 90 == 0){ int tmp = outWidth; outWidth = outHeight; outHeight = tmp; }
若是有旋轉角度,則在decodeRegionCrop裁剪前,須要對裁剪的寬和高進行交換處理。code
你們能夠在個人github地址android-cropclone個人官方fork版本。
example中相比原始項目增長了拍照後裁剪的demo。orm