PorterDuffXfermode图片重叠过渡模式

转载 2015年11月20日 10:43:36

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

我们可以首先在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);
      }
    }
  }

}

相关文章推荐

【Android】PorterDuffXfermode使用(通过消除背景层与重叠部分绘制组合图形)

利用PorterDuffXfermode,绘制组合图形,过程我分成了4个步骤(onDraw方法里面):      1、通过canvas.saveLayout()先绘制一个背景图层(这里位置大小很重要,...

关于android中图片裁剪以及PorterDuffXfermode的使用经验小结

关于图片”裁剪”出现锯齿的问题,以及PorterDuffXfermode实现方式原理小结

PorterDuffXfermode无法合成图片

PorterDuffXfermode无法合成

PorterDuffXfermode实例,将自定义View变为图片

在原有的canvas上建立一个bitmap的图片背景。 在另一个bitmap上新建一个 canvas: canvasbit在 canvasbit上首先画一个蒙版,再画一个path,开始时的p...

使用PorterDuffXferMode实现自定义的圆角图片

最近研究了下PorterDuffXferMode,也就是图像混合模式。学习了爱哥的自定义View篇的这篇文章: 自定义控件其实很简单1/6。主要学习了关于PorterDuffXfermode的这个部...
  • ljngya
  • ljngya
  • 2016年10月17日 17:56
  • 283

Android学习研究(四)通过PorterDuffXfermode形成简单的圆角和圆形图片

我们之前学习了PorterDuffXfermode了,现在我们来用它做一下简单的圆角和圆形图片 首先自定义属性: ...

Android 理解PorterDuffXfermode叠加模式

关于PorterDuffXfermode的讲解在网上有很多相关的教程,以下只是针对我自己在使用过程中遇到的问题做补充说明: 以上所有格子应该看做一张图片(包括图片的大小) src需要是一...
  • fz_dev
  • fz_dev
  • 2016年05月24日 13:24
  • 719

PNG图片重叠父窗口残留刷新问题

  • 2014年12月26日 09:09
  • 1.03MB
  • 下载

简单的js 图片轮换相册,有过渡渐变效果。兼容IE,ff

#cnt{width:100%;height:80%;} .ctrl{text-align:center;border:1px solid gray;font-size:12px;cursor:poi...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:PorterDuffXfermode图片重叠过渡模式
举报原因:
原因补充:

(最多只允许输入30个字)