您的位置:首页 > 移动开发 > Android开发

Android 颜色渲染(九) PorterDuff及Xfermode详解

2015-11-25 17:01 567 查看
Android 颜色渲染(九) PorterDuff及Xfermode详解

之前已经讲过了除ComposeShader之外Shader的全部子类, 在讲ComposeShader(组合渲染)之前, 由于构造ComposeShader需要 PorterDuffXfermode或者PorterDuff.Mode作为参数,所以在此先详细地了解下这两个类的作用,这对之后的绘图会有很大的帮助:

在讲具体的使用之前补充一点知识,这就是 ProterDuff的由来:



相信大多数人看到这个ProterDuff单词很奇怪了吧,这肿么个意思呢,然后就用有道啊,金山啊开始翻译,但是翻译软件给出的结果肯定还是 ProterDuff或者"未找到".

这是神马情况呢?因为ProterDuff是两个人名的组合: Tomas Proter和 Tom Duff. 他们是最早在SIGGRAPH上提出图形混合概念的大神级人物.有兴趣的童靴们可以自己查下并深入了解,在此不再做过多描述.

利用ProterBuff.Mode我们可以完成任意2D图像测操作, 比如涂鸦画板应用中的橡皮擦效果,绘制各种自定义的进度,等等很强大的效果,下面请看具体的介绍:

1. Xfermode:



Xfermode有三个子类 :

AvoidXfermode 指定了一个颜色和容差,强制Paint避免在它上面绘图(或者只在它上面绘图)。

PixelXorXfermode 当覆盖已有的颜色时,应用一个简单的像素异或操作。

PorterDuffXfermode 这是一个非常强大的转换模式,使用它,可以使用图像合成的16条Porter-Duff规则的任意一条来控制Paint如何与已有的Canvas图像进行交互。

要应用转换模式,可以使用setXferMode方法,如下所示:

[java] view
plaincopy

AvoidXfermode avoid = new AvoidXfermode(Color.BLUE, 10, AvoidXfermode.Mode. AVOID); borderPen.setXfermode(avoid);

2.PorterDuff:



首先看一下效果图(来自ApiDemos/Graphics/XferModes)



从上面我们可以看到PorterDuff.Mode为枚举类,一共有16个枚举值:

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

取两图层全部区域,交集部分变为透明色

以下是使用的范例源码:

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);
}
}
}

}


转自:http://blog.csdn.net/t12x3456/article/details/10432935
http://www.tuicool.com/articles/6RjE3m
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: