android繪制圓形圖片的兩種方式示例
android繪制圓形圖片的兩種方式
看下效果先
下面有完整的示例代碼
使用BitmapShader(著色器)
我們?cè)诶L制view 的時(shí)候 就是小學(xué)上美術(shù)課 用水彩筆在本子上畫畫 使用著色器繪制圓形圖片最簡單的理解方式 就是把bitmap當(dāng)做一種顏色 設(shè)置給paint ,paint都已經(jīng)有顏色了 你想讓它方了,圓了,扁了 還不是看你心情 canvas調(diào)用那個(gè)方法咯
實(shí)現(xiàn)的大致思路如下:
1. 創(chuàng)建一個(gè)類 繼承imageView 重寫onDraw()
2. 獲取到bitmap圖片
3. 計(jì)算圖片的縮放比例 使用矩陣matrix 進(jìn)行縮放
4. 創(chuàng)建BitmapShader著色器 設(shè)置縮放矩陣
5. paint設(shè)置著色器 繪制
具體實(shí)現(xiàn) 注釋也標(biāo)注的很清楚
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()); //設(shè)置半徑 mRadius=minValue/2; //計(jì)算縮放比例 一定要*1.0f 因?yàn)閕nt之間的計(jì)算結(jié)果會(huì)四舍五入0或1 效果就不美麗了 scale=minValue*1.0f/minBitMap; //設(shè)置縮放比例 matrix.setScale(scale,scale); /** * 創(chuàng)建著色器 設(shè)置著色模式 * TileMode的取值有三種: * CLAMP 拉伸 REPEAT 重復(fù) MIRROR 鏡像 */ BitmapShader shader=new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); //設(shè)置矩陣 shader.setLocalMatrix(matrix); paint.setShader(shader); canvas.drawCircle(mRadius, mRadius, mRadius, paint); } }
使用Xfermode 設(shè)置圖片相交模式
簡單說呢 在一張畫布上畫了兩張圖片 這兩張圖的以怎樣的方式顯示出來 例如:只顯示上層圖片,只顯示下層圖片 ,顯示兩張圖的交集部分 等等等
實(shí)現(xiàn)思路
1.創(chuàng)建一個(gè)空bitmap 根據(jù)這個(gè)bitmap創(chuàng)建一個(gè)Canvas
2.設(shè)置Canvas透明 畫一個(gè)想要實(shí)現(xiàn)的形狀
3.設(shè)置圖形相交模式
4.獲取圖片資源 繪制到Canvas
實(shí)現(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); //繪制整個(gè)畫板為透明 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()); //設(shè)置半徑 mRadius = minValue / 2; canvas.drawCircle(mRadius,mRadius,mRadius,paint); } //設(shè)置圖形相交模式 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; }
這個(gè)特別經(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完成圓形和圓角圖片控件的實(shí)現(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; } } } /** * 設(shè)置著色器 */ 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()); //設(shè)置半徑 mRadius = minValue / 2; //計(jì)算縮放比例 一定要*1.0f 因?yàn)閕nt之間的計(jì)算結(jié)果會(huì)四舍五入0或1 效果就不美麗了 scale = minValue * 1.0f / minBitMap; }else{ //比較view和圖片寬高比例大的 要讓縮放后的圖片大于view scale = Math.max(getWidth() * 1.0f / bitmap.getWidth(), getHeight() * 1.0f / bitmap.getHeight()); } //設(shè)置縮放比例 matrix.setScale(scale, scale); /** * 創(chuàng)建著色器 設(shè)置著色模式 * TileMode的取值有三種: * CLAMP 拉伸 REPEAT 重復(fù) MIRROR 鏡像 */ BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); //設(shè)置矩陣 shader.setLocalMatrix(matrix); //設(shè)置著色 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)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android裁剪圖片為圓形圖片的實(shí)現(xiàn)原理與代碼
- Android中Glide加載圓形圖片和圓角圖片實(shí)例代碼
- Android實(shí)現(xiàn)圓形圖片的兩種方式
- 詳解Android中Glide與CircleImageView加載圓形圖片的問題
- 分享一個(gè)Android設(shè)置圓形圖片的特別方法
- Android編程繪制圓形圖片的方法
- Android自定義View實(shí)現(xiàn)旋轉(zhuǎn)的圓形圖片
- Android實(shí)現(xiàn)圓形圖片或者圓角圖片
- Android使用自定義ImageView實(shí)現(xiàn)圓形圖片效果
- Android實(shí)現(xiàn)圓形圖片效果
相關(guān)文章
Android實(shí)現(xiàn)從相冊(cè)截圖的功能
這篇文章主要介紹了Android實(shí)現(xiàn)從相冊(cè)截圖的功能,簡單介紹了Android實(shí)現(xiàn)從相冊(cè)截圖功能的步驟,供大家參考,感興趣的小伙伴們可以參考一下2016-01-01Android的TextView與Html相結(jié)合的具體方法
Android的TextView與Html相結(jié)合的具體方法,需要的朋友可以參考一下2013-06-06Android6.0獲取動(dòng)態(tài)權(quán)限代碼示例
這篇文章主要介紹了Android6.0以上獲取動(dòng)態(tài)權(quán)限代碼示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11Android使用 Coroutine + Retrofit打造簡單的HTTP請(qǐng)求庫
這篇文章主要介紹了Android使用 Coroutine + Retrofit打造簡單的HTTP請(qǐng)求庫,幫助大家更好的理解和學(xué)習(xí)使用Android,感興趣的朋友可以了解下2021-03-03android基礎(chǔ)教程之開機(jī)啟動(dòng)示例
這篇文章主要介紹了android開機(jī)啟動(dòng)示例,開機(jī)自動(dòng)啟動(dòng)程序后開機(jī)啟動(dòng)廣播功能實(shí)現(xiàn),需要的朋友可以參考下2014-02-02Android Wear計(jì)時(shí)器開發(fā)
這篇文章主要介紹了Android Wear計(jì)時(shí)器開發(fā),需要的朋友可以參考下2014-11-11Android 動(dòng)態(tài)改變布局實(shí)例詳解
這篇文章主要介紹了Android 動(dòng)態(tài)改變布局實(shí)例詳解的相關(guān)資料,這里舉例說明如何實(shí)現(xiàn)動(dòng)態(tài)改變布局的例子,幫助大家學(xué)習(xí)理解,需要的朋友可以參考下2016-11-11Android 讀取sdcard上的圖片實(shí)例(必看)
下面小編就為大家?guī)硪黄狝ndroid 讀取sdcard上的圖片實(shí)例(必看)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-03-03