【Android】Paint的效果研究

在Paint中有很多的屬性可以設置,比如可以設置陰影,顏色過濾等等,這些會產生不同的奇妙效果,今天就對各種屬性探索一下。

方法一:

1 //設置繪製的顏色,a代表透明度,r,g,b代表顏色值。 
2 setARGB(int a,int r,int g,int b);  

這個不多說了,還有兩個類似的方法,將設置alpha和rgb分割開來了。注意的是這裏的a值是0~255的範圍,不是小數。

方法二:

//設置是否使用抗鋸齒功能,會消耗較大資源,繪製圖形速度會變慢。
setAntiAlias(boolean aa);  

也不多說,你可以試驗一下效果,設置後會平滑一些;

方法三:

1 //設定是否使用圖像抖動處理,會使繪製出來的圖片顏色更加平滑和飽滿,圖像更加清晰 
2 setDither(boolean dither);  

方法四:

1 //設置MaskFilter,可以用不同的MaskFilter實現濾鏡的效果,如濾化,立體等 
2 setMaskFilter(MaskFilter maskfilter);  

MaskFilter類可以爲Paint分配邊緣效果。
對MaskFilter的擴展可以對一個Paint邊緣的alpha通道應用轉換。Android包含了下面幾種MaskFilter:
BlurMaskFilter   指定了一個模糊的樣式和半徑來處理Paint的邊緣。
EmbossMaskFilter  指定了光源的方向和環境光強度來添加浮雕效果。
要應用一個MaskFilter,可以使用setMaskFilter方法,並傳遞給它一個MaskFilter對象。下面的例子是對一個已經存在的Paint應用一個EmbossMaskFilter:

複製代碼
 1 // 設置光源的方向
 2 float[] direction = new float[]{ 1, 1, 1 };
 3 
 4 //設置環境光亮度
 5 float light = 0.4f;
 6 
 7 // 選擇要應用的反射等級
 8 float specular = 6;
 9 
10 // 向mask應用一定級別的模糊
11 float blur = 3.5f;
12 
13 EmbossMaskFilter emboss=new EmbossMaskFilter(direction,light,specular,blur);
14 
15 // 應用mask 
16 myPaint.setMaskFilter(emboss);
複製代碼

可以看一下下面的圖,是不是有浮雕的效果??

再看下面使用BlurMaskFilter:

1 //前面一個控制陰影的寬度,後面一個參數控制陰影效果
2 maskFilter = new BlurMaskFilter(10, BlurMaskFilter.Blur.SOLID);

是不是有陰影效果呢??

方法五:

1 //設置顏色過濾器,可以在繪製顏色時實現不用顏色的變換效果
2 setColorFilter(ColorFilter colorfilter);  

這個方法也值得試驗一下:

MaskFilter是對一個Paint的alpha通道的轉換,而ColorFilter則是對每一個RGB通道應用轉換。所有由ColorFilter所派生的類在執行它們的轉換時,都會忽略alpha通道。

這個貌似比較麻煩,改天再說。

方法六:

1 //設置繪製路徑的效果,如點畫線等
2 setPathEffect(PathEffect effect);  

又是一個很好玩的方法:

到目前爲止,所有的效應都會影響到Paint填充圖像的方式;PathEffect是用來控制繪製輪廓(線條)的方式。PathEffect對於繪製Path基本圖形特別有用,但是它們也可以應用到任何Paint中從而影響線條繪製的方式。
使用PathEffect,可以改變一個形狀的邊角的外觀並且控制輪廓的外表。Android包含了多個PathEffect,包括:
1)CornerPathEffect  可以使用圓角來代替尖銳的角從而對基本圖形的形狀尖銳的邊角進行平滑。

2)DashPathEffect  可以使用DashPathEffect來創建一個虛線的輪廓(短橫線/小圓點),而不是使用實線。你還可以指定任意的虛/實線段的重複模式。

3) DiscretePathEffect  與DashPathEffect相似,但是添加了隨機性。當繪製它的時候,需要指定每一段的長度和與原始路徑的偏離度。

4)PathDashPathEffect  這種效果可以定義一個新的形狀(路徑)並將其用作原始路徑的輪廓標記。
下面的效果可以在一個Paint中組合使用多個Path Effect。
1)SumPathEffect  順序地在一條路徑中添加兩種效果,這樣每一種效果都可以應用到原始路徑中,而且兩種結果可以結合起來。
2)ComposePathEffect  將兩種效果組合起來應用,先使用第一種效果,然後在這種效果的基礎上應用第二種效果。
對象形狀的PathEffect的改變會影響到形狀的區域。這就能夠保證應用到相同形狀的填充效果將會繪製到新的邊界中。
使用setPathEffect方法可以把PathEffect應用到Paint對象中,如下所示:

1 paint.setPathEffect(new CornerPathEffect(10));

其他效果懶得測試了,這個在模擬器上跑的時候效果也不明顯,但是真機上跑的時候的確圓滑了許多,看上去很舒服

方法七:

1 //設置圖形重疊時的處理方式,如合併,取交集或並集,經常用來製作橡皮的擦除效果
2 setXfermode(Xfermode xfermode);   

橡皮擦,這是個好方法啊,看看。

可以通過修改Paint的Xfermode來影響在Canvas已有的圖像上面繪製新的顏色的方式。
在正常的情況下,在已有的圖像上繪圖將會在其上面添加一層新的形狀。如果新的Paint是完全不透明的,那麼它將完全遮擋住下面的Paint;如果它是部分透明的,那麼它將會被染上下面的顏色。下面的Xfermode子類可以改變這種行爲:
1)AvoidXfermode  指定了一個顏色和容差,強制Paint避免在它上面繪圖(或者只在它上面繪圖)。
2)PixelXorXfermode  當覆蓋已有的顏色時,應用一個簡單的像素XOR操作。
3)PorterDuffXfermode  這是一個非常強大的轉換模式,使用它,可以使用圖像合成的16條Porter-Duff規則的任意一條來控制Paint如何與已有的Canvas圖像進行交互。
要應用轉換模式,可以使用setXferMode方法,如下所示: 

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

這裏可以實現完美的橡皮擦功能!代碼異常簡單:

1 Xfermode xFermode = new PorterDuffXfermode(PorterDuff.Mode.CLEAR);
2 paint.setXfermode(xFermode);

這是使用的最後一個子類,關於16條Porter-Duff規則,如下:

複製代碼
 1 private static final Xfermode[] sModes = {
 2             new PorterDuffXfermode(PorterDuff.Mode.CLEAR),
 3             new PorterDuffXfermode(PorterDuff.Mode.SRC),
 4             new PorterDuffXfermode(PorterDuff.Mode.DST),
 5             new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER),
 6             new PorterDuffXfermode(PorterDuff.Mode.DST_OVER),
 7             new PorterDuffXfermode(PorterDuff.Mode.SRC_IN),
 8             new PorterDuffXfermode(PorterDuff.Mode.DST_IN),
 9             new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT),
10             new PorterDuffXfermode(PorterDuff.Mode.DST_OUT),
11             new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP),
12             new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP),
13             new PorterDuffXfermode(PorterDuff.Mode.XOR),
14             new PorterDuffXfermode(PorterDuff.Mode.DARKEN),
15             new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN),
16             new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY),
17             new PorterDuffXfermode(PorterDuff.Mode.SCREEN)
18         };
複製代碼

它們每個顯示的效果具體如下:

第一個就是Clear效果!

上面很多的圖都是由SDK APIDemos運行所得~~有時間仔細研究一下Graphics中的每個Activity。

 

 

Java代碼  收藏代碼
  1. /**   
  2.      * Paint類介紹   
  3.      *    
  4.      * Paint即畫筆,在繪圖過程中起到了極其重要的作用,畫筆主要保存了顏色,   
  5.      * 樣式等繪製信息,指定了如何繪製文本和圖形,畫筆對象有很多設置方法,   
  6.      * 大體上可以分爲兩類,一類與圖形繪製相關,一類與文本繪製相關。          
  7.      *    
  8.      * 1.圖形繪製   
  9.      * setARGB(int a,int r,int g,int b);   
  10.      * 設置繪製的顏色,a代表透明度,r,g,b代表顏色值。   
  11.      *    
  12.      * setAlpha(int a);   
  13.      * 設置繪製圖形的透明度。   
  14.      *    
  15.      * setColor(int color);   
  16.      * 設置繪製的顏色,使用顏色值來表示,該顏色值包括透明度和RGB顏色。   
  17.      *    
  18.     * setAntiAlias(boolean aa);   
  19.      * 設置是否使用抗鋸齒功能,會消耗較大資源,繪製圖形速度會變慢。   
  20.      *    
  21.      * setDither(boolean dither);   
  22.      * 設定是否使用圖像抖動處理,會使繪製出來的圖片顏色更加平滑和飽滿,圖像更加清晰   
  23.      *    
  24.      * setFilterBitmap(boolean filter);   
  25.      * 如果該項設置爲true,則圖像在動畫進行中會濾掉對Bitmap圖像的優化操作,加快顯示   
  26.      * 速度,本設置項依賴於dither和xfermode的設置   
  27.      *    
  28.      * setMaskFilter(MaskFilter maskfilter);   
  29.      * 設置MaskFilter,可以用不同的MaskFilter實現濾鏡的效果,如濾化,立體等       *    
  30.      * setColorFilter(ColorFilter colorfilter);   
  31.      * 設置顏色過濾器,可以在繪製顏色時實現不用顏色的變換效果   
  32.      *    
  33.      * setPathEffect(PathEffect effect);   
  34.      * 設置繪製路徑的效果,如點畫線等   
  35.      *    
  36.      * setShader(Shader shader);   
  37.      * 設置圖像效果,使用Shader可以繪製出各種漸變效果   
  38.      *   
  39.      * setShadowLayer(float radius ,float dx,float dy,int color);   
  40.      * 在圖形下面設置陰影層,產生陰影效果,radius爲陰影的角度,dx和dy爲陰影在x軸和y軸上的距離,color爲陰影的顏色   
  41.      *    
  42.      * setStyle(Paint.Style style);   
  43.      * 設置畫筆的樣式,爲FILL,FILL_OR_STROKE,或STROKE   
  44.      *    
  45.      * setStrokeCap(Paint.Cap cap);   
  46.      * 當畫筆樣式爲STROKE或FILL_OR_STROKE時,設置筆刷的圖形樣式,如圓形樣式   
  47.      * Cap.ROUND,或方形樣式Cap.SQUARE   
  48.      *    
  49.      * setSrokeJoin(Paint.Join join);   
  50.      * 設置繪製時各圖形的結合方式,如平滑效果等   
  51.      *    
  52.      * setStrokeWidth(float width);   
  53.      * 當畫筆樣式爲STROKE或FILL_OR_STROKE時,設置筆刷的粗細度   
  54.      *    
  55.      * setXfermode(Xfermode xfermode);   
  56.      * 設置圖形重疊時的處理方式,如合併,取交集或並集,經常用來製作橡皮的擦除效果   
  57.      *    
  58.      * 2.文本繪製   
  59.      * setFakeBoldText(boolean fakeBoldText);   
  60.      * 模擬實現粗體文字,設置在小字體上效果會非常差   
  61.      *    
  62.      * setSubpixelText(boolean subpixelText);   
  63.      * 設置該項爲true,將有助於文本在LCD屏幕上的顯示效果   
  64.      *    
  65.      * setTextAlign(Paint.Align align);   
  66.      * 設置繪製文字的對齊方向   
  67.      *    
  68.    * setTextScaleX(float scaleX);   
  69.     * 設置繪製文字x軸的縮放比例,可以實現文字的拉伸的效果   
  70.      *    
  71.      * setTextSize(float textSize);   
  72.      * 設置繪製文字的字號大小   
  73.      *    
  74.      * setTextSkewX(float skewX);   
  75.      * 設置斜體文字,skewX爲傾斜弧度   
  76.      *    
  77.      * setTypeface(Typeface typeface);   
  78.      * 設置Typeface對象,即字體風格,包括粗體,斜體以及襯線體,非襯線體等   
  79.      *    
  80.      * setUnderlineText(boolean underlineText);   
  81.      * 設置帶有下劃線的文字效果   
  82.      *    
  83.      * setStrikeThruText(boolean strikeThruText);   
  84.      * 設置帶有刪除線的效果   
  85.      *    
  86.      */  

 

Java代碼  收藏代碼
  1. private class MyView2 extends View {  
  2.   
  3.         public MyView2(Context context) {  
  4.   
  5.             super(context);  
  6.   
  7.         }  
  8.   
  9.         @Override  
  10.         protected void onDraw(Canvas canvas)  
  11.   
  12.         {  
  13.   
  14.             super.onDraw(canvas);  
  15.   
  16.             canvas.drawColor(Color.WHITE);  
  17.   
  18.             Paint paint = new Paint();  
  19.   
  20.             paint.setAntiAlias(true);  
  21.   
  22.             paint.setColor(Color.RED);  
  23.   
  24.             paint.setStyle(Paint.Style.STROKE);//設置爲空心  
  25.   
  26.             paint.setStrokeWidth(3);  
  27.   
  28.             canvas.drawCircle(404030, paint);  
  29.   
  30.             canvas.drawRect(109070150, paint);  
  31.   
  32.             canvas.drawRect(1017070200, paint);  
  33.   
  34.             canvas.drawOval(new RectF(1022070250), paint);  
  35.   
  36.             Path path = new Path();//三角形  
  37.   
  38.             path.moveTo(10330);  
  39.   
  40.             path.lineTo(70330);  
  41.   
  42.             path.lineTo(40270);  
  43.   
  44.             path.close();  
  45.   
  46.             canvas.drawPath(path, paint);  
  47.   
  48.             Path path1 = new Path();//梯形  
  49.   
  50.             path1.moveTo(10410);//繪畫基點  
  51.   
  52.             path1.lineTo(70410);  
  53.   
  54.             path1.lineTo(55350);  
  55.   
  56.             path1.lineTo(25350);  
  57.   
  58.             path1.close();//把開始的點和最後的點連接在一起,構成一個封閉圖形  
  59.             /* 
  60.              * 最重要的就是movtTo和close,如果是Style.FILL的話,不設置close,也沒有區別,可是如果是STROKE模式, 
  61.              * 如果不設置close,圖形不封閉。 
  62.              *  
  63.              * 當然,你也可以不設置close,再添加一條線,效果一樣。 
  64.              */  
  65.             canvas.drawPath(path1, paint);  
  66.               
  67.               
  68.               
  69.               
  70.             ///////////////////////////////////////第二列  
  71.   
  72.             paint.setColor(Color.BLUE);  
  73.   
  74.             paint.setStyle(Paint.Style.FILL);//設置實心  
  75.   
  76.             canvas.drawCircle(1204030, paint);  
  77.   
  78.             canvas.drawRect(9090150150, paint);  
  79.   
  80.             canvas.drawRect(90170150200, paint);  
  81.   
  82.             RectF re2 = new RectF(90220150250);  
  83.   
  84.             canvas.drawOval(re2, paint);  
  85.   
  86.             Path path2 = new Path();  
  87.   
  88.             path2.moveTo(90330);  
  89.   
  90.             path2.lineTo(150330);  
  91.   
  92.             path2.lineTo(120270);  
  93.   
  94.             path2.close();  
  95.   
  96.             canvas.drawPath(path2, paint);  
  97.   
  98.             Path path3 = new Path();  
  99.   
  100.             path3.moveTo(90410);  
  101.   
  102.             path3.lineTo(150410);  
  103.   
  104.             path3.lineTo(135350);  
  105.   
  106.             path3.lineTo(105350);  
  107.   
  108.             path3.close();  
  109.   
  110.             canvas.drawPath(path3, paint);  
  111.               
  112.               
  113.             ////////////////////////////////////////////////////第三列  
  114.               
  115.             /* 
  116.              * LinearGradient shader = new LinearGradient(0, 0, endX, endY, new 
  117.              * int[]{startColor, midleColor, endColor},new float[]{0 , 0.5f, 
  118.              * 1.0f}, TileMode.MIRROR); 
  119.              * 參數一爲漸變起初點座標x位置,參數二爲y軸位置,參數三和四分辨對應漸變終點 
  120.              * 其中參數new int[]{startColor, midleColor,endColor}是參與漸變效果的顏色集合,  
  121.              * 其中參數new float[]{0 , 0.5f, 1.0f}是定義每個顏色處於的漸變相對位置, 這個參數可以爲null,如果爲null表示所有的顏色按順序均勻的分佈 
  122.              */  
  123.             Shader mShader = new LinearGradient(00100100,  
  124.   
  125.             new int[] { Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW },  
  126.   
  127.             null, Shader.TileMode.REPEAT);  
  128.   
  129.             // Shader.TileMode三種模式  
  130.   
  131.             // REPEAT:沿着漸變方向循環重複  
  132.   
  133.             // CLAMP:如果在預先定義的範圍外畫的話,就重複邊界的顏色  
  134.   
  135.             // MIRROR:與REPEAT一樣都是循環重複,但這個會對稱重複  
  136.   
  137.             paint.setShader(mShader);// 用Shader中定義定義的顏色來話  
  138.   
  139.             canvas.drawCircle(2004030, paint);  
  140.   
  141.             canvas.drawRect(17090230150, paint);  
  142.   
  143.             canvas.drawRect(170170230200, paint);  
  144.   
  145.             RectF re3 = new RectF(170220230250);  
  146.   
  147.             canvas.drawOval(re3, paint);  
  148.   
  149.             Path path4 = new Path();  
  150.   
  151.             path4.moveTo(170330);  
  152.   
  153.             path4.lineTo(230330);  
  154.   
  155.             path4.lineTo(200270);  
  156.   
  157.             path4.close();  
  158.   
  159.             canvas.drawPath(path4, paint);  
  160.   
  161.             Path path5 = new Path();  
  162.   
  163.             path5.moveTo(170410);  
  164.   
  165.             path5.lineTo(230410);  
  166.   
  167.             path5.lineTo(215350);  
  168.   
  169.             path5.lineTo(185350);  
  170.   
  171.             path5.close();  
  172.   
  173.             canvas.drawPath(path5, paint);  
  174.               
  175.             //////////////////////////////////第4列  
  176.   
  177.             paint.setTextSize(24);  
  178.   
  179.             canvas.drawText("圓形"24050, paint);  
  180.   
  181.             canvas.drawText("正方形"240120, paint);  
  182.   
  183.             canvas.drawText("長方形"240190, paint);  
  184.   
  185.             canvas.drawText("橢圓形"240250, paint);  
  186.   
  187.             canvas.drawText("三角形"240320, paint);  
  188.   
  189.             canvas.drawText("梯形"240390, paint);  
  190.   
  191.         }  
  192.   
  193.     }  

 

發佈了22 篇原創文章 · 獲贊 9 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章