@TargetApi(10) private Bitmap decodeRegionCrop(Bitmap croppedImage, Rect rect) { // Release memory now clearImageView(); InputStream is = null; try { is = getContentResolver().openInputStream(sourceUri); BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(is, false); final int width = decoder.getWidth(); final int height = decoder.getHeight(); if (exifRotation != 0) { // Adjust crop area to account for image rotation Matrix matrix = new Matrix(); matrix.setRotate(-exifRotation); RectF adjusted = new RectF(); matrix.mapRect(adjusted, new RectF(rect)); // Adjust to account for origin at 0,0 adjusted.offset(adjusted.left < 0 ? width : 0, adjusted.top < 0 ? height : 0); rect = new Rect( (int) adjusted.left, (int) adjusted.top, (int) adjusted.right, (int) adjusted.bottom); } try { croppedImage = decoder.decodeRegion(rect, new BitmapFactory.Options()); } catch (IllegalArgumentException e) { // Rethrow with some extra information throw new IllegalArgumentException( "Rectangle " + rect + " is outside of the image (" + width + "," + height + "," + exifRotation + ")", e); } } catch (IOException e) { Log.e("Error cropping image: " + e.getMessage(), e); finish(); } catch (OutOfMemoryError e) { Log.e("OOM cropping image: " + e.getMessage(), e); setResultException(e); } finally { CropUtil.closeSilently(is); } return croppedImage; }
private Bitmap inMemoryCrop( RotateBitmap rotateBitmap, Bitmap croppedImage, Rect r, int width, int height, int outWidth, int outHeight) { // In-memory crop means potential OOM errors, // but we have no choice as we can't selectively decode a bitmap with this API level System.gc(); try { croppedImage = Bitmap.createBitmap(outWidth, outHeight, Bitmap.Config.RGB_565); RectF dstRect = new RectF(0, 0, width, height); Matrix m = new Matrix(); m.setRectToRect(new RectF(r), dstRect, Matrix.ScaleToFit.FILL); m.preConcat(rotateBitmap.getRotateMatrix()); if (isCircleCrop) { return cropCircleView(rotateBitmap.getBitmap(), croppedImage, m); } Canvas canvas = new Canvas(croppedImage); canvas.drawBitmap(rotateBitmap.getBitmap(), m, null); } catch (OutOfMemoryError e) { Log.e("OOM cropping image: " + e.getMessage(), e); setResultException(e); System.gc(); } // Release bitmap memory as soon as possible clearImageView(); return croppedImage; }
private void setupFromIntent() { Intent intent = getIntent(); Bundle extras = intent.getExtras(); if (extras != null) { aspectX = extras.getInt(Crop.Extra.ASPECT_X); aspectY = extras.getInt(Crop.Extra.ASPECT_Y); maxX = extras.getInt(Crop.Extra.MAX_X); maxY = extras.getInt(Crop.Extra.MAX_Y); isCircleCrop = extras.getBoolean(Crop.Extra.IS_CIRCLE_CROP); saveUri = extras.getParcelable(MediaStore.EXTRA_OUTPUT); } sourceUri = intent.getData(); if (sourceUri != null) { exifRotation = CropUtil.getExifRotation(CropUtil.getFromMediaUri(getContentResolver(), sourceUri)); InputStream is = null; try { sampleSize = calculateBitmapSampleSize(sourceUri); is = getContentResolver().openInputStream(sourceUri); BitmapFactory.Options option = new BitmapFactory.Options(); option.inSampleSize = sampleSize; rotateBitmap = new RotateBitmap(BitmapFactory.decodeStream(is, null, option), exifRotation); } catch (IOException e) { Log.e("Error reading image: " + e.getMessage(), e); setResultException(e); } catch (OutOfMemoryError e) { Log.e("OOM reading image: " + e.getMessage(), e); setResultException(e); } finally { CropUtil.closeSilently(is); } } }
private void saveOutput(Bitmap croppedImage) { if (saveUri != null) { OutputStream outputStream = null; try { outputStream = getContentResolver().openOutputStream(saveUri); if (outputStream != null) { if (exifRotation > 0) { try { Matrix matrix = new Matrix(); matrix.reset(); matrix.postRotate(exifRotation); Bitmap bMapRotate = Bitmap.createBitmap( croppedImage, 0, 0, croppedImage.getWidth(), croppedImage.getHeight(), matrix, true); bMapRotate.compress(Bitmap.CompressFormat.PNG, 70, outputStream); } catch (Exception e) { e.printStackTrace(); croppedImage.compress(Bitmap.CompressFormat.PNG, 70, outputStream); } finally { if (croppedImage != null && !croppedImage.isRecycled()) { croppedImage.recycle(); } } } else { croppedImage.compress(Bitmap.CompressFormat.PNG, 70, outputStream); } } } catch (IOException e) { setResultException(e); Log.e("Cannot open file: " + saveUri, e); } finally { CropUtil.closeSilently(outputStream); } if (!IN_MEMORY_CROP) { // In-memory crop negates the rotation CropUtil.copyExifRotation( CropUtil.getFromMediaUri(getContentResolver(), sourceUri), CropUtil.getFromMediaUri(getContentResolver(), saveUri)); } setResultUri(saveUri); } final Bitmap b = croppedImage; handler.post( new Runnable() { public void run() { imageView.clear(); b.recycle(); } }); finish(); }