Android上的简单图像合成类——PorterDuffXfermode

来源:互联网 发布:青岛淘宝运营 编辑:程序博客网 时间:2024/06/16 16:44

图像合成,是将两幅图片放在一起的动作,它使得我们能够同时看到两幅图像的特征。

我们可以首先在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)  {    // TODO Auto-generated method stub    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)    {      // TODO Auto-generated catch block      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)    {      // TODO Auto-generated catch block      e.printStackTrace();    }    return returnBmp;  }  @Override  protected void onActivityResult(int requestCode, int resultCode, Intent data)  {    // TODO Auto-generated method stub    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);      }    }  }}
0 0
原创粉丝点击