日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

hencoder学习自定义view(1)

發布時間:2023/12/10 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hencoder学习自定义view(1) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

從hencoder上學習關于 paint的知識
HenCoder Android 開發進階: 自定義 View 1-2 Paint 詳解

關于Paint,有四個最重要的API,分別是

  • 顏色
  • 效果
  • drawText()相關
  • 初始化

1、顏色

canvas繪制的內容對顏色有三種處理:

1.1、基本顏色
為像素的基本顏色,根據繪制內容的不同而有不同的控制方式:Canvas的顏色填充類方法drawColor()/RGB()/ARGB()的顏色,是直接寫在參數中的,drawBitmap的顏色是由Bitmap對象直接提供的,除此之外,文字和圖形的顏色繪制就需要paint的額外參數來設置了。

  • 直接設置顏色 setColor()
  • paint.setColor(Color.parseColor("#00FFFF")); canvas.drawText("rikkatheworld",100,100,paint);
  • setARGB(int a,int r,int g,int b)
    這三個值為透明度和三原色,實際運用setARGB和setColor效果是一樣的
  • paint.setARGB(100,255,0,0); canvas.drawRect(0,0,200,200,paint);

    setShader(Shader shader) 設置 Shader
    除了給paint直接設置顏色,還可以給paint設置Shader,它是一個著色器,是一套設置顏色的方案。
    當設置了Shader后,Paint就不會使用setColor或者setARGB里面的顏色了,而是直接使用Shader中的方案。

  • LinearGradient 線性漸變
    設置兩個點和兩種顏色,以這兩個點作為端點,使用兩種顏色的漸變來繪制顏色。比如:
  • Shader shader = new LinearGradient(100,100,500,500,Color.parseColor("E91E63"),Color.parseColor("#2196F3"),Shader.TileMode.CLAMP); paint.setShader(shader); canvas.drawCircle(300,300,200,paint);

    效果如下:

    其中前4個參數為2個端點的坐標,兩個顏色為端點散發出的顏色,最后一個變量Shader.TileMode tile有三種模式:CLAMP、MIRROR、REPEAT,從字面意思上可以得出CLAMP是最正常的模式,其次是鏡像最后一個是重復漸變。

  • RadialGradient 輻射漸變
    就是從圓的中心向外顏色漸變:
  • Shader shader = new RadialGradient(300, 300, 200, Color.parseColor("#E91E63"), Color.parseColor("#2196F3"), Shader.TileMode.CLAMP); paint.setShader(shader); canvas.drawCircle(300,300,200,paint);

    前兩個參數為圓心,第三個參數為半徑,第一個顏色為輻射的中心顏色,第二個則為邊緣顏色。效果如下:

    3. SweepGradient 掃描漸變
    大概是這樣:

    Shader shader = new SweepGradient(300, 300, 200, Color.parseColor("#E91E63"), Color.parseColor("#2196F3"), Shader.TileMode.CLAMP); paint.setShader(shader); canvas.drawCircle(300, 300, 200, paint);

    效果如下:

  • BitmapShader 就是將Bitmap的像素作為圖形或者文字的填充
  • Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.batman); Shader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); paint.setShader(shader); canvas.drawCircle(300, 300, 200, paint);


    沒錯從上面的效果可以看出 使用drawCircle+BitmapShader 和 drawBitmap效果一樣,但是這樣可以繪制出圓形的bitmap,比如說頭像。

  • ComposeShader 混合著色器
    就是把兩個Shader混在一起用
  • // 第一個 Shader:頭像的 Bitmap Bitmap bitmap1 = BitmapFactory.decodeResource(getResources(), R.drawable.batman); Shader shader1 = new BitmapShader(bitmap1, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);// 第二個 Shader:從上到下的線性漸變(由透明到黑色) Bitmap bitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.batman_logo); Shader shader2 = new BitmapShader(bitmap2, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);// ComposeShader:結合兩個 Shader Shader shader = new ComposeShader(shader1, shader2, PorterDuff.Mode.SRC_OVER); paint.setShader(shader); canvas.drawCircle(300, 300, 300, paint);

    PorterDuff.Mode.SRC_OVER:使用了兩個bitmap進行疊加繪制。
    PorterDuff.Mode是用來指定兩個bitmap繪制時的顏色策略。它有17種繪制模式,而 SRC_OVER是最正常最常用的繪制策略。
    別的模式可以參考官方文檔:官方文檔

    1.2、setColorFilter(ColorFilter colorFilter)
    為顏繪制設置顏色過濾,為繪制的內容建立一個統一的過濾策略,然后 Canvas的drawXXX()會對每個像素都進行過濾然后繪制出來。在paint中使用setColorFilter方法,ColorFilter并不能直接使用,而是要使用它的三個子類:LightingColorFilter PorterDuffColorFilter 和 ColorMatrixColorFilter。

  • LightingColorFilter
    用來模擬簡單的光照效果
    LightingColorFilter的構造方法是LightingColorFilter(int mul, int add),參數中的mul和add都是和顏色格式相同的int值,其中mul用來和目標像素相乘,add用來和目標像素相加。
  • R' = R * mul.R / 0xff + add.R G' = G * mul.G / 0xff + add.G B' = B * mul.B / 0xff + add.B

    一個默認的LightingColorFilter,mul值為0xffffff,add值為0x000000,那么對于一個像素,他的計算過程就是:

    R' = R * 0xff / 0xff + 0x0 = R // R' = R G' = G * 0xff / 0xff + 0x0 = G // G' = G B' = B * 0xff / 0xff + 0x0 = B // B' = B

    如果我們將紅色移除,可以把mul值改成 0x00ffff,則R’就計算等于0了。
    比如說我們可以把綠色調的更加鮮艷,可以將add改成 0x003000,那么其G’=G+0x30,這時候綠色就更加的鮮艷了~

    ColorFilter lightingColorFilter = new LightingColorFilter(0xffffff, 0x003000); paint.setColorFilter(lightingColorFilter);
  • PorterDuffColorFilter
    用一個指定的顏色和一個指定的ProterDuff.Mode來對繪制對象進行合成。和之前的ComposeShader相比的區別就是之前是用Bitmap來進行合成,而這次就只能指定用一種顏色源。

  • ColorMatrixColorFilter
    ColorMatrixColorFilter 使用一個 ColorMatrix 來對顏色進行處理。 ColorMatrix 這個類,內部是一個 4x5 的矩陣:

  • [ a, b, c, d, e,f, g, h, i, j,k, l, m, n, o,p, q, r, s, t ]

    通過計算,ColorMartix可以要把繪制的像素進行轉化,對于顏色【R,G,B,A】來說,轉化算法是這樣的:

    R’ = a*R + b*G + c*B + d*A + e; G’ = f*R + g*G + h*B + i*A + j; B’ = k*R + l*G + m*B + n*A + o; A’ = p*R + q*G + r*B + s*A + t;

    還可以通過setSatuation(float sat)來進行設置飽和度,具體如何就不說了。
    這里有個通過ColorMatrixColorFilter做的開源濾鏡庫StyleImageView

    以上就是Paint對顏色的第二層處理:通過setColorFilter(colorFilter)來進行像素過濾從而達到加工顏色的效果。
    Paint最后一層處理顏色的方法就是setXfermode,它處理的是 [當顏色遇上View] 的問題。

    1.3 setXfermode
    “Xfermode"其實就是"Transfer mode”,準確的定義是當你要繪制的內容和Canvas的目標位置的內容應該怎樣結合計算去得出最終的顏色。通俗地說,其實就是要你以繪制的內容作為源圖像,以 View 中已有的內容作為目標圖像,選取一個 PorterDuff.Mode 作為繪制內容的顏色處理方案。就像這樣:

    Xfermode xfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_IN); ... canvas.drawBitmap(rectBitmap, 0, 0, paint); // 畫方 paint.setXfermode(xfermode); // 設置 Xfermode canvas.drawBitmap(circleBitmap, 0, 0, paint); // 畫圓 paint.setXfermode(null); // 用完及時清除 Xfermode

    得到的效果是這樣:


    另外,從上面的示例代碼可以看出,創建 Xfermode 的時候其實是創建的它的子類 PorterDuffXfermode。而事實上,Xfermode 也只有這一個子類。

    使用Xfemode時我們要注意兩點:

  • 使用離屏緩存
    我們實際上在不做處理時使用上述的代碼并不能直接得到那么理想的結果,而是:

    這是因為在第二步畫圓的時候,和正方形一起進行計算并不是這個圓,而是這個帶圓的view,而且因為View的底色并不是默認的透明色,所以導致這些底色也參與了計算,這個時候我們需要開啟離屏緩存 (Off-screen Buffer) ,先讓繪制的內容在屏幕之外繪制好,最后再貼回view中:

    使用離屏緩存有兩種方式:
    (1)Canvas.saveLayer()
    可以做短時間的離屏緩沖。
  • int saved = canvas.saveLayer(null, null, Canvas.ALL_SAVE_FLAG);canvas.drawBitmap(rectBitmap, 0, 0, paint); // 畫方 paint.setXfermode(xfermode); // 設置 Xfermode canvas.drawBitmap(circleBitmap, 0, 0, paint); // 畫圓 paint.setXfermode(null); // 用完及時清除 Xfermodecanvas.restoreToCount(saved);

    (2)View.setLayerType()
    View.setLayerType() 是直接把整個 View 都繪制在離屏緩沖中。 setLayerType(LAYER_TYPE_HARDWARE) 是使用 GPU 來緩沖, setLayerType(LAYER_TYPE_SOFTWARE) 是直接用一個 Bitmap 來緩沖。

  • 控制好透明區域
    使用Xfermode來繪制內容,除了注意使用離屏緩沖,還要注意控制它的透明區域不要太小,要讓它足夠覆蓋到要和它結合繪制的內容。否則很容易得到你不想要的,比如:
  • 到這里,Paint的第一類API,關于顏色的設置到這里就講完了,Paint對繪制內容的著色主要包括三層,第一層是通過setColor等api像素進行直接上色,第二類是通過setColoerFilter來對像素進行過濾,就和我們平時相機用到的濾鏡似的,最后通過Xfermode來對繪制中出現相遇別的view的時候做一個顏色的處理。

    總結

    以上是生活随笔為你收集整理的hencoder学习自定义view(1)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。