private void clearImageView() { imageView.clear(); if (rotateBitmap != null) { rotateBitmap.recycle(); } System.gc(); }
@Override protected void onDestroy() { super.onDestroy(); if (null != mImageView) { mImageView.clear(); } if (null != mBitmap) { if (!mBitmap.isRecycled()) { mBitmap.recycle(); } mBitmap = null; } }
private void onSaveClicked() { // TODO this code needs to change to use the decode/crop/encode single // step api so that we don't require that the whole (possibly large) // bitmap doesn't have to be read into memory if (mCrop == null) { return; } if (mSaving) return; mSaving = true; Bitmap croppedImage; // If the output is required to a specific size, create an new image // with the cropped image in the center and the extra space filled. if (mOutputX != 0 && mOutputY != 0 && !mScale) { // Don't scale the image but instead fill it so it's the // required dimension croppedImage = Bitmap.createBitmap(mOutputX, mOutputY, Bitmap.Config.RGB_565); Canvas canvas = new Canvas(croppedImage); Rect srcRect = mCrop.getCropRect(); Rect dstRect = new Rect(0, 0, mOutputX, mOutputY); int dx = (srcRect.width() - dstRect.width()) / 2; int dy = (srcRect.height() - dstRect.height()) / 2; // If the srcRect is too big, use the center part of it. srcRect.inset(Math.max(0, dx), Math.max(0, dy)); // If the dstRect is too big, use the center part of it. dstRect.inset(Math.max(0, -dx), Math.max(0, -dy)); // Draw the cropped bitmap in the center canvas.drawBitmap(mBitmap, srcRect, dstRect, null); // Release bitmap memory as soon as possible mImageView.clear(); mBitmap.recycle(); } else { Rect r = mCrop.getCropRect(); int width = r.width(); int height = r.height(); // If we are circle cropping, we want alpha channel, which is the // third param here. croppedImage = Bitmap.createBitmap( width, height, mCircleCrop ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565); Canvas canvas = new Canvas(croppedImage); Rect dstRect = new Rect(0, 0, width, height); canvas.drawBitmap(mBitmap, r, dstRect, null); // Release bitmap memory as soon as possible mImageView.clear(); mBitmap.recycle(); if (mCircleCrop) { // OK, so what's all this about? // Bitmaps are inherently rectangular but we want to return // something that's basically a circle. So we fill in the // area around the circle with alpha. Note the all important // PortDuff.Mode.CLEAR. Canvas c = new Canvas(croppedImage); Path p = new Path(); p.addCircle(width / 2F, height / 2F, width / 2F, Path.Direction.CW); c.clipPath(p, Region.Op.DIFFERENCE); c.drawColor(0x00000000, PorterDuff.Mode.CLEAR); } // If the required dimension is specified, scale the image. if (mOutputX != 0 && mOutputY != 0 && mScale) { croppedImage = Util.transform( new Matrix(), croppedImage, mOutputX, mOutputY, mScaleUp, Util.RECYCLE_INPUT); } } mImageView.setImageBitmapResetBase(croppedImage, true); mImageView.center(true, true); mImageView.mHighlightViews.clear(); // Return the cropped image directly or save it to the specified URI. Bundle myExtras = getIntent().getExtras(); if (myExtras != null && (myExtras.getParcelable("data") != null || myExtras.getBoolean("return-data"))) { Bundle extras = new Bundle(); extras.putParcelable("data", croppedImage); setResult(RESULT_OK, (new Intent()).setAction("inline-data").putExtras(extras)); finish(); } else { final Bitmap b = croppedImage; final int msdId = mSetWallpaper ? R.string.wallpaper : R.string.savingImage; Util.startBackgroundJob( this, this, null, getResources().getString(msdId), new Runnable() { public void run() { saveOutput(b); } }, mHandler); } }
private void onSaveClicked() { if (!mNeedCrop) { Bitmap nocropBitmap = createNoCropBitmap(); mImageView.clear(); if (nocropBitmap != mBitmap) { mBitmap.recycle(); mBitmap = null; } if (null != nocropBitmap) { // Return the cropped image directly or save it to the specified // URI. Bundle myExtras = getIntent().getExtras(); if (myExtras != null && (myExtras.getParcelable("data") != null || myExtras.getBoolean("return-data"))) { Bundle extras = new Bundle(); extras.putParcelable("data", nocropBitmap); setResult( RESULT_OK, (new Intent()).setAction(ICustomAction.ACTION_INLINE_DATA).putExtras(extras)); finish(); } else { final Bitmap b = nocropBitmap; final int msdId = mSetWallpaper ? R.string.wallpaper : R.string.savingImage; Util.startBackgroundJob( this, null, getResources().getString(msdId), new Runnable() { @Override public void run() { saveOutput(b); } }, mHandler); } } else { setResult(RESULT_CANCELED); finish(); } return; } // TODO this code needs to change to use the decode/crop/encode single // step api so that we don't require that the whole (possibly large) // bitmap doesn't have to be read into memory if (mCrop == null) { return; } if (mSaving) { return; } mSaving = true; Bitmap croppedImage = null; Bitmap.Config bmpConfig = mHasApha ? Bitmap.Config.ARGB_8888 : Bitmap.Config.ARGB_8888; // If the output is required to a specific size, create an new image // with the cropped image in the center and the extra space filled. if (mOutputX != 0 && mOutputY != 0 && !mScale) { // Don't scale the image but instead fill it so it's the // required dimension try { croppedImage = Bitmap.createBitmap(mOutputX, mOutputY, bmpConfig); } catch (OutOfMemoryError e) { // 创建失败 e.printStackTrace(); OutOfMemoryHandler.handle(); Toast.makeText(this, getString(R.string.err_out_of_memory), Toast.LENGTH_SHORT); // Release bitmap memory as soon as possible mImageView.clear(); mBitmap.recycle(); mBitmap = null; setResult(RESULT_CANCELED); finish(); return; } Canvas canvas = new Canvas(croppedImage); Rect srcRect = mCrop.getCropRect(); Rect dstRect = new Rect(0, 0, mOutputX, mOutputY); int dx = (srcRect.width() - dstRect.width()) / 2; int dy = (srcRect.height() - dstRect.height()) / 2; // If the srcRect is too big, use the center part of it. srcRect.inset(Math.max(0, dx), Math.max(0, dy)); // If the dstRect is too big, use the center part of it. dstRect.inset(Math.max(0, -dx), Math.max(0, -dy)); // Draw the cropped bitmap in the center canvas.drawBitmap(mBitmap, srcRect, dstRect, null); // Release bitmap memory as soon as possible mImageView.clear(); mBitmap.recycle(); } else { Rect r = mCrop.getCropRect(); // int width = r.width(); // int height = r.height(); // If we are circle cropping, we want alpha channel, which is the // third param here. try { croppedImage = Bitmap.createBitmap(mOutputX, mOutputY, bmpConfig); } catch (OutOfMemoryError e) { e.printStackTrace(); OutOfMemoryHandler.handle(); // 创建失败 // Toast.makeText(this, getString(R.string.err_out_of_memory), // Toast.LENGTH_SHORT).show(); // Release bitmap memory as soon as possible mImageView.clear(); mBitmap.recycle(); setResult(RESULT_CANCELED); finish(); return; } Canvas canvas = new Canvas(croppedImage); canvas.setDrawFilter( new PaintFlagsDrawFilter( 0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG)); // 在有缩放的情况下需要提高绘图质量 Rect dstRect = new Rect(0, 0, mOutputX, mOutputY); canvas.drawBitmap(mBitmap, r, dstRect, null); // Release bitmap memory as soon as possible mImageView.clear(); mBitmap.recycle(); // if (mCircleCrop) { // // OK, so what's all this about? // // Bitmaps are inherently rectangular but we want to return // // something that's basically a circle. So we fill in the // // area around the circle with alpha. Note the all important // // PortDuff.Mode.CLEAR. // Canvas c = new Canvas(croppedImage); // Path p = new Path(); // p.addCircle(width / 2F, height / 2F, width / 2F, // Path.Direction.CW); // c.clipPath(p, Region.Op.DIFFERENCE); // c.drawColor(0x00000000, PorterDuff.Mode.CLEAR); // } // If the required dimension is specified, scale the image. // if (mOutputX != 0 && mOutputY != 0 && mScale) { // croppedImage = Util.transform(new Matrix(), croppedImage, // mOutputX, mOutputY, mScaleUp, Util.RECYCLE_INPUT); // } } mImageView.setImageBitmapResetBase(croppedImage, true); mImageView.center(true, true); mImageView.mHighlightViews.clear(); // Return the cropped image directly or save it to the specified URI. Bundle myExtras = getIntent().getExtras(); if (myExtras != null && (myExtras.getParcelable("data") != null || myExtras.getBoolean("return-data"))) { Bundle extras = new Bundle(); extras.putParcelable("data", croppedImage); setResult( RESULT_OK, (new Intent()).setAction(ICustomAction.ACTION_INLINE_DATA).putExtras(extras)); finish(); } else { final Bitmap b = croppedImage; final int msdId = mSetWallpaper ? R.string.wallpaper : R.string.savingImage; Util.startBackgroundJob( this, null, getResources().getString(msdId), new Runnable() { @Override public void run() { saveOutput(b); } }, mHandler); } }