Android 顏色渲染(九) PorterDuff及Xfermode詳解
Android 顏色渲染(九) PorterDuff及Xfermode詳解
之前已經講過了除ComposeShader之外Shader的全部子類, 在講ComposeShader(組合渲染)之前, 由於構造ComposeShader需要 PorterDuffXfermode或者PorterDuff.Mode作為引數,所以在此先詳細地瞭解下這兩個類的作用,這對之後的繪圖會有很大的幫助:
在講具體的使用之前補充一點知識,這就是 ProterDuff的由來:
相信大多數人看到這個ProterDuff單詞很奇怪了吧,這腫麼個意思呢,然後就用有道啊,金山啊開始翻譯,但是翻譯軟體給出的結果肯定還是 ProterDuff或者"未找到".
利用ProterBuff.Mode我們可以完成任意2D影象測操作, 比如塗鴉畫板應用中的橡皮擦效果,繪製各種自定義的進度,等等很強大的效果,下面請看具體的介紹:
1. Xfermode:
Xfermode有三個子類 :
AvoidXfermode 指定了一個顏色和容差,強制Paint避免在它上面繪圖(或者只在它上面繪圖)。
PixelXorXfermode 當覆蓋已有的顏色時,應用一個簡單的畫素異或操作。
PorterDuffXfermode 這是一個非常強大的轉換模式,使用它,可以使用影象合成的16條Porter-Duff規則的任意一條來控制Paint如何與已有的Canvas影象進行互動。
要應用轉換模式,可以使用setXferMode方法,如下所示:
- 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
相關文章
- YUV顏色詳解
- Android TextView 預渲染詳解AndroidTextView
- android顏色對應的xml配置值,顏色表AndroidXML
- 修改Android 介面顏色Android
- iOS 修改狀態列StatusBar的顏色及文字顏色iOS
- Android ListView(Selector 顏色)AndroidView
- 一文詳解 OpenGL ES 紋理顏色混合
- javascriptRGB顏色轉換到16進位制詳解JavaScript
- 直播軟體搭建,修改狀態列、導航條顏色及文字顏色
- 短視訊系統,android Switch修改顏色修改樣式滑塊顏色Android
- Android 顏色漸變 屬性動畫Android動畫
- Android 圓形ProgressBar 改變顏色Android
- Android 顏色透明度換算Android
- android更改EditText下劃線顏色Android
- css顏色屬性詳細總結CSS
- EasyPR--開發詳解(5)顏色定位與偏斜扭轉
- [SVG]修改固定顏色為填充顏色SVG
- 字型渲染詳解
- HTML 顏色色號HTML
- 九. Vuex詳解Vue
- Android中自定義特定顏色的ToastAndroidAST
- Android 使用ColorMatrix改變圖片顏色AndroidColorMatrix
- css顏色CSS
- HTML 顏色HTML
- 設定toast的字型顏色和背景顏色AST
- Android 開發者和設計師必須瞭解的顏色知識Android
- Android通過程式碼修改圖片顏色Android
- Android 濾鏡效果和顏色通道過濾Android
- Android自定義邊框背景顏色的ToastAndroidAST
- Android系統更改狀態列字型顏色Android
- 殘缺棋盤 android實現顏色填充Android
- android顏色值的表示方法android:background="#FFFFFFFF"的意思Android
- 自定義Toast的背景顏色大小及字型大小AST
- Pypycharm修改程式碼字型大小及修改顏色PyCharm
- 美顏SDK詳解,您瞭解美顏SDK嗎?
- 顏色轉換
- CSS顏色表示CSS
- HSV顏色模型模型