private void initViews() { imageView = (CropImageView) findViewById(R.id.crop_image); imageView.context = this; imageView.setRecycler( new ImageViewTouchBase.Recycler() { @Override public void recycle(Bitmap b) { b.recycle(); System.gc(); } }); findViewById(R.id.btn_cancel) .setOnClickListener( new View.OnClickListener() { public void onClick(View v) { setResult(RESULT_CANCELED); finish(); } }); findViewById(R.id.btn_done) .setOnClickListener( new View.OnClickListener() { public void onClick(View v) { onSaveClicked(); } }); }
private void setupViews() { setContentView(R.layout.crop__activity_crop); imageView = (CropImageView) findViewById(R.id.crop_image); imageView.context = this; imageView.setRecycler( new ImageViewTouchBase.Recycler() { @Override public void recycle(Bitmap b) { b.recycle(); System.gc(); } }); findViewById(R.id.btn_cancel) .setOnClickListener( new View.OnClickListener() { public void onClick(View v) { setResult(RESULT_CANCELED); finish(); } }); findViewById(R.id.btn_done) .setOnClickListener( new View.OnClickListener() { public void onClick(View v) { onSaveClicked(); } }); findViewById(R.id.btn_rotate_left) .setOnClickListener( new View.OnClickListener() { public void onClick(View v) { Bitmap bitmap = drawableToBitmap(imageView.getDrawable()); rotateDegreesCounter = rotateDegreesCounter - 90; rotateBitmap = new RotateBitmap(bitmap, rotateDegreesCounter); if (rotateBitmap != null) { startCrop(); } } }); findViewById(R.id.btn_rotate_right) .setOnClickListener( new View.OnClickListener() { public void onClick(View v) { Bitmap bitmap = drawableToBitmap(imageView.getDrawable()); rotateDegreesCounter = rotateDegreesCounter + 90; rotateBitmap = new RotateBitmap(bitmap, rotateDegreesCounter); if (rotateBitmap != null) { startCrop(); } } }); }
/* * TODO This should use the decode/crop/encode single step API so that the whole (possibly large) Bitmap doesn't need to be read * into memory */ private void onSaveClicked() { if (cropView == null || isSaving) { return; } isSaving = true; Bitmap croppedImage = null; Rect r = cropView.getScaledCropRect(sampleSize); int width = r.width(); int height = r.height(); int outWidth = width, outHeight = height; if (maxX > 0 && maxY > 0 && (width > maxX || height > maxY)) { float ratio = (float) width / (float) height; if ((float) maxX / (float) maxY > ratio) { outHeight = maxY; outWidth = (int) ((float) maxY * ratio + .5f); } else { outWidth = maxX; outHeight = (int) ((float) maxX / ratio + .5f); } } if (IN_MEMORY_CROP && rotateBitmap != null) { croppedImage = inMemoryCrop(rotateBitmap, croppedImage, r, width, height, outWidth, outHeight); if (croppedImage != null) { imageView.setImageBitmapResetBase(croppedImage, true); imageView.center(true, true); imageView.highlightViews.clear(); } } else { try { croppedImage = decodeRegionCrop(croppedImage, r); if (isCircleCrop) { croppedImage = cropCircleView(croppedImage); } } catch (IllegalArgumentException e) { setResultException(e); finish(); return; } if (croppedImage != null) { imageView.setImageRotateBitmapResetBase(new RotateBitmap(croppedImage, exifRotation), true); imageView.center(true, true); imageView.highlightViews.clear(); } } saveImage(croppedImage); }
private void startCrop() { if (isFinishing()) { return; } imageView.setImageRotateBitmapResetBase(rotateBitmap, true); CropUtil.startBackgroundJob( this, null, getResources().getString(R.string.crop__wait), new Runnable() { public void run() { final CountDownLatch latch = new CountDownLatch(1); handler.post( new Runnable() { public void run() { if (imageView.getScale() == 1F) { imageView.center(true, true); } latch.countDown(); } }); try { latch.await(); } catch (InterruptedException e) { throw new RuntimeException(e); } new Cropper().crop(); } }, handler); }
public void run() { mImageMatrix = mImageView.getImageMatrix(); Bitmap faceBitmap = prepareBitmap(); mScale = 1.0F / mScale; if (faceBitmap != null) { FaceDetector detector = new FaceDetector(faceBitmap.getWidth(), faceBitmap.getHeight(), mFaces.length); mNumFaces = detector.findFaces(faceBitmap, mFaces); } if (faceBitmap != null && faceBitmap != mBitmap) { faceBitmap.recycle(); } mHandler.post( new Runnable() { public void run() { mWaitingToPick = mNumFaces > 1; makeDefault(); mImageView.invalidate(); if (mImageView.mHighlightViews.size() > 0) { mCrop = mImageView.mHighlightViews.get(0); mCrop.setFocus(true); } if (mNumFaces > 1) {} } }); }
// Create a default HightlightView if we found no face in the picture. private void makeDefault() { HighlightView hv = new HighlightView(mImageView, mOutlineColor, mOutlineCircleColor); int width = mBitmap.getWidth(); int height = mBitmap.getHeight(); Rect imageRect = new Rect(0, 0, width, height); // make the default size about 4/5 of the width or height int cropWidth = Math.min(width, height) * 4 / 5; int cropHeight = cropWidth; if (mAspectX != 0 && mAspectY != 0) { if (mAspectX > mAspectY) { cropHeight = cropWidth * mAspectY / mAspectX; } else { cropWidth = cropHeight * mAspectX / mAspectY; } } int x = (width - cropWidth) / 2; int y = (height - cropHeight) / 2; RectF cropRect = new RectF(x, y, x + cropWidth, y + cropHeight); hv.setup(mImageMatrix, imageRect, cropRect, mCircleCrop, mAspectX != 0 && mAspectY != 0); mImageView.add(hv); }
private void clearImageView() { imageView.clear(); if (rotateBitmap != null) { rotateBitmap.recycle(); } System.gc(); }
private void makeDefault() { HighlightView hv = new HighlightView(mImageView); int width = 0; int height = 0; if (mBitmap != null) { width = mBitmap.getWidth(); height = mBitmap.getHeight(); } Rect imageRect = new Rect(0, 0, width, height); // make the default size about 4/5 of the width or height int cropWidth = Math.min(width, height) * 4 / 5; int cropHeight = cropWidth; if (mAspectX != 0 && mAspectY != 0) { if (mAspectX > mAspectY) { cropHeight = cropWidth * mAspectY / mAspectX; } else { cropWidth = cropHeight * mAspectX / mAspectY; } } int x = (width - cropWidth) / 2; int y = (height - cropHeight) / 2; RectF cropRect = new RectF(x, y, x + cropWidth, y + cropHeight); hv.setup(null, imageRect, cropRect, mCircleCrop, mAspectX != 0 && mAspectY != 0); mImageView.add(hv); hv.setResizeDrawable(mResizeDrawableWidth, mResizeDrawableHeight, mResizeDrawableDiagonal); }
/** * Instantiates a new crop image. * * @param context the context * @param imageView the image view * @param handler the handler */ public CropImage(Context context, CropImageView imageView, Handler handler) { mContext = context; mImageView = imageView; mImageView.setCropImage(this); mHandler = handler; // 初始化图片保存路径 FILE_LOCAL = new File(AbFileUtil.getImageDownloadDir(context)); if (!FILE_LOCAL.exists()) { FILE_LOCAL.mkdirs(); } }
@Override protected void onDestroy() { super.onDestroy(); if (null != mImageView) { mImageView.clear(); } if (null != mBitmap) { if (!mBitmap.isRecycled()) { mBitmap.recycle(); } mBitmap = null; } }
public void run() { mImageMatrix = mImageView.getImageMatrix(); Bitmap faceBitmap = prepareBitmap(); mScale = 1.0F / mScale; if (faceBitmap != null && mDoFaceDetection) { FaceDetector detector = new FaceDetector(faceBitmap.getWidth(), faceBitmap.getHeight(), mFaces.length); mNumFaces = detector.findFaces(faceBitmap, mFaces); } if (faceBitmap != null && faceBitmap != mBitmap) { faceBitmap.recycle(); } mHandler.post( new Runnable() { public void run() { mWaitingToPick = mNumFaces > 1; if (mNumFaces > 0) { for (int i = 0; i < mNumFaces; i++) { handleFace(mFaces[i]); } } else { makeDefault(); } mImageView.invalidate(); if (mImageView.mHighlightViews.size() == 1) { mCrop = mImageView.mHighlightViews.get(0); mCrop.setFocus(true); } if (mNumFaces > 1) { Toast t = Toast.makeText( CropImageBaseActivity.this, R.string.multiface_crop_help, Toast.LENGTH_SHORT); t.show(); } } }); }
private void startFaceDetection() { if (isFinishing()) { return; } mImageView.setImageBitmapResetBase(mBitmap, true); Util.startBackgroundJob( this, this, null, getResources().getString(R.string.runningFaceDetection), new Runnable() { public void run() { final CountDownLatch latch = new CountDownLatch(1); final Bitmap b = (mImage != null) ? mImage.fullSizeBitmap(IImage.UNCONSTRAINED, 1024 * 1024) : mBitmap; mHandler.post( new Runnable() { public void run() { if (b != mBitmap && b != null) { mImageView.setImageBitmapResetBase(b, true); mBitmap.recycle(); mBitmap = b; } if (mImageView.getScale() == 1F) { mImageView.center(true, true); } latch.countDown(); } }); try { latch.await(); } catch (InterruptedException e) { throw new RuntimeException(e); } mRunFaceDetection.run(); } }, mHandler); }
// Create a default HightlightView if we found no face in the picture. private void makeDefault() { HighlightView hv = new HighlightView(mImageView); int width = mBitmap.getWidth(); int height = mBitmap.getHeight(); Rect imageRect = new Rect(0, 0, width, height); // CR: sentences! // make the default size about 4/5 of the width or height int cropWidth = Math.min(width, height) * 4 / 5; int cropHeight = cropWidth; int x = (width - cropWidth) / 2; int y = (height - cropHeight) / 2; RectF cropRect = new RectF(x, y, x + cropWidth, y + cropHeight); hv.setup(mImageMatrix, imageRect, cropRect, false, true); mImageView.add(hv); }
// For each face, we create a HightlightView for it. private void handleFace(FaceDetector.Face f) { PointF midPoint = new PointF(); int r = ((int) (f.eyesDistance() * mScale)) * 2; f.getMidPoint(midPoint); midPoint.x *= mScale; midPoint.y *= mScale; int midX = (int) midPoint.x; int midY = (int) midPoint.y; HighlightView hv = new HighlightView(mImageView); int width = mBitmap.getWidth(); int height = mBitmap.getHeight(); Rect imageRect = new Rect(0, 0, width, height); RectF faceRect = new RectF(midX, midY, midX, midY); faceRect.inset(-r, -r); if (faceRect.left < 0) { faceRect.inset(-faceRect.left, -faceRect.left); } if (faceRect.top < 0) { faceRect.inset(-faceRect.top, -faceRect.top); } if (faceRect.right > imageRect.right) { faceRect.inset(faceRect.right - imageRect.right, faceRect.right - imageRect.right); } if (faceRect.bottom > imageRect.bottom) { faceRect.inset(faceRect.bottom - imageRect.bottom, faceRect.bottom - imageRect.bottom); } hv.setup(mImageMatrix, imageRect, faceRect, false, true); mImageView.add(hv); }
@Override public void onCreate(Bundle icicle) { super.onCreate(icicle); mContentResolver = getContentResolver(); requestWindowFeature(Window.FEATURE_NO_TITLE); // MenuHelper.showStorageToast(this); Intent intent = getIntent(); Bundle extras = intent.getExtras(); if (extras != null) { // if (extras.getString("circleCrop") != null) { // mCircleCrop = true; // mAspectX = 1; // mAspectY = 1; // } mSaveUri = (Uri) extras.getParcelable(MediaStore.EXTRA_OUTPUT); if (mSaveUri != null) { String outputFormatString = extras.getString("outputFormat"); if (outputFormatString != null) { mOutputFormat = Bitmap.CompressFormat.valueOf(outputFormatString); } } else { mSetWallpaper = extras.getBoolean("setWallpaper"); } mBitmap = (Bitmap) extras.getParcelable("data"); mAspectX = extras.getInt("aspectX"); mAspectY = extras.getInt("aspectY"); mOutputX = extras.getInt("outputX"); mOutputY = extras.getInt("outputY"); mScale = extras.getBoolean("scale", false); mScaleUp = extras.getBoolean("scaleUpIfNeeded", false); // mDoFaceDetection = extras.containsKey("noFaceDetection") // ? !extras.getBoolean("noFaceDetection") // : true; android.content.res.Resources resources = getResources(); int id = extras.getInt("arrowHorizontal", -1); if (id != -1) { mResizeDrawableWidth = resources.getDrawable(id); } id = extras.getInt("arrowVertical", -1); if (id != -1) { mResizeDrawableHeight = resources.getDrawable(id); } // id = extras.getInt("arrowDiagonal", -1); // if(id != -1){ // mResizeDrawableDiagonal = resources.getDrawable(id); // } } if (mBitmap == null) { Uri target = intent.getData(); try { decodeBitmapStreamSafe(target); } catch (OutOfMemoryError e) { OutOfMemoryHandler.handle(); } catch (Throwable e) { e.printStackTrace(); } // TODO // if (mImage != null) { // // Don't read in really large bitmaps. Use the (big) thumbnail // // instead. // // TODO when saving the resulting bitmap use the // // decode/crop/encode api so we don't lose any resolution. // mBitmap = mImage.thumbBitmap(IImage.ROTATE_AS_NEEDED); // } } if (mBitmap == null) { setResult(RESULT_CANCELED); finish(); return; } // Make UI fullscreen. getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.cropimage); mImageView = (CropImageView) findViewById(R.id.image); findViewById(R.id.discard) .setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { setResult(RESULT_CANCELED); finish(); } }); findViewById(R.id.crop) .setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { onSaveClicked(); } }); final Button btn = (Button) findViewById(R.id.no_crop); btn.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { // if (mNeedCrop) // { // mImageView.setImageBitmapResetBase(mBitmap, true); // mImageView.remove(mCrop); // mCrop = null; // // btn.setText(R.string.crop_text); // } // else // { // makeDefault(); // mImageView.requestLayout(); // mCrop = mImageView.mHighlightViews.get(0); // mCrop.setFocus(true); // // btn.setText(R.string.no_crop_text); // } // mNeedCrop = !mNeedCrop; mNeedCrop = false; onSaveClicked(); } }); // startFaceDetection(); mImageView.setImageBitmapResetBase(mBitmap, true); makeDefault(); mCrop = mImageView.mHighlightViews.get(0); mCrop.setFocus(true); }
@Override public void onCreate(Bundle icicle) { super.onCreate(icicle); mContentResolver = getContentResolver(); setContentView(getContentViewId()); mImageView = getCropImageView(); // Work-around for devices incapable of using hardware-accelerated clipPath. // (android.view.GLES20Canvas.clipPath) // // See also: // - https://code.google.com/p/android/issues/detail?id=20474 // - https://github.com/lvillani/android-cropimage/issues/20 // if (Build.VERSION.SDK_INT > 10 && Build.VERSION.SDK_INT < 16) { // >= Gingerbread && < Jelly Bean mImageView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); } Intent intent = getIntent(); Bundle extras = intent.getExtras(); if (extras != null) { if (extras.getBoolean("circleCrop", false)) { mCircleCrop = true; mAspectX = 1; mAspectY = 1; mOutputFormat = Bitmap.CompressFormat.PNG; } mSaveUri = (Uri) extras.getParcelable(MediaStore.EXTRA_OUTPUT); if (mSaveUri != null) { String outputFormatString = extras.getString("outputFormat"); if (outputFormatString != null) { mOutputFormat = Bitmap.CompressFormat.valueOf(outputFormatString); } mOutputQuality = extras.getInt("outputQuality", 100); } else { mSetWallpaper = extras.getBoolean("setWallpaper"); } mBitmap = (Bitmap) extras.getParcelable("data"); mAspectX = extras.getInt("aspectX"); mAspectY = extras.getInt("aspectY"); mOutputX = extras.getInt("outputX"); mOutputY = extras.getInt("outputY"); mOutlineColor = extras.getInt("outlineColor", HighlightView.DEFAULT_OUTLINE_COLOR); mOutlineCircleColor = extras.getInt("outlineCircleColor", HighlightView.DEFAULT_OUTLINE_CIRCLE_COLOR); mScale = extras.getBoolean("scale", true); mScaleUp = extras.getBoolean("scaleUpIfNeeded", true); mDoFaceDetection = extras.containsKey("noFaceDetection") ? !extras.getBoolean("noFaceDetection") : true; } if (mBitmap == null) { Uri target = intent.getData(); mAllImages = ImageManager.makeImageList(mContentResolver, target, ImageManager.SORT_ASCENDING); mImage = mAllImages.getImageForUri(target); if (mImage != null) { // Don't read in really large bitmaps. Use the (big) thumbnail // instead. // TODO when saving the resulting bitmap use the // decode/crop/encode api so we don't lose any resolution. mBitmap = mImage.thumbBitmap(IImage.ROTATE_AS_NEEDED); } } if (mBitmap == null) { finish(); return; } // Make UI fullscreen. getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); Button discardButton = getDiscardButton(); if (discardButton != null) { discardButton.setOnClickListener( new View.OnClickListener() { public void onClick(View v) { setResult(RESULT_CANCELED); finish(); } }); } Button saveButton = getSaveButton(); if (saveButton != null) { saveButton.setOnClickListener( new View.OnClickListener() { public void onClick(View v) { onSaveClicked(); } }); } startFaceDetection(); }
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); } }
/** 取消裁剪. */ public void cropCancel() { mImageView.mHighlightViews.clear(); mImageView.invalidate(); }