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

简介: Adnroid上的简单图像合成类——PorterDuffXfermode

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


我们可以首先在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);
      }
    }
  }
}
目录
相关文章
|
2月前
|
机器学习/深度学习 人工智能 编解码
MV-Adapter:上交大、北航和 VAST 等联合开源多视图一致图像生成模型,将预训练的文生图扩散模型转为多视图生成器
MV-Adapter是由北京航空航天大学、VAST和上海交通大学联合开发的多视图一致图像生成模型。该模型能够将预训练的文本到图像扩散模型转化为多视图图像生成器,支持生成高分辨率的多视角图像。
303 18
MV-Adapter:上交大、北航和 VAST 等联合开源多视图一致图像生成模型,将预训练的文生图扩散模型转为多视图生成器
|
4月前
|
人工智能 数据可视化 API
语义分割笔记(一):基于PaddleSeg使用Transfomer模型对航空遥感图像分割
这篇博客介绍了如何使用PaddleSeg和Transformer模型SegFormer B3对航空遥感图像进行语义分割,包括项目背景、数据集处理、训练步骤和代码实现。
264 1
语义分割笔记(一):基于PaddleSeg使用Transfomer模型对航空遥感图像分割
|
4月前
|
编解码 人工智能 数据可视化
imagen: 具有深度语言理解的逼真的文本到图像扩散模型
imagen: 具有深度语言理解的逼真的文本到图像扩散模型
76 0
|
5月前
|
人工智能 Serverless
西游再现!Flux 大模型一键生成写实西游人物
快来报名参加西游AI活动,使用函数计算一键部署 Flux 大模型,生成写实西游人物图像赢取精美小风扇!
440 8
|
7月前
|
机器学习/深度学习 数据可视化 TensorFlow
使用Python实现深度学习模型:图像语义分割与对象检测
【7月更文挑战第15天】 使用Python实现深度学习模型:图像语义分割与对象检测
135 2
|
7月前
|
存储 Java 程序员
【c++】继承深度解剖
【c++】继承深度解剖
50 1
|
8月前
|
机器学习/深度学习 监控 算法
傻傻分不清目标检测、语义分割和实例分割,看这篇就够了
傻傻分不清目标检测、语义分割和实例分割,看这篇就够了
540 0
|
9月前
|
存储 传感器 编解码
CVPR 2023 最全分割类论文整理:图像/全景/语义/实例分割等【附PDF+代码】
CVPR 2023 最全分割类论文整理:图像/全景/语义/实例分割等【附PDF+代码】
1247 1
|
机器学习/深度学习 人工智能 自然语言处理
多模态对比语言图像预训练CLIP:打破语言与视觉的界限
多模态对比语言图像预训练CLIP:打破语言与视觉的界限
多模态对比语言图像预训练CLIP:打破语言与视觉的界限
|
机器学习/深度学习 编解码 人工智能
深度学习应用篇-计算机视觉-图像增广1:数据增广、图像混叠、图像剪裁类变化类等详解
深度学习应用篇-计算机视觉-图像增广1:数据增广、图像混叠、图像剪裁类变化类等详解
深度学习应用篇-计算机视觉-图像增广1:数据增广、图像混叠、图像剪裁类变化类等详解