導航:首頁 > 操作系統 > androidcanvas鋸齒

androidcanvas鋸齒

發布時間:2025-09-25 04:07:36

android 如何重寫imageview 讓圖片有圓角效果

android 自定義圓角ImageView以及鋸齒的處理

看到很多人開發過程中要使用圓角圖片時,解決方法有:


1.重新繪制一張圖片


2.通過布局來配置


3.通過重寫View來實現


其中1,2在這里就不講了,重點講講方法三的實現。



實現一:通過截取畫布一個圓形區域與圖片的相交部分進行繪制,缺點:鋸齒明顯,設置Paint,Canvas抗鋸齒無效。

package com.open.circleimageview.widget;


import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.Canvas;

import android.graphics.Paint;

import android.graphics.PaintFlagsDrawFilter;

import android.graphics.Path;

import android.graphics.Rect;

import android.graphics.Region;

import android.util.AttributeSet;

import android.view.View;


public class CircleImageViewA extends View {


public CircleImageViewA(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

}


public CircleImageViewA(Context context, AttributeSet attrs) {

super(context, attrs);

}


public CircleImageViewA(Context context) {

super(context);

}


private Bitmap bitmap;

private Rect bitmapRect=new Rect();

private PaintFlagsDrawFilter pdf=new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG);

private Paint paint = new Paint();

{

paint.setStyle(Paint.Style.STROKE);

paint.setFlags(Paint.ANTI_ALIAS_FLAG);

paint.setAntiAlias(true);// 設置畫筆的鋸齒效果。 true是去除,大家一看效果就明白了

}

private Path mPath=new Path();

public void setImageBitmap(Bitmap bitmap)

{

this.bitmap=bitmap;

}

@Override

protected void onDraw(Canvas canvas) {


if(null==bitmap)

{

return;

}

bitmapRect.set(0, 0, getWidth(), getHeight());

canvas.save();

canvas.setDrawFilter(pdf);

mPath.reset();

canvas.clipPath(mPath); // makes the clip empty

mPath.addCircle(getWidth()/2, getWidth()/2, getHeight()/2, Path.Direction.CCW);

canvas.clipPath(mPath, Region.Op.REPLACE);

canvas.drawBitmap(bitmap, null, bitmapRect, paint);

canvas.restore();

}

}


實現二:通過PorterDuffXfermode 方式(注意要設置硬體加速,否則部分機子無效),優點:鋸齒基本沒有

package com.open.circleimageview.widget;


import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.PaintFlagsDrawFilter;

import android.graphics.PorterDuff;

import android.graphics.PorterDuffXfermode;

import android.graphics.Rect;

import android.graphics.RectF;

import android.util.AttributeSet;

import android.view.View;


public class CircleImageViewB extends View {


public CircleImageViewB(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

init();

}


public CircleImageViewB(Context context, AttributeSet attrs) {

super(context, attrs);

init();

}


public CircleImageViewB(Context context) {

super(context);

init();

}


private Bitmap bitmap;

private Rect bitmapRect=new Rect();

private PaintFlagsDrawFilter pdf=new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG);

private Paint paint = new Paint();

{

paint.setStyle(Paint.Style.STROKE);

paint.setFlags(Paint.ANTI_ALIAS_FLAG);

paint.setAntiAlias(true);// 設置畫筆的鋸齒效果。 true是去除,大家一看效果就明白了

}

private Bitmap mDstB=null;

private PorterDuffXfermode xfermode=new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY);

private void init()

{

try {

if(android.os.Build.VERSION.SDK_INT>=11)

{

setLayerType(LAYER_TYPE_SOFTWARE, null);

}

} catch (Exception e) {

e.printStackTrace();

}

}

public void setImageBitmap(Bitmap bitmap)

{

this.bitmap=bitmap;

}


private Bitmap makeDst(int w, int h)

{

Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);

Canvas c = new Canvas(bm);

Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);

p.setColor(Color.parseColor("#ffffffff"));

c.drawOval(new RectF(0, 0, w, h), p);

return bm;

}

@Override

protected void onDraw(Canvas canvas) {


if(null==bitmap)

{

return;

}

if(null==mDstB)

{

mDstB=makeDst(getWidth(), getHeight());

}


bitmapRect.set(0, 0, getWidth(), getHeight());

canvas.save();

canvas.setDrawFilter(pdf);

canvas.drawBitmap(mDstB, 0, 0, paint);

paint.setXfermode(xfermode);

canvas.drawBitmap(bitmap, null, bitmapRect, paint);

paint.setXfermode(null);

canvas.restore();

}

}


Ⅱ android canvas.drawcircle 為什麼畫不出圓

繪制圓的話,drawcircle需要傳圓心坐標和半徑大小/畫筆進去,我猜你缺少對應的參數,可以參考如下代碼:
mPaint.setAntiAlias(false); //設置畫筆為無鋸齒
mPaint.setColor(Color.BLACK); //設置畫筆顏色
canvas.drawColor(Color.WHITE); //白色背景
mPaint.setStrokeWidth((float) 3.0); //線寬
mPaint.setStyle(Paint.Style.STROKE); //空心效果

canvas.drawCircle(50, 50, 10, mPaint); //繪制圓形
canvas.drawCircle(100, 100, 20, mPaint); //繪制圓形
canvas.drawCircle(150, 150, 30, mPaint); //繪制圓形
canvas.drawCircle(200, 200, 40, mPaint); //繪制圓形
canvas.drawCircle(250, 250, 50, mPaint); //繪制圓形
canvas.drawCircle(300, 300, 60, mPaint); //繪制圓形
canvas.drawCircle(350, 350, 70, mPaint); //繪制圓形

Ⅲ 微信android版應用圖標上添加數字是怎麼實現的

使用RemoteView自定義Notification

/**

* 在給定的圖片的右上角加上聯系人數量。數量用紅色表示

* @param icon 給定的圖片

* @return 帶聯系人數量的圖片

*/

private Bitmap generatorContactCountIcon(Bitmap icon){

//初始化畫布

int iconSize=(int)getResources().getDimension(android.R.dimen.app_icon_size);

Log.d(TAG, "the icon size is "+iconSize);

Bitmap contactIcon=Bitmap.createBitmap(iconSize, iconSize, Config.ARGB_8888);

Canvas canvas=new Canvas(contactIcon);

//拷貝圖片

Paint iconPaint=new Paint();

iconPaint.setDither(true);//防抖動

iconPaint.setFilterBitmap(true);//用來對Bitmap進行濾波處理,這樣,當你選擇Drawable時,會有抗鋸齒的效果

Rect src=new Rect(0, 0, icon.getWidth(), icon.getHeight());

Rect dst=new Rect(0, 0, iconSize, iconSize);

canvas.drawBitmap(icon, src, dst, iconPaint);

//在圖片上創建一個覆蓋的聯系人個數

int contacyCount=getContactCount();

//啟用抗鋸齒和使用設備的文本字距

Paint countPaint=new Paint(Paint.ANTI_ALIAS_FLAG|Paint.DEV_KERN_TEXT_FLAG);

countPaint.setColor(Color.RED);

countPaint.setTextSize(20f);

countPaint.setTypeface(Typeface.DEFAULT_BOLD);

canvas.drawText(String.valueOf(contacyCount), iconSize-18, 25, countPaint);

return contactIcon;

}

mImageView.setImageBitmap(contactCountIcon);
無非就是定義一個畫布(Canvas),然後在上面畫圖標,畫數字文本。

Ⅳ Android 圓角、圓形 ImageView 實現

我們要實現的圖片控制項繼承自 AppCompatImageView ,它是 ImageView 的子類,但提供了更好的兼容性,我們在此基礎上添加了若干自定義的屬性和方法以實現最終的 NiceImageView :

要實圓角或者圓形的顯示效果,就是對圖片顯示的內容區域進行「裁剪」,只顯示指定的區域即可。如何做呢?

一種比較直接的辦法是這樣的,由於圖片是被繪制在畫布上的,所以用 canvas 的 clipPath() 方法先將畫布裁剪成指定形狀,這樣就能讓圖片按指定形狀顯示了,重新 draw() 方法即可:

這樣使用 src 、 background 屬性給ImageView設置顯示的圖片都能達到預期的顯示效果。但是由於 clipPath() 方法不支持抗鋸齒,圖片邊緣會有明顯的毛糙感,體驗並不理想,所以需要尋找其它方法。

另一種方法是使用圖像的 Alpha 合成模式 ,即
PorterDuff 來實現, 官方文檔 。這里我們使用其中的 DST_IN 模式。整個過程就是先繪制目標圖像,也就是圖片;再繪制原圖像,即一個圓角矩形或者圓形,這樣最終目標圖像只顯示和原圖像重合的區域。

到這里就實現了顯示為圓角或者圓形了。但是需要通過 src 屬性或者對應的方法來設置圖片,否則不能達到預期效果。

繪制邊框就相對容易理解了,只需要繪制一個指定樣式的圓角矩形或者圓形即可:

當圖片顯示為圓形時,還可以繪制一個內邊框,但圓角矩形的話由於圓角大小的問題,目前只能設置一個邊框咯。

但是有個問題,繪制的邊框會覆蓋在圖片上,如果邊框太寬會導致圖片的可見區域變小了,影像顯示效果,像這樣,左下角的花盆不見了:

那麼如何讓邊框不覆蓋在圖片上呢?可以在 Alpha 合成繪制前先將畫布縮小一定比例,最後再繪制邊框,這樣問題就解決了。

縮放後的ImageView顯示區域的寬高就是原寬、高分別減去2倍的邊框寬度,這樣縮小的比例也就顯而易見了。效果如下,左下角的花盆出來了:

遮罩可以理解為一層帶透明度的顏色,遮罩默認不繪制,當制定了遮罩顏色時才會繪制,實現很簡單:

例如加一個透明度30%的紅色遮罩後的效果:

核心的實現邏輯就這些了,剩下的就是自定義屬性和方法了,有興趣的可以看源碼,都很簡單,希望對你有所幫助吧!

更多細節及用法見GitHub: https://github.com/SheHuan/NiceImageView

如果你需要實現類似釘釘的圓形組合頭像,例如:

閱讀全文

與androidcanvas鋸齒相關的資料

熱點內容
雲伺服器帶款不夠怎麼辦 瀏覽:286
php網站工具下載 瀏覽:635
伺服器hs是什麼 瀏覽:456
編譯器電腦硬體 瀏覽:85
防火牆埠配置命令 瀏覽:549
壓縮機製造技術 瀏覽:314
迅捷pdf編輯器在線 瀏覽:844
如何選擇騰訊雲伺服器 瀏覽:148
程序員案件 瀏覽:380
編程題演算法想的很慢怎麼辦 瀏覽:999
現在的app怎麼都這么白啊 瀏覽:228
共享文件夾儲存不足 瀏覽:914
java編程技巧 瀏覽:144
命令別人動漫 瀏覽:520
程序員的工資是多少了解一下啊 瀏覽:115
古典密碼對什麼加密 瀏覽:975
java圖論 瀏覽:759
e盤里的360文件夾刪不掉 瀏覽:806
最解壓的球視頻 瀏覽:632
dos定時命令 瀏覽:412