Android Canvas實現(xiàn)自定義形狀的image

靈活自定義imageview的形狀

  • 在自定義View的ondraw方法中實現(xiàn)繪制的內(nèi)容郑趁,各個layer逐個繪制挤安,通過設置PorterDuffXfermode實現(xiàn)不同的圖片疊加效果
//設置背景色

canvas.drawARGB(255, 139, 197, 186);

int canvasWidth = canvas.getWidth();

int canvasHeight = canvas.getHeight();

int layerId = canvas.saveLayer(0, 0, canvasWidth, canvasHeight, null, Canvas.ALL_SAVE_FLAG);

int r = canvasWidth / 2;

//根據(jù)圖片生成bitmapshader

paint.setColor(0xFFFFCC44);

Bitmap bitmap = Bitmap.createBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.xihu));

bitmap = scaleBitmap(bitmap,2*r,2*r);

BitmapShader bitmapShader = new BitmapShader(bitmap,Shader.TileMode.CLAMP,Shader.TileMode.CLAMP);

paint.setShader(bitmapShader);

canvas.drawCircle(r, r, r, paint);

//使用CLEAR作為PorterDuffXfermode繪制藍色的矩形

paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));// clear 到背景顏色那一層

canvas.drawCircle(r*3f-50, r, r , paint);

//最后將畫筆去除Xfermode

paint.setXfermode(null);

canvas.restoreToCount(layerId);
  • Bitmap生成shader的時候彼城,需要將圖片縮放成view的大小
/**

 * 根據(jù)給定的寬和高進行拉伸

* @param origin    原圖

* @param newWidth  新圖的寬

* @param newHeight 新圖的高

* @return new Bitmap

 */

private Bitmap scaleBitmap(Bitmap origin, int newWidth, int newHeight) {

    if (origin == null) {

        return null;

    }

    int height = origin.getHeight();

    int width = origin.getWidth();

    float scaleWidth = ((float) newWidth) / width;

    float scaleHeight = ((float) newHeight) / height;

    Matrix matrix = new Matrix();

    matrix.postScale(scaleWidth, scaleHeight);// 使用后乘

    Bitmap newBM = Bitmap.createBitmap(origin, 0, 0, width, height, matrix, false);

    if (!origin.isRecycled()) {

        origin.recycle();

    }

    return newBM;

}
  • 效果
r1McLAqQYLVfWL6Ducp97ZuhdH1OWBRhZiWv2OEBSZYGCWP7ps.png
  • 業(yè)務中是通過設計師給出的svgx圖片生成path孽惰,根據(jù)path繪制出想要的圖形贩绕,再用需要展示的bitmap縮放后生成著色器嗤无,再實現(xiàn)渲染;因為svg形狀可以任意对雪,因此更加靈活

Android graphics使用

(1)繪制形狀Canvas

[圖片上傳失敗...(image-3c6580-1573961626362)]

Path可自由實現(xiàn)各種自定義形狀:直線河狐,圓弧,貝塞爾曲線等等

Path path = new Path();

RectF rect = new RectF(300,300,1000,800);

mPaint.setColor(Color.GRAY);

mPaint.setStyle(Style.FILL);

canvas.drawRect(rect, mPaint);

mPaint.setColor(Color.BLACK);

mPaint.setStyle(Style.STROKE);

path.lineTo(100, 100); //用path畫一條從(0,0)到(100,100)的直線

path.arcTo(rect, 90, 180); //用arcTo方法畫一段圓弧

canvas.drawPath(path, mPaint); //直線終點(100,100)與圓弧起點會連成一條直線

(2)繪制效果Paint

  • Paint

  • 設置顏色

  • 設置筆觸效果/文字大小

  • 設置濾鏡

  • 設置透明度

  • 設置著色器Shader

  • BimapShader:位圖的圖像渲染器

  • LinearGradient:線性渲染器

  • RadialGradient:環(huán)形渲染器瑟捣,一般的水波紋效果馋艺,充電水波紋擴散效果、調(diào)色板都可以使用該渲染器實現(xiàn)迈套。

  • SweepGradient:梯度渲染器(即掃描渲染)捐祠,可以使用該渲染器實現(xiàn),如:微信等雷達掃描效果桑李、手機衛(wèi)士垃圾掃描踱蛀。

  • ComposeShader:組合渲染器

  • 設置layer之間的組合模式PorterDuffXfermode等等

[圖片上傳失敗...(image-f699f4-1573961626362)]

(3)繪制位置坐標

[圖片上傳失敗...(image-f432a2-1573961626362)]

(4)變換處理Matrix

  • setTranslate(float dx,float dy):控制Matrix進行位移

  • setSkew(float kx,float ky):控制Matrix進行傾斜窿给,kx、ky為X星岗、Y方向上的比例

  • setSkew(float kx,float ky,float px,float py):控制Matrix以px填大、py為軸心進行傾斜,kx俏橘、ky為X允华、Y方向上的傾斜比例

  • setRotate(float degrees):控制Matrix進行depress角度的旋轉,軸心為(0,0)

  • setRotate(float degrees,float px,float py):控制Matrix進行depress角度的旋轉寥掐,軸心為(px,py)

  • setScale(float sx,float sy):設置Matrix進行縮放靴寂,sx、sy為X召耘、Y方向上的縮放比例

  • setScale(float sx,float sy,float px,float py):設置Matrix以(px,py)為軸心進行縮放百炬,sx、sy為X污它、Y方向上的縮放比例

例:將bitmap放大2倍

Matrix matrix = new Matrix();

matrix.postScale(2, 2);// 使用后乘

Bitmap newBM = Bitmap.createBitmap(origin, 0, 0, width, height, matrix, false);

(5)自定義動畫效果

[圖片上傳失敗...(image-47702a-1573961626362)]

[圖片上傳失敗...(image-b5fd46-1573961626362)]

參考文檔

graphic基本操作例子

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末剖踊,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子衫贬,更是在濱河造成了極大的恐慌德澈,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件固惯,死亡現(xiàn)場離奇詭異梆造,居然都是意外死亡,警方通過查閱死者的電腦和手機葬毫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門镇辉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人贴捡,你說我怎么就攤上這事忽肛。” “怎么了烂斋?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵麻裁,是天一觀的道長。 經(jīng)常有香客問我源祈,道長,這世上最難降的妖魔是什么色迂? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任香缺,我火速辦了婚禮,結果婚禮上歇僧,老公的妹妹穿的比我還像新娘图张。我一直安慰自己锋拖,他們只是感情好,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布祸轮。 她就那樣靜靜地躺著兽埃,像睡著了一般。 火紅的嫁衣襯著肌膚如雪适袜。 梳的紋絲不亂的頭發(fā)上柄错,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天,我揣著相機與錄音苦酱,去河邊找鬼售貌。 笑死,一個胖子當著我的面吹牛疫萤,可吹牛的內(nèi)容都是我干的颂跨。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼扯饶,長吁一口氣:“原來是場噩夢啊……” “哼恒削!你這毒婦竟也來了?” 一聲冷哼從身側響起尾序,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤钓丰,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蹲诀,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體斑粱,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年脯爪,在試婚紗的時候發(fā)現(xiàn)自己被綠了则北。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡痕慢,死狀恐怖尚揣,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情掖举,我是刑警寧澤快骗,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站塔次,受9級特大地震影響方篮,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜励负,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一藕溅、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧继榆,春花似錦巾表、人聲如沸汁掠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽考阱。三九已至,卻和暖如春鞠苟,著一層夾襖步出監(jiān)牢的瞬間乞榨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工偶妖, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留姜凄,地道東北人。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓趾访,卻偏偏與公主長得像态秧,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子扼鞋,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容