原:http://blog.csdn.net/panda1234lee/article/details/8722386?utm_source=tuicool
图像合成,是将两幅退昂放在一起的动作,它使得我们能够同时看到两幅图像的特征。
我们可以首先在Canvas对象上绘制一个位图对象,然后再相同的Canvas对象上绘制第二个位图对象的方式来实现合成。不过这里在绘制第二幅图像的时候,需要在Paint对象上指定一个过渡模式(Xfermode)。
可用作过渡模式的类集合都继承自Xfermode基类,而其中包括一个成为PorterDuffXfermode的类。PorterDuffXfermode因Thomas Porter和Tom Duff而得名,他们于1984年在ACM SIGGRAPH计算机图形学出版物上发表了题为“Compositing digital images”(合成数字图像)的文章,详细介绍了一系列不同的规则,用于彼此重叠的绘制图像。
在Android的PorterDuff.Mode类中列举了他们制定的规则:
android.graphics.PorterDuff.Mode.SRC:只绘制源图像
android.graphics.PorterDuff.Mode.DST:只绘制目标图像
android.graphics.PorterDuff.Mode.DST_OVER:在源图像的顶部绘制目标图像
android.graphics.PorterDuff.Mode.DST_IN:只在源图像和目标图像相交的地方绘制目标图像
android.graphics.PorterDuff.Mode.DST_OUT:只在源图像和目标图像不相交的地方绘制目标图像
android.graphics.PorterDuff.Mode.DST_ATOP:在源图像和目标图像相交的地方绘制目标图像,在不相交的地方绘制源图像
android.graphics.PorterDuff.Mode.SRC_OVER:在目标图像的顶部绘制源图像
android.graphics.PorterDuff.Mode.SRC_IN:只在源图像和目标图像相交的地方绘制源图像
android.graphics.PorterDuff.Mode.SRC_OUT:只在源图像和目标图像不相交的地方绘制源图像
android.graphics.PorterDuff.Mode.SRC_ATOP:在源图像和目标图像相交的地方绘制源图像,在不相交的地方绘制目标图像
android.graphics.PorterDuff.Mode.XOR:在源图像和目标图像重叠之外的任何地方绘制他们,而在不重叠的地方不绘制任何内容
android.graphics.PorterDuff.Mode.LIGHTEN:获得每个位置上两幅图像中最亮的像素并显示
android.graphics.PorterDuff.Mode.DARKEN:获得每个位置上两幅图像中最暗的像素并显示
android.graphics.PorterDuff.Mode.MULTIPLY:将每个位置的两个像素相乘,除以255,然后使用该值创建一个新的像素进行显示。结果颜色=顶部颜色*底部颜色/255
android.graphics.PorterDuff.Mode.SCREEN:反转每个颜色,执行相同的操作(将他们相乘并除以255),然后再次反转。结果颜色=255-(((255-顶部颜色)*(255-底部颜色))/255)
以下是使用的范例源码:
- public class MainActivity extends Activity implements OnClickListener
- {
- static final int PICKED_ONE = 0;
- static final int PICKED_TWO = 1;
- boolean onePicked = false;
- boolean twoPicked = false;
- ImageView compositeImageView;
- Button choosePicture1, choosePicture2;
- Bitmap bmp1, bmp2;
- Canvas canvas;
- Paint paint;
-
- @Override
- protected void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- compositeImageView = (ImageView) findViewById(R.id.ChosenImageView);
- choosePicture1 = (Button) findViewById(R.id.ChoosePictureButton1);
- choosePicture2 = (Button) findViewById(R.id.ChoosePictureButton2);
- choosePicture1.setOnClickListener(this);
- choosePicture2.setOnClickListener(this);
- }
-
- @Override
- public void onClick(View v)
- {
-
- int which = -1;
- if (v == choosePicture1)
- {
- which = PICKED_ONE;
- } else
- {
- which = PICKED_TWO;
- }
- Intent choosePictureIntent = new Intent(Intent.ACTION_PICK,
- Media.EXTERNAL_CONTENT_URI);
- startActivityForResult(choosePictureIntent, which);
- }
-
- private Bitmap loadBitmap(Uri imageFileUri)
- {
- Display currentDisplay = getWindowManager().getDefaultDisplay();
- int dw = currentDisplay.getWidth();
- int dh = currentDisplay.getHeight();
- Bitmap returnBmp = Bitmap.createBitmap(dw, dh, Config.ARGB_4444);
-
- BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
- bmpFactoryOptions.inJustDecodeBounds = true;
- try
- {
- returnBmp = BitmapFactory.decodeStream(getContentResolver()
- .openInputStream(imageFileUri), null, bmpFactoryOptions);
- } catch (FileNotFoundException e)
- {
-
- e.printStackTrace();
- }
-
- int heightRatio = (int) Math.ceil(bmpFactoryOptions.outHeight
- / (float) dh);
- int widthRatio = (int) Math.ceil(bmpFactoryOptions.outWidth
- / (float) dw);
- if (heightRatio > 1 && widthRatio > 1)
- {
- if (heightRatio > widthRatio)
- {
- bmpFactoryOptions.inSampleSize = heightRatio;
- } else
- {
- bmpFactoryOptions.inSampleSize = widthRatio;
- }
- }
- bmpFactoryOptions.inJustDecodeBounds = false;
- try
- {
- returnBmp = BitmapFactory.decodeStream(getContentResolver()
- .openInputStream(imageFileUri), null, bmpFactoryOptions);
- } catch (FileNotFoundException e)
- {
-
- e.printStackTrace();
- }
- return returnBmp;
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data)
- {
-
- super.onActivityResult(requestCode, resultCode, data);
- if (resultCode == RESULT_OK)
- {
- Uri imageFileUri = data.getData();
-
- if (requestCode == PICKED_ONE)
- {
- bmp1 = loadBitmap(imageFileUri);
- onePicked = true;
- } else
- {
- bmp2 = loadBitmap(imageFileUri);
- twoPicked = true;
- }
-
- if (onePicked && twoPicked)
- {
- Bitmap drawingBitmap = Bitmap.createBitmap(bmp1.getWidth(),
- bmp1.getHeight(), bmp1.getConfig());
- canvas = new Canvas(drawingBitmap);
- paint = new Paint();
- canvas.drawBitmap(bmp1, 0, 0, paint);
- paint.setXfermode(new PorterDuffXfermode(
- android.graphics.PorterDuff.Mode.DARKEN));
- canvas.drawBitmap(bmp2, 0, 0, paint);
- compositeImageView.setImageBitmap(drawingBitmap);
- }
- }
- }
-
- }