我们可以通过paint.setXfermode对合并的图片做相关处理,如取2张bitmap非交集部分可以这么做:
Bitmap newbmp = Bitmap
.createBitmap(foreground.getWidth(), foreground.getHeight(), Config.RGB_565);
Canvas bgCanvas = new Canvas(newbmp);
bgCanvas.drawBitmap(foreground, 0, 0, null);
// 接下来我们在上面画一个实心圆
Paint p = new Paint();
p.setStrokeWidth(1);
p.setStyle(Paint.Style.FILL);
p.setColor(Color.BLACK);
//取非交集部分
p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.XOR));
int radius = (forePosition.right - forePosition.left) / 2;
bgCanvas.drawCircle(radius, radius, radius-30, p);
bgCanvas.save();
bgCanvas.restore();
这样我们得到的newbmp就是2张图片的非交集部分,但是我发现他们非交集部分都被黑色所填充了,而不是我想象的空白或者透明,经过仔细研究才发现是Config.RGB_565搞的鬼,下面我们来补习下相关知识:
我们操作bitmap时都会遇到内存问题,基本的做法就是缩小其size,其实除了size之外还有一个影响图片占用空间的还有图片的色彩信息,看下如下方法:
createBitmap(intwidth, int height, Bitmap.Config config),
这个config就是Android.graphics.Bitmap里的一个内部类Bitmap.Config,
有如下变量:
枚举变量
public static final Bitmap.Config ALPHA_8
public static final Bitmap.Config ARGB_4444
public static final Bitmap.Config ARGB_8888
public static final Bitmap.Config RGB_565
我们知道ARGB指的是一种色彩模式,其中A代表alpha,R代表red,G代码green,B代码blue,其实所有可见色都是由红、绿、蓝组成,他们有称为3原色,每个原色都储存着表示颜色的信息值。
ALPHA_8就是Alpha由8位组成
ARGB_4444就是由4个4位组成即16位,
ARGB_8888就是由4个8位组成即32位,
RGB_565就是R为5位,G为6位,B为5位共16位
由此可见:
ALPHA_8 代表8位Alpha位图
ARGB_4444 代表16位ARGB位图
ARGB_8888 代表32位ARGB位图
RGB_565 代表8位RGB位图
位图位数越高代表其可以存储的颜色信息越多,当然图像也就越逼真,所占内存也会越大,所以有时候我们在不需要太清晰的图片时也可以在这方面做改变。
好了,回到之前的问题上面来,我们设置了RGB_565,这个是没有A(即透明度),所以没有图像的地方肯定就是黑色填充了,那么我们需要将其改为ARGB_8888即可。
网上有很多关于setXfermode的介绍,找了一个来记录下相关的知识:
1.PorterDuff.Mode.CLEAR
所绘制不会提交到画布上。
2.PorterDuff.Mode.SRC
显示上层绘制图片
3.PorterDuff.Mode.DST
显示下层绘制图片
4.PorterDuff.Mode.SRC_OVER
正常绘制显示,上下层绘制叠盖。
5.PorterDuff.Mode.DST_OVER
上下层都显示。下层居上显示。
6.PorterDuff.Mode.SRC_IN
取两层绘制交集。显示上层。
7.PorterDuff.Mode.DST_IN
取两层绘制交集。显示下层。
8.PorterDuff.Mode.SRC_OUT
取上层绘制非交集部分。
9.PorterDuff.Mode.DST_OUT
取下层绘制非交集部分。
10.PorterDuff.Mode.SRC_ATOP
取下层非交集部分与上层交集部分
11.PorterDuff.Mode.DST_ATOP
取上层非交集部分与下层交集部分
12.PorterDuff.Mode.XOR
异或:去除两图层交集部分
13.PorterDuff.Mode.DARKEN
取两图层全部区域,交集部分颜色加深
14.PorterDuff.Mode.LIGHTEN
取两图层全部,点亮交集部分颜色
15.PorterDuff.Mode.MULTIPLY
取两图层交集部分叠加后颜色
16.PorterDuff.Mode.SCREEN
取两图层全部区域,交集部分变为透明色
注:上面的效果图是指des和src是在完全重合的情况下的效果,其实合并的一个原则就是变化的区域只有src区域(脏区域),des区域是不会改变的,这点切记,很多开发者都只是参考上面的事例图,并没有真正的理解。