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

举报
ShaderJoy 发表于 2022/01/01 23:51:17 2022/01/01
【摘要】 图像合成,是将两幅退昂放在一起的动作,它使得我们能够同时看到两幅图像的特征。 我们可以首先在Canvas对象上绘制一个位图对象,然后再相同的Canvas对象上绘制第二个位图对象的方式来实现合成。不过这里在绘制第二幅图像的时候,需要在Paint对象上指定一个过渡模式(Xfermode)。 可用作过渡模式的类集合都继承自Xfermode...

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

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

以下是使用的范例源码:


  
  1. public class MainActivity extends Activity implements OnClickListener
  2. {
  3. static final int PICKED_ONE = 0;
  4. static final int PICKED_TWO = 1;
  5. boolean onePicked = false;
  6. boolean twoPicked = false;
  7. ImageView compositeImageView;
  8. Button choosePicture1, choosePicture2;
  9. Bitmap bmp1, bmp2;
  10. Canvas canvas;
  11. Paint paint;
  12. @Override
  13. protected void onCreate(Bundle savedInstanceState)
  14. {
  15. super.onCreate(savedInstanceState);
  16. setContentView(R.layout.activity_main);
  17. compositeImageView = (ImageView) findViewById(R.id.ChosenImageView);
  18. choosePicture1 = (Button) findViewById(R.id.ChoosePictureButton1);
  19. choosePicture2 = (Button) findViewById(R.id.ChoosePictureButton2);
  20. choosePicture1.setOnClickListener(this);
  21. choosePicture2.setOnClickListener(this);
  22. }
  23. @Override
  24. public void onClick(View v)
  25. {
  26. // TODO Auto-generated method stub
  27. int which = -1;
  28. if (v == choosePicture1)
  29. {
  30. which = PICKED_ONE;
  31. } else
  32. {
  33. which = PICKED_TWO;
  34. }
  35. Intent choosePictureIntent = new Intent(Intent.ACTION_PICK,
  36. Media.EXTERNAL_CONTENT_URI);
  37. startActivityForResult(choosePictureIntent, which);
  38. }
  39. private Bitmap loadBitmap(Uri imageFileUri)
  40. {
  41. Display currentDisplay = getWindowManager().getDefaultDisplay();
  42. int dw = currentDisplay.getWidth();
  43. int dh = currentDisplay.getHeight();
  44. Bitmap returnBmp = Bitmap.createBitmap(dw, dh, Config.ARGB_4444);
  45. BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
  46. bmpFactoryOptions.inJustDecodeBounds = true;
  47. try
  48. {
  49. returnBmp = BitmapFactory.decodeStream(getContentResolver()
  50. .openInputStream(imageFileUri), null, bmpFactoryOptions);
  51. } catch (FileNotFoundException e)
  52. {
  53. // TODO Auto-generated catch block
  54. e.printStackTrace();
  55. }
  56. int heightRatio = (int) Math.ceil(bmpFactoryOptions.outHeight
  57. / (float) dh);
  58. int widthRatio = (int) Math.ceil(bmpFactoryOptions.outWidth
  59. / (float) dw);
  60. if (heightRatio > 1 && widthRatio > 1)
  61. {
  62. if (heightRatio > widthRatio)
  63. {
  64. bmpFactoryOptions.inSampleSize = heightRatio;
  65. } else
  66. {
  67. bmpFactoryOptions.inSampleSize = widthRatio;
  68. }
  69. }
  70. bmpFactoryOptions.inJustDecodeBounds = false;
  71. try
  72. {
  73. returnBmp = BitmapFactory.decodeStream(getContentResolver()
  74. .openInputStream(imageFileUri), null, bmpFactoryOptions);
  75. } catch (FileNotFoundException e)
  76. {
  77. // TODO Auto-generated catch block
  78. e.printStackTrace();
  79. }
  80. return returnBmp;
  81. }
  82. @Override
  83. protected void onActivityResult(int requestCode, int resultCode, Intent data)
  84. {
  85. // TODO Auto-generated method stub
  86. super.onActivityResult(requestCode, resultCode, data);
  87. if (resultCode == RESULT_OK)
  88. {
  89. Uri imageFileUri = data.getData();
  90. if (requestCode == PICKED_ONE)
  91. {
  92. bmp1 = loadBitmap(imageFileUri);
  93. onePicked = true;
  94. } else
  95. {
  96. bmp2 = loadBitmap(imageFileUri);
  97. twoPicked = true;
  98. }
  99. if (onePicked && twoPicked)
  100. {
  101. Bitmap drawingBitmap = Bitmap.createBitmap(bmp1.getWidth(),
  102. bmp1.getHeight(), bmp1.getConfig());
  103. canvas = new Canvas(drawingBitmap);
  104. paint = new Paint();
  105. canvas.drawBitmap(bmp1, 0, 0, paint);
  106. paint.setXfermode(new PorterDuffXfermode(
  107. android.graphics.PorterDuff.Mode.DARKEN));
  108. canvas.drawBitmap(bmp2, 0, 0, paint);
  109. compositeImageView.setImageBitmap(drawingBitmap);
  110. }
  111. }
  112. }
  113. }



文章来源: panda1234lee.blog.csdn.net,作者:panda1234lee,版权归原作者所有,如需转载,请联系作者。

原文链接:panda1234lee.blog.csdn.net/article/details/8722386

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。