線帽
Paint.setStrokeCap(Paint.Cap.BUTT); 無線帽
Paint.setStrokeCap(Paint.Cap.ROUND); 圓形線帽
Paint.setStrokeCap(Paint.Cap.SQUARE);方形線帽
f18e0eb1379575428eefcd82d1216005.png
拐角風(fēng)格
Paint.setStrokeJoin(Paint.Join.MITER); 默認(rèn)
Paint.setStrokeJoin(Paint.Join.ROUND); 圓角
Paint.setStrokeJoin(Paint.Join.BEVEL); 斜角
ac20ae1c998fdb48a887833251739183.png
渲染器
線性渲染
/**
* 1.線性渲染,LinearGradient(float x0, float y0, float x1, float y1, @NonNull @ColorInt int colors[], @Nullable float positions[], @NonNull TileMode tile)
* (x0,y0):漸變起始點(diǎn)坐標(biāo)
* (x1,y1):漸變結(jié)束點(diǎn)坐標(biāo)
* color0:漸變開始點(diǎn)顏色,16進(jìn)制的顏色表示鹅巍,必須要帶有透明度
* color1:漸變結(jié)束顏色
* colors:漸變數(shù)組
* positions:位置數(shù)組,position的取值范圍[0,1],作用是指定某個(gè)位置的顏色值,如果傳null,漸變就線性變化。
* tile:用于指定控件區(qū)域大于指定的漸變區(qū)域時(shí),空白區(qū)域的顏色填充方法
*/
mShader = new LinearGradient(0, 0, 200, 200, new int[]{Color.RED, Color.BLUE, Color.GREEN}, new float[]{0.f,0.7f,1}, Shader.TileMode.REPEAT);
mPaint.setShader(mShader);
canvas.drawRect(0,100,400,450, mPaint);
環(huán)形渲染
/**
* 環(huán)形渲染,RadialGradient(float centerX, float centerY, float radius, @ColorInt int colors[], @Nullable float stops[], TileMode tileMode)
* centerX ,centerY:shader的中心坐標(biāo)墓陈,開始漸變的坐標(biāo)
* radius:漸變的半徑
* centerColor,edgeColor:中心點(diǎn)漸變顏色,邊界的漸變顏色
* colors:漸變顏色數(shù)組
* stoops:漸變位置數(shù)組第献,類似掃描漸變的positions數(shù)組贡必,取值[0,1],中心點(diǎn)為0,半徑到達(dá)位置為1.0f
* tileMode:shader未覆蓋以外的填充模式庸毫。
*/
mShader = new RadialGradient(650, 250, 150, new int[]{Color.GREEN, Color.YELLOW, Color.RED}, null, Shader.TileMode.CLAMP);
mPaint.setShader(mShader);
canvas.drawCircle(650, 250, 150, mPaint);
掃描渲染
/**
* 掃描渲染赊级,SweepGradient(float cx, float cy, @ColorInt int color0,int color1)
* cx,cy 漸變中心坐標(biāo)
* color0,color1:漸變開始結(jié)束顏色
* colors,positions:類似LinearGradient,用于多顏色漸變,positions為null時(shí)岔绸,根據(jù)顏色線性漸變
*/
mShader = new SweepGradient(1050, 250, Color.RED, Color.GREEN);
mPaint.setShader(mShader);
canvas.drawCircle(1050, 250, 150, mPaint);
位圖渲染
/**
* 位圖渲染,BitmapShader(@NonNull Bitmap bitmap, @NonNull TileMode tileX, @NonNull TileMode tileY)
* Bitmap:構(gòu)造shader使用的bitmap
* tileX:X軸方向的TileMode
* tileY:Y軸方向的TileMode
REPEAT, 繪制區(qū)域超過渲染區(qū)域的部分橡伞,重復(fù)排版
CLAMP盒揉, 繪制區(qū)域超過渲染區(qū)域的部分,會(huì)以最后一個(gè)像素拉伸排版
MIRROR, 繪制區(qū)域超過渲染區(qū)域的部分兑徘,鏡像翻轉(zhuǎn)排版
*/
mShader = new BitmapShader(mBitmap, Shader.TileMode.REPEAT, Shader.TileMode.MIRROR);
mPaint.setShader(mShader);
canvas.drawRect(0,600,300, 800, mPaint);
組合渲染
/**
* 組合渲染刚盈,
* ComposeShader(@NonNull Shader shaderA, @NonNull Shader shaderB, Xfermode mode)
* ComposeShader(@NonNull Shader shaderA, @NonNull Shader shaderB, PorterDuff.Mode mode)
* shaderA,shaderB:要混合的兩種shader
* Xfermode mode: 組合兩種shader顏色的模式
* PorterDuff.Mode mode: 組合兩種shader顏色的模式
*/
BitmapShader bitmapShader = new BitmapShader(mBitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
LinearGradient linearGradient = new LinearGradient(400, 600, 900, 1100, new int[]{Color.RED, Color.GREEN, Color.BLUE}, null, Shader.TileMode.CLAMP);
mShader = new ComposeShader(bitmapShader, linearGradient, PorterDuff.Mode.MULTIPLY);
mPaint.setShader(mShader);
canvas.drawCircle(650, 850, 250, mPaint);
3911af3a313cbb49949fd720a935cae8.png
圖層混合模式
// draw the border
paint.setStyle(Paint.Style.STROKE);
paint.setShader(null);
canvas.drawRect(x - 0.5f, y - 0.5f, x + W + 0.5f, y + H + 0.5f, paint);
// draw the checker-board pattern
paint.setStyle(Paint.Style.FILL);
paint.setShader(mBG);
canvas.drawRect(x, y, x + W, y + H, paint);
// 使用離屏繪制
int sc = canvas.saveLayer(x, y, x + W, y + H, null);
canvas.translate(x, y);
canvas.drawBitmap(makeDst(2 * W / 3, 2 * H / 3), 0, 0, paint);
paint.setXfermode(Xfermode.sModes[i]);
canvas.drawBitmap(makeSrc(2 * W / 3, 2 * H / 3), W / 3, H / 3, paint);
paint.setXfermode(null);
canvas.restoreToCount(sc);
//其中Sa全稱為Source alpha表示源圖的Alpha通道;Sc全稱為Source color表示源圖的顏色挂脑;Da全稱為Destination alpha表示目標(biāo)圖的Alpha通道藕漱;Dc全稱為Destination color表示目標(biāo)圖的顏色欲侮,[...,..]前半部分計(jì)算的是結(jié)果圖像的Alpha通道值,“,”后半部分計(jì)算的是結(jié)果圖像的顏色值肋联。
//效果作用于src源圖像區(qū)域
public static final PorterDuffXfermode[] sModes = {
//所繪制不會(huì)提交到畫布上
new PorterDuffXfermode(PorterDuff.Mode.CLEAR),
//顯示上層繪制的圖像
new PorterDuffXfermode(PorterDuff.Mode.SRC),
//顯示下層繪制圖像
new PorterDuffXfermode(PorterDuff.Mode.DST),
//正常繪制顯示,上下層繪制疊蓋
new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER),
//上下層都顯示,下層居上顯示
new PorterDuffXfermode(PorterDuff.Mode.DST_OVER),
//取兩層繪制交集项秉,顯示上層
new PorterDuffXfermode(PorterDuff.Mode.SRC_IN),
//取兩層繪制交集稚机,顯示下層
new PorterDuffXfermode(PorterDuff.Mode.DST_IN),
//取上層繪制非交集部分,交集部分變成透明
new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT),
//取下層繪制非交集部分侮繁,交集部分變成透明
new PorterDuffXfermode(PorterDuff.Mode.DST_OUT),
//取上層交集部分與下層非交集部分
new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP),
//取下層交集部分與上層非交集部分
new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP),
//去除兩圖層交集部分
new PorterDuffXfermode(PorterDuff.Mode.XOR),
//取兩圖層全部區(qū)域虑粥,交集部分顏色加深
new PorterDuffXfermode(PorterDuff.Mode.DARKEN),
//取兩圖層全部區(qū)域,交集部分顏色點(diǎn)亮
new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN),
//取兩圖層交集部分宪哩,顏色疊加
new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY),
//取兩圖層全部區(qū)域娩贷,交集部分濾色
new PorterDuffXfermode(PorterDuff.Mode.SCREEN),
//取兩圖層全部區(qū)域,交集部分飽和度相加
new PorterDuffXfermode(PorterDuff.Mode.ADD),
//取兩圖層全部區(qū)域锁孟,交集部分疊加
new PorterDuffXfermode(PorterDuff.Mode.OVERLAY)
};
e42db77c81b9b0438365428a3237b19b.png
顏色過濾器
LightingColorFilter
/**
* R' = R * mul.R / 0xff + add.R
* G' = G * mul.G / 0xff + add.G
* B' = B * mul.B / 0xff + add.B
*/
int sc;
//原始圖片效果
sc = canvas.saveLayer(0, 0, W, H, null);
canvas.drawText("原始圖片", 100,50,labelP);
LightingColorFilter lighting1 = new LightingColorFilter(0xffffff,0x000000);
mPaint.setColorFilter(lighting1);
canvas.drawBitmap(mBitmap, 0,100, mPaint);
canvas.restoreToCount(sc);
//藍(lán)色去除掉
sc = canvas.saveLayer(W, 0, W*2, H, null);
canvas.translate(W, 0);
canvas.drawText("藍(lán)色去除掉", 100,50,labelP);
LightingColorFilter lighting2 = new LightingColorFilter(0xffff00,0x000000);
mPaint.setColorFilter(lighting2);
canvas.drawBitmap(mBitmap, 0,100, mPaint);
canvas.restoreToCount(sc);
//綠色更亮
sc = canvas.saveLayer(W*2, 0, W*3, H, null);
canvas.translate(W*2, 0);
canvas.drawText("綠色更亮", 100,50,labelP);
LightingColorFilter lighting3 = new LightingColorFilter(0xffffff,0x003000);
mPaint.setColorFilter(lighting3);
canvas.drawBitmap(mBitmap, 0,100, mPaint);
canvas.restoreToCount(sc);
ba117e660fc9f943910e5a96d22341aa.png
PorterDuffColorFilter
//圖層混合紅色
sc = canvas.saveLayer(0, H, W, H*2, null);
canvas.translate(0, H);
canvas.drawText("圖層混合紅色", 100,50,labelP);
PorterDuffColorFilter porterDuffColorFilter1 = new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.DARKEN);
mPaint.setColorFilter(porterDuffColorFilter1);
canvas.drawBitmap(mBitmap, 0, 100, mPaint);
canvas.restoreToCount(sc);
//圖層混合黃色
sc = canvas.saveLayer(W, H, W*2, H*2, null);
canvas.translate(W, H);
canvas.drawText("圖層混合黃色", 100,50,labelP);
PorterDuffColorFilter porterDuffColorFilter2 = new PorterDuffColorFilter(Color.YELLOW, PorterDuff.Mode.DARKEN);
mPaint.setColorFilter(porterDuffColorFilter2);
canvas.drawBitmap(mBitmap, 0, 100, mPaint);
canvas.restoreToCount(sc);
//圖層混合紅色
sc = canvas.saveLayer(W*2, H, W*3, H*2, null);
canvas.translate(W*2, H);
canvas.drawText("圖層混合紫色", 100,50,labelP);
PorterDuffColorFilter porterDuffColorFilter3 = new PorterDuffColorFilter(Color.MAGENTA, PorterDuff.Mode.DARKEN);
mPaint.setColorFilter(porterDuffColorFilter3);
canvas.drawBitmap(mBitmap, 0, 100, mPaint);
canvas.restoreToCount(sc);
54ad2658514f0140941d7176284c7801.png
ColorMatrixColorFilter
float[] colorMatrix = {
2,0,0,0,0, //red
0,1,0,0,0, //green
0,0,1,0,0, //blue
0,0,0,1,0 //alpha
};
sc = canvas.saveLayer(0, H*2, W, H*3, null);
canvas.translate(0, H*2);
canvas.drawText("顏色亮度調(diào)節(jié)-綠色", 100,50,labelP);
ColorMatrix cm1 = new ColorMatrix();
// //顏色亮度調(diào)節(jié)-綠色
cm1.setScale(1,2,1,1);
ColorMatrixColorFilter colorMatrixColorFilter1 = new ColorMatrixColorFilter(cm1);
mPaint.setColorFilter(colorMatrixColorFilter1);
canvas.drawBitmap(mBitmap, 0, 100, mPaint);
canvas.restoreToCount(sc);
sc = canvas.saveLayer(W, H*2, W*2, H*3, null);
canvas.translate(W, H*2);
canvas.drawText("飽和度調(diào)節(jié)", 100,50,labelP);
ColorMatrix cm2 = new ColorMatrix();
// //飽和度調(diào)節(jié)0-無色彩彬祖, 1- 默認(rèn)效果, >1飽和度加強(qiáng)
cm2.setSaturation(2);
ColorMatrixColorFilter colorMatrixColorFilter2 = new ColorMatrixColorFilter(cm2);
mPaint.setColorFilter(colorMatrixColorFilter2);
canvas.drawBitmap(mBitmap, 0, 100, mPaint);
canvas.restoreToCount(sc);
sc = canvas.saveLayer(W*2, H*2, W*3, H*3, null);
canvas.translate(W*2, H*2);
canvas.drawText("色調(diào)調(diào)節(jié)", 100,50,labelP);
ColorMatrix cm3 = new ColorMatrix();
//色調(diào)調(diào)節(jié)-紅色45度
cm3.setRotate(0, 45);
ColorMatrixColorFilter colorMatrixColorFilter3 = new ColorMatrixColorFilter(cm3);
mPaint.setColorFilter(colorMatrixColorFilter3);
canvas.drawBitmap(mBitmap, 0, 100, mPaint);
canvas.restoreToCount(sc);
19bb619b815f494e90acffd13312478a.png
遮罩濾鏡
int W = 700;
int H = 150;
int sc;
sc = canvas.saveLayer(0, 0, W, H, null);
canvas.translate(0, 0);
canvas.drawText("內(nèi)外模糊", 100,50,labelP);
mPaint.setMaskFilter(new BlurMaskFilter(10, BlurMaskFilter.Blur.NORMAL));//設(shè)置畫筆遮罩濾鏡 ,傳入度數(shù)和樣式
canvas.drawLine(100,100,W-100,100,mPaint);
canvas.restoreToCount(sc);
sc = canvas.saveLayer(0, H, W, H*2, null);
canvas.translate(0, H);
canvas.drawText("外模糊內(nèi)填充", 100,50,labelP);
mPaint.setMaskFilter(new BlurMaskFilter(10, BlurMaskFilter.Blur.SOLID));//設(shè)置畫筆遮罩濾鏡 ,傳入度數(shù)和樣式
canvas.drawLine(100,100,W-100,100,mPaint);
canvas.restoreToCount(sc);
sc = canvas.saveLayer(0, H*2, W, H*3, null);
canvas.translate(0, H*2);
canvas.drawText("外模糊", 100,50,labelP);
mPaint.setMaskFilter(new BlurMaskFilter(10, BlurMaskFilter.Blur.OUTER));//設(shè)置畫筆遮罩濾鏡 ,傳入度數(shù)和樣式
canvas.drawLine(100,100,W-100,100,mPaint);
canvas.restoreToCount(sc);
sc = canvas.saveLayer(0, H*3, W, H*4, null);
canvas.translate(0, H*3);
canvas.drawText("內(nèi)模糊", 100,50,labelP);
mPaint.setMaskFilter(new BlurMaskFilter(10, BlurMaskFilter.Blur.INNER));//設(shè)置畫筆遮罩濾鏡 ,傳入度數(shù)和樣式
canvas.drawLine(100,100,W-100,100,mPaint);
canvas.restoreToCount(sc);
sc = canvas.saveLayer(0, H*4, W+300, H*4+500, null);
canvas.translate(0, H*4);
canvas.drawText("圖片加陰影", 100,50,labelP);
Bitmap mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.girl);
// 獲取位圖的Alpha通道圖
Bitmap shadowBitmap = mBitmap.extractAlpha();
mPaint.setColor(Color.DKGRAY);
// 設(shè)置畫筆遮罩濾鏡 ,傳入度數(shù)和樣式
mPaint.setMaskFilter(new BlurMaskFilter(10, BlurMaskFilter.Blur.NORMAL));
// 先繪制陰影
canvas.drawBitmap(shadowBitmap, 100, 100, mPaint);
// 畫原圖
canvas.drawBitmap(mBitmap, 100, 100, null);
canvas.restoreToCount(sc);
5f6e4219e2cf324181dd9a238382b854.png
測量文本寬度
private void drawMeasureText(Canvas canvas) {
mPaint.reset();
mPaint.setColor(Color.BLACK);
String str = "測試文本的長度:";
Rect rect = new Rect();
float size = 0;
mPaint.setTextSize(10);
mPaint.getTextBounds(str, 0, str.length(), rect); //測量文本大小罗岖,將文本大小信息存放在rect中
size = mPaint.measureText(str);//獲取文本的寬
canvas.drawText(str + size, 100, 100, mPaint);
mPaint.setTextSize(20);
mPaint.getTextBounds(str, 0, str.length(), rect); //測量文本大小涧至,將文本大小信息存放在rect中
size = mPaint.measureText(str);//獲取文本的寬
canvas.drawText(str + size, 100, 120, mPaint);
mPaint.setTextSize(30);
mPaint.getTextBounds(str, 0, str.length(), rect); //測量文本大小,將文本大小信息存放在rect中
size = mPaint.measureText(str);//獲取文本的寬
canvas.drawText(str + size, 100, 150, mPaint);
mPaint.setTextSize(40);
mPaint.getTextBounds(str, 0, str.length(), rect); //測量文本大小桑包,將文本大小信息存放在rect中
size = mPaint.measureText(str);//獲取文本的寬
canvas.drawText(str + size, 100, 190, mPaint);
mPaint.setTextSize(50);
mPaint.getTextBounds(str, 0, str.length(), rect); //測量文本大小南蓬,將文本大小信息存放在rect中
size = mPaint.measureText(str);//獲取文本的寬
canvas.drawText(str + size, 100, 240, mPaint);
postInvalidate();
invalidate();
}