android繪制圓形圖片的兩種方式示例
android繪制圓形圖片的兩種方式
看下效果先


下面有完整的示例代碼
使用BitmapShader(著色器)
我們在繪制view 的時候 就是小學上美術課 用水彩筆在本子上畫畫 使用著色器繪制圓形圖片最簡單的理解方式 就是把bitmap當做一種顏色 設置給paint ,paint都已經(jīng)有顏色了 你想讓它方了,圓了,扁了 還不是看你心情 canvas調(diào)用那個方法咯
實現(xiàn)的大致思路如下:
1. 創(chuàng)建一個類 繼承imageView 重寫onDraw()
2. 獲取到bitmap圖片
3. 計算圖片的縮放比例 使用矩陣matrix 進行縮放
4. 創(chuàng)建BitmapShader著色器 設置縮放矩陣
5. paint設置著色器 繪制
具體實現(xiàn) 注釋也標注的很清楚
private void shaderCircle(Canvas canvas){
//獲取Drawable
Drawable resources=getDrawable();
float scale = 1.0f;//縮放比例
int mRadius=0;//圓的半徑
if (resources instanceof BitmapDrawable){
//獲取bitmap
Bitmap bitmap=((BitmapDrawable) resources).getBitmap();
if (bitmap==null) return;
// 獲取bitmap寬高中的小值
int minBitMap = Math.min(bitmap.getWidth(), bitmap.getHeight());
//取view寬高中的小值 盡量保證圖片內(nèi)容的顯示
int minValue=Math.min(getWidth(),getHeight());
//設置半徑
mRadius=minValue/2;
//計算縮放比例 一定要*1.0f 因為int之間的計算結果會四舍五入0或1 效果就不美麗了
scale=minValue*1.0f/minBitMap;
//設置縮放比例
matrix.setScale(scale,scale);
/**
* 創(chuàng)建著色器 設置著色模式
* TileMode的取值有三種:
* CLAMP 拉伸 REPEAT 重復 MIRROR 鏡像
*/
BitmapShader shader=new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
//設置矩陣
shader.setLocalMatrix(matrix);
paint.setShader(shader);
canvas.drawCircle(mRadius, mRadius, mRadius, paint);
}
}
使用Xfermode 設置圖片相交模式
簡單說呢 在一張畫布上畫了兩張圖片 這兩張圖的以怎樣的方式顯示出來 例如:只顯示上層圖片,只顯示下層圖片 ,顯示兩張圖的交集部分 等等等
實現(xiàn)思路
1.創(chuàng)建一個空bitmap 根據(jù)這個bitmap創(chuàng)建一個Canvas
2.設置Canvas透明 畫一個想要實現(xiàn)的形狀
3.設置圖形相交模式
4.獲取圖片資源 繪制到Canvas
實現(xiàn)代碼
private Bitmap getCircleBitmap(){
Drawable drawable=getDrawable();
if (drawable instanceof BitmapDrawable) {
Paint paint=new Paint();
paint.setAntiAlias(true);
//獲取資源圖片
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
//創(chuàng)建空位圖
Bitmap output=Bitmap.createBitmap(getWidth(),getHeight(),Bitmap.Config.ARGB_8888);
//創(chuàng)建畫板
Canvas canvas=new Canvas(output);
//繪制整個畫板為透明
canvas.drawColor(Color.TRANSPARENT);
paint.setColor(Color.WHITE);
//繪制圓角圖片
if (type==ROUND){
canvas.drawRoundRect(new RectF(0, 0, getWidth(), getHeight()), mRound, mRound,paint);
}else{
//繪制圓形圖片
//取view寬高中的小值 盡量保證圖片內(nèi)容的顯示
int minValue = Math.min(getWidth(), getHeight());
//設置半徑
mRadius = minValue / 2;
canvas.drawCircle(mRadius,mRadius,mRadius,paint);
}
//設置圖形相交模式
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
Rect src=new Rect(0,0,bitmap.getWidth(),bitmap.getHeight());
Rect dst=new Rect(0,0,output.getWidth(),output.getHeight());
canvas.drawBitmap(bitmap,src,dst,paint);
return output;
}
return null;
}
這個特別經(jīng)典的圖......

PorterDuff.Mode.CLEAR 清除畫布上圖像 PorterDuff.Mode.SRC 顯示上層圖像 PorterDuff.Mode.DST 顯示下層圖像 PorterDuff.Mode.SRC_OVER上下層圖像都顯示,上層居上顯示 PorterDuff.Mode.DST_OVER 上下層都顯示,下層居上顯示 PorterDuff.Mode.SRC_IN 取兩層圖像交集部分只顯示上層圖像 PorterDuff.Mode.DST_IN 取兩層圖像交集部分,只顯示下層圖像 PorterDuff.Mode.SRC_OUT 取上層圖像非交集部分 PorterDuff.Mode.DST_OUT 取下層圖像非交集部分 PorterDuff.Mode.SRC_ATOP 取下層圖像非交集部分與上層圖像交集部分 PorterDuff.Mode.DST_ATOP 取上層圖像非交集部分與下層圖像交集部分 PorterDuff.Mode.XOR 取兩層圖像的非交集部分
參考文檔
繼承ImageVIew完成圓形和圓角圖片控件的實現(xiàn)過程(使用著色器)
<declare-styleable name="CircleImage">
<attr name="imageRound" format="dimension"/>
<attr name="imageType">
<enum name="circle" value="0"/>
<enum name="round" value="1"/>
</attr>
</declare-styleable>
public class CircleImage extends ImageView {
private Matrix matrix;
private Paint paint;
private int mRound;//圓角度數(shù)
private int mRadius;//圓的半徑
private int type;//控件類型
private final int CIRCLE=0;//圓形
private final int ROUND=1;//圓角
public CircleImage(Context context) {
super(context,null);
}
public CircleImage(Context context, AttributeSet attrs) {
super(context, attrs);
matrix=new Matrix();
paint=new Paint();
paint.setAntiAlias(true);
initAttrValues(context,attrs);
}
@Override
protected void onDraw(Canvas canvas) {
if (getDrawable() == null) {
return;
}
setShader();
if (type==CIRCLE){
canvas.drawCircle(mRadius, mRadius, mRadius, paint);
}else{
canvas.drawRoundRect(new RectF(0, 0, getWidth(), getHeight()), mRound, mRound,paint);
}
}
/**
* 初始化屬性集合
* @param context
* @param attrs
*/
private void initAttrValues(Context context, AttributeSet attrs){
TypedArray typedArray=context.obtainStyledAttributes(attrs, R.styleable.CircleImage);
for (int i=0;i<typedArray.getIndexCount();i++){
int index=typedArray.getIndex(i);
switch (index){
case R.styleable.CircleImage_imageRound:
mRound =typedArray.getDimensionPixelSize(index,
(int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,10,getResources().getDisplayMetrics()));
break;
case R.styleable.CircleImage_imageType:
type=typedArray.getInt(index,CIRCLE);
break;
}
}
}
/**
* 設置著色器
*/
private void setShader() {
//獲取Drawable
Drawable resources=getDrawable();
float scale = 1.0f;//縮放比例
if (resources instanceof BitmapDrawable) {
//獲取bitmap
Bitmap bitmap = ((BitmapDrawable) resources).getBitmap();
if (bitmap == null) return;
//圓形
if (type==CIRCLE){
// 獲取bitmap寬高中的小值
int minBitMap = Math.min(bitmap.getWidth(), bitmap.getHeight());
//取view寬高中的小值 盡量保證圖片內(nèi)容的顯示
int minValue = Math.min(getWidth(), getHeight());
//設置半徑
mRadius = minValue / 2;
//計算縮放比例 一定要*1.0f 因為int之間的計算結果會四舍五入0或1 效果就不美麗了
scale = minValue * 1.0f / minBitMap;
}else{
//比較view和圖片寬高比例大的 要讓縮放后的圖片大于view
scale = Math.max(getWidth() * 1.0f / bitmap.getWidth(), getHeight()
* 1.0f / bitmap.getHeight());
}
//設置縮放比例
matrix.setScale(scale, scale);
/**
* 創(chuàng)建著色器 設置著色模式
* TileMode的取值有三種:
* CLAMP 拉伸 REPEAT 重復 MIRROR 鏡像
*/
BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
//設置矩陣
shader.setLocalMatrix(matrix);
//設置著色
paint.setShader(shader);
}
}
/**
* 測試轉(zhuǎn)換效果 沒什么卵用 可以刪除
* @param event
* @return
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction()==MotionEvent.ACTION_DOWN){
if (type==CIRCLE){
mRound =10;
type=ROUND;
}else{
type=CIRCLE;
}
invalidate();
}
return super.onTouchEvent(event);
}
}
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Android實現(xiàn)簡易的柱狀圖和曲線圖表實例代碼
柱狀圖是統(tǒng)計圖表中經(jīng)常用到的一種圖表,比如降雨量之類的統(tǒng)計展示。這篇文章主要給大家介紹了關于利用Android如何實現(xiàn)簡易的柱狀圖和曲線圖表的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下。2017-12-12
Android Accessibility 輔助功能簡單介紹
這篇文章主要介紹了Android Accessibility 輔助功能簡單介紹的相關資料,文字轉(zhuǎn)語音,觸覺反饋,手勢操作,軌跡球和手柄操作,需要的朋友可以參考下2016-11-11
Android編程使用內(nèi)容提供者方式(ContentProvider)進行存儲的方法
這篇文章主要介紹了Android編程使用內(nèi)容提供者方式進行存儲的方法,涉及Android內(nèi)容提供者的創(chuàng)建,配置及針對數(shù)據(jù)的增刪改查等操作技巧,需要的朋友可以參考下2016-01-01
Android Studio導入Eclipse項目的兩種方法
本文主要介紹了Android Studio導入Eclipse項目的兩種方法。具有一定的參考價值,下面跟著小編一起來看下吧2017-01-01
activitygroup 切換動畫效果如何實現(xiàn)
本文將詳細介紹activitygroup 切換動畫效果實現(xiàn)過程,需要聊解的朋友可以參考下2012-12-12
Android通過AIDL在兩個APP之間Service通信
這篇文章主要為大家詳細介紹了Android通過AIDL在兩個APP之間Service通信,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-05-05
Android Compose Column列表不自動刷新問題
這篇文章主要介紹了Android Compose Column列表數(shù)據(jù)更新列表不刷新的問題,總的來說這并不是一道難題,那為什么要拿出這道題介紹?拿出這道題真正想要傳達的是解題的思路,以及不斷優(yōu)化探尋最優(yōu)解的過程。希望通過這道題能給你帶來一種解題優(yōu)化的思路2023-01-01
Android AIDL實現(xiàn)兩個APP間的跨進程通信實例
這篇文章主要為大家詳細介紹了Android AIDL實現(xiàn)兩個APP間的跨進程通信實例,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-04-04

