相干图片处理的一些片段-Xfermode属性

http://www.myexception.cn/mobile/917390.html

1、PorterDuffXfermode
PorterDuff.Mode的十六种情况可以看APIDemos中的效果,唯一记录一下,做测试时候迷茫的地方

private  void drawIntoBitmap(Bitmap bm) {
        Canvas canvas = new Canvas(bm);
        Paint paint = new Paint();
        InputStream stream = null;
    try {
    stream = mContext.getAssets().open("icon.jpg");
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    Bitmap bitmap = BitmapFactory.decodeStream(stream);
    bitmap = RoundActivity.getRoundCornerBitmap(bitmap);//只是获取一个圆角的图片
    stream = getResources().openRawResource(R.drawable.ic_launcher);
    Bitmap src = BitmapFactory.decodeStream(stream);
   
   
    canvas.drawBitmap(bitmap, 100, 100, paint);
    canvas.drawBitmap(bitmap, 0, 0, paint);
    //SRC_OVER与SRC模式相比,主要区别SRC_OVER是会有透明度影响。而DST的话,则是src区域不显示,不像SRC模式,只是src区域所占的地方,det区对应地方被覆盖
//Over 类型的MODE只有Config为ARGB,以及Alph8类型的位图才会有效果
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_OVER));
//只有src占用的区间才会用到Xfermode模式进行运算,而不是整个Canvas区域生效。当然可以指定dst区域.或着如下边注释行的方法,设置了dirst区域。
// canvas.drawBitmap(src,new Rect(0, 0, src.getWidth(), src.getHeight()),new Rect(0, 0, 200 , 200),paint);
canvas.drawBitmap(src, 0, 0,paint);
paint.setARGB(0x80, 0x0, 0xff, 0x0);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER));
paint.setTextSize(60)
;// paint.setShader(mShader);
paint.setTextAlign(Paint.Align.CENTER);//如果是这个属性,则drawtext中的x,y坐标指的是文字所占区域的中心
Paint.FontMetrics fm = paint.getFontMetrics();
//如果是文字的话,XFermode设置后,只有文字的轨迹占用的地方才会生效
canvas.drawText("text", bm.getWidth()/2, (bm.getWidth()-fm.ascent)/2, paint);

}


如图



2、AvoidXfermode

private void drawInBitmapAvoid(Bitmap bm) {
Canvas canvas = new Canvas(bm);
Paint paint = new Paint();
canvas.drawBitmap(mBitmap, new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight()), new Rect(0, 0, bm.getWidth(), bm.getHeight()), paint);
paint.setARGB(0xff, 0xff, 0x00, 0x00);
//Mode.AVOID 模式下是给op-color不一样的地方才绘制
// 如果tolerance 即误差为0,或者说完全不一样,才会绘制
// 如果tolerance 即误差为255,或者说稍微不一样,就可以绘制
//这边有点拗口,看另外一个模式就明白了
paint.setXfermode(new AvoidXfermode(0xff505050, 0, AvoidXfermode.Mode.AVOID));;
canvas.drawCircle(0, 0, bm.getWidth()/2, paint);
paint.setXfermode(new AvoidXfermode(0xff505050, 255, AvoidXfermode.Mode.AVOID));;
canvas.drawCircle(bm.getWidth(), 0, bm.getWidth()/2, paint);
// 如果是Mode.TARGET模式,只给与op-color一样的像素点上绘制
//如果tolerance为0,即完全一样,才会给这个像素点绘制
//如果tolerance为255,即稍微一样一点,就会给这个像素点绘制
paint.setXfermode(new AvoidXfermode(0xff505050, 0, AvoidXfermode.Mode.TARGET));;
canvas.drawCircle(0, bm.getHeight(), bm.getWidth()/2, paint);
paint.setXfermode(new AvoidXfermode(0xff505050, 255, AvoidXfermode.Mode.TARGET));;
canvas.drawCircle(bm.getWidth(), bm.getHeight(), bm.getWidth()/2, paint);
}


如图



3、PixelXorXfermode


文档中说PixelXorXfermode implements a simple pixel xor (op ^ src ^ dst).  我自认为模块一和模块二效果会一样,但是实验结果不同。

这个类,我完全被他打败了。测试了一下午也没测出规律和原因来,如果有懂的,望不吝赐教
而且经常不同的是R值和B值互换,有时候又正常。真不知道哪里错了

        private void drawInBitmapPixel(Bitmap bm) {
Canvas canvas = new Canvas(bm);
Paint paint = new Paint();
int dst = 0xff00ffff;
paint.setColor(dst);
Rect rect = new Rect(0, 0, bm.getWidth(), bm.getHeight()/2-8);
canvas.drawRect(rect, paint);
int src = 0xffffff00;
int opr = 0xffff0000;

//模块一
paint.setXfermode(new PixelXorXfermode(opr));
paint.setColor(src);
canvas.drawRect(rect, paint);
//模块二
paint.setXfermode(null);
int result = opr^src^dst;
/*//R和B 互换  0x ff ff ff ff
// 取B值
int b = result&0x000000ff;
//取R值
int r = result&0x00ff0000;
//移动到对应位置
b = b<<16;
r = r>>16;
//过滤RB值
result = result&0xff00ff00;
//放入RB值
result |= r;
result |= b;*/
paint.setColor(result);
rect = new Rect(0,bm.getHeight()/2+8,bm.getWidth(),bm.getHeight());
canvas.drawRect(rect, paint);

paint.setXfermode(null);
paint.setTextSize(15);
paint.setTextAlign(Align.CENTER);
canvas.drawText("^color="+Integer.toHexString(paint.getColor()), bm.getWidth()/2, (bm.getHeight()-paint.getFontMetrics().ascent)/2, paint);
}

猜你喜欢

转载自abc20899.iteye.com/blog/1768650