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); }
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); } }