Reputation: 13555
Currently I have an upper overlay image over a camera surface view.
I would like to do is only output the part of photo that is overlapped with upper layer. So Far I can merge the two image , that means , the overlap layer is on top of the camera view. But how can I get only the overlay part is in output? Thanks
public void onPictureTaken(byte[] data, Camera camera) {
Bitmap resizedBottom;
Bitmap resizedTop;
BitmapFactory.Options options=new BitmapFactory.Options();
options.inSampleSize = 8;
Bitmap photo=BitmapFactory.decodeByteArray(data, 0, data.length,options);
Matrix matrix = new Matrix();
matrix.postRotate(passDegree);
Bitmap rotatedBitmap = Bitmap.createBitmap(photo, 0, 0,photo.getWidth(), photo.getHeight(), matrix, true);
photo.recycle();
photo = null;
if (h >= w) {
h = w;
} else {
w = h;
}
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
resizedBottom = Bitmap.createScaledBitmap(rotatedBitmap,w,h,false);
resizedTop = Bitmap.createScaledBitmap(topLayer,w,h,false);
} else {
resizedBottom = Bitmap.createScaledBitmap(rotatedBitmap,h,w,false);
resizedTop = Bitmap.createScaledBitmap(topLayer,h,w,false);
}
Canvas c = new Canvas(resizedBottom);
Resources res = getResources();
Drawable drawable1 = new BitmapDrawable(res,resizedBottom);
Drawable drawable2 = new BitmapDrawable(res,resizedTop);
if (res.getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
drawable1.setBounds(0, 0, w, h);
drawable2.setBounds(0, 0, w, h);
} else {
drawable1.setBounds(0, 0, h, w);
drawable2.setBounds(0, 0, h, w);
}
drawable1.draw(c);
drawable2.draw(c);
File sdDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
// Write to SD Card
String fileName = String.format(sdDir+"/%d.jpg", System.currentTimeMillis());
OutputStream os = null;
try {
os = new FileOutputStream(fileName);
resizedBottom.compress(Bitmap.CompressFormat.PNG, 50, os);
} catch(IOException e) {
e.printStackTrace();
}
Log.i("test", "onPictureTaken - jpeg");
resetCam();
}
Upvotes: 2
Views: 1236
Reputation: 13555
Spent an afternoon, at the end there is solution , it turn out easier than I thought:
Just
1.Create a temp bitmap to store render result
2.Set PorterDuff.Mode.DST_IN on top layer(In this mode only the overlap area is drawn)
Example code:
Bitmap result = Bitmap.createBitmap(topLayer.getWidth(), topLayer.getHeight(), Config.ARGB_8888);
Canvas mCanvas = new Canvas(result);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mCanvas.drawBitmap(resizedBottom, 0, 0, null);
mCanvas.drawBitmap(topLayer, 0, 0, paint);
paint.setXfermode(null);
Further reading about PorterDuff Mode: http://www.ibm.com/developerworks/java/library/j-mer0918/
Upvotes: 3