一、首先了解一下BitmapShader:
好了,本篇就先到这里吧,希望对各位正处在迷茫之中的小伙伴有所帮助
BitmapShader是Shader的子类,可以通过Paint.setShader(Shader shader)进行设置、
我们这里只关注BitmapShader,构造方法:
mBitmapShader = new BitmapShader(bitmap, TileMode.CLAMP, TileMode.CLAMP);
参数1:bitmap
参数2,参数3:TileMode:其取值有三种:1>CLAMP 拉伸 2>REPEAT 重复 3>MIRROR 镜像
二、首先来看一下效果:
三、下面进入编程阶段:
a.如果你是用的是Bitmap类型的图片,即你直接把图片放在了res/mipmap下,那么你就可以参考一下代码实现相应功能:
public class BitmapShaderView extends ImageView {
private float mRadius;
private int mWidth;
private Paint mPaint;
private Bitmap mBitmap;
public BitmapShaderView(Context context) {
this(context, null);
}
public BitmapShaderView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public BitmapShaderView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initPaint();
}
private void initPaint() {
mPaint = new Paint();
mPaint.setAntiAlias(true);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidth = Math.min(getMeasuredWidth(), getMeasuredHeight());
mRadius = mWidth * 1.0f / 2;
setMeasuredDimension(mWidth, mWidth);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
setBitmapShader();
canvas.drawCircle(mRadius, mRadius, mRadius, mPaint);
// canvas.drawCircle(mRadius,mRadius,mRadius-10.0f,mPaint);
//第二个参数rx:x方向上的圆角半径。第三个参数ry:y方向上的圆角半径。
// canvas.drawRoundRect(new RectF(0, 0, mWidth, mWidth), 30, 30, mPaint);
}
private void setBitmapShader() {
mBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.img10);
float mBitWidth = Math.min(mBitmap.getWidth(), mBitmap.getHeight());
Log.d("aaa", "mBitmap.getWidth() = " + mBitmap.getWidth());
Log.d("aaa", "mBitmap.getHeight() = " + mBitmap.getHeight());
BitmapShader mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
float scale = mWidth * 1.0f / mBitWidth;
Log.d("aaa", "scale = " + scale);
Matrix mMatrix = new Matrix();
mMatrix.setScale(scale, scale);
mBitmapShader.setLocalMatrix(mMatrix);
mPaint.setShader(mBitmapShader);
}
}
至于布局文件,那就很简单了 可以参考以下代码:
如此你就可以实现你梦寐以求的圆形图片了,怎么样简单吧!
当然有的同学可能会遇到下面这个问题 不解释直接看图:
没错 代码觉得没错,逻辑也没错 怎么就成了这个样子呢 真令人伤脑筋
不要着急,我也遇到了这个问题,所以特地记下来提醒一下自己。这个问题其实很简单就只是因为一行代码的事,原因就是我们忘记了注释掉onDraw里面的super.onDraw(canvas);这句话。只要像下面这样注释掉就可以了。
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageView;
/**
* Created by Administrator on 2017/2/17.
*/
public class BitmapShaderView extends ImageView {
private float mRadius;
private int mWidth;
private Paint mPaint;
private Bitmap mBitmap;
public BitmapShaderView(Context context) {
this(context, null);
}
public BitmapShaderView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public BitmapShaderView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initPaint();
}
private void initPaint() {
mPaint = new Paint();
mPaint.setAntiAlias(true);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidth = Math.min(getMeasuredWidth(), getMeasuredHeight());
mRadius = mWidth * 1.0f / 2;
setMeasuredDimension(mWidth, mWidth);
}
@Override
protected void onDraw(Canvas canvas) {
// super.onDraw(canvas);//务必注释掉
setBitmapShader();
canvas.drawCircle(mRadius, mRadius, mRadius, mPaint);
// canvas.drawCircle(mRadius,mRadius,mRadius-10.0f,mPaint);
//第二个参数rx:x方向上的圆角半径。第三个参数ry:y方向上的圆角半径。
// canvas.drawRoundRect(new RectF(0, 0, mWidth, mWidth), 30, 30, mPaint);
}
private void setBitmapShader() {
mBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.img10);
float mBitWidth = Math.min(mBitmap.getWidth(), mBitmap.getHeight());
Log.d("aaa", "mBitmap.getWidth() = " + mBitmap.getWidth());
Log.d("aaa", "mBitmap.getHeight() = " + mBitmap.getHeight());
BitmapShader mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
float scale = mWidth * 1.0f / mBitWidth;
Log.d("aaa", "scale = " + scale);
Matrix mMatrix = new Matrix();
mMatrix.setScale(scale, scale);
mBitmapShader.setLocalMatrix(mMatrix);
mPaint.setShader(mBitmapShader);
}
}
那么有的人又想把图片制成圆角的,又该怎么办呢?下面我们就来看一下 其实也很简单只要修改一行代码就可以。
当然先看效果图:
代码实现很简单 只需要在圆形代码的基础上修改一行代码即可
package com.example.circleimageview;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageView;
/**
* Created by Administrator on 2017/2/17.
*/
public class BitmapShaderView extends ImageView {
private float mRadius;
private int mWidth;
private Paint mPaint;
private Bitmap mBitmap;
public BitmapShaderView(Context context) {
this(context, null);
}
public BitmapShaderView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public BitmapShaderView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initPaint();
}
private void initPaint() {
mPaint = new Paint();
mPaint.setAntiAlias(true);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidth = Math.min(getMeasuredWidth(), getMeasuredHeight());
mRadius = mWidth * 1.0f / 2;
setMeasuredDimension(mWidth, mWidth);
}
@Override
protected void onDraw(Canvas canvas) {
// super.onDraw(canvas);//务必注释掉
setBitmapShader();
// canvas.drawCircle(mRadius, mRadius, mRadius, mPaint);
// canvas.drawCircle(mRadius,mRadius,mRadius-10.0f,mPaint);
//第二个参数rx:x方向上的圆角半径。第三个参数ry:y方向上的圆角半径。
canvas.drawRoundRect(new RectF(0, 0, mWidth, mWidth), 30, 30, mPaint);
}
private void setBitmapShader() {
mBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.img10);
float mBitWidth = Math.min(mBitmap.getWidth(), mBitmap.getHeight());
Log.d("aaa", "mBitmap.getWidth() = " + mBitmap.getWidth());
Log.d("aaa", "mBitmap.getHeight() = " + mBitmap.getHeight());
BitmapShader mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
float scale = mWidth * 1.0f / mBitWidth;
Log.d("aaa", "scale = " + scale);
Matrix mMatrix = new Matrix();
mMatrix.setScale(scale, scale);
mBitmapShader.setLocalMatrix(mMatrix);
mPaint.setShader(mBitmapShader);
}
}
这么神奇嘛!哈哈,没错,相信自己的眼睛就是这么神奇!
b.
.那么如果有的人就非得用Drawable类型的图片呢,即你直接把图片放在了res/drawable下,那么也没关系,你可以参考一下代码实现相应功能:
package com.example.circleimageview;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageView;
/**
* Created by Administrator on 2017/2/17.
*/
public class BitmapShaderView extends ImageView {
private float mRadius;
private int mWidth;
private Paint mPaint;
private Bitmap mBitmap;
public BitmapShaderView(Context context) {
this(context, null);
}
public BitmapShaderView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public BitmapShaderView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initPaint();
}
private void initPaint() {
mPaint = new Paint();
mPaint.setAntiAlias(true);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidth = Math.min(getMeasuredWidth(), getMeasuredHeight());
mRadius = mWidth * 1.0f / 2;
setMeasuredDimension(mWidth, mWidth);
}
@Override
protected void onDraw(Canvas canvas) {
setBitmapShader();
canvas.drawCircle(mRadius, mRadius, mRadius, mPaint);
// canvas.drawCircle(mRadius,mRadius,mRadius-10.0f,mPaint);
//第二个参数rx:x方向上的圆角半径。第三个参数ry:y方向上的圆角半径。
// canvas.drawRoundRect(new RectF(0, 0, mWidth, mWidth), 30, 30, mPaint);
}
private Bitmap DrawableToBitmap(Drawable drawable) {
//首先明白instanceof是一种运算符是用来在运行时指出对象是否是特定类的一个实例。例如:result = object instanceof class 主要判断前面是否是后面的一个实例 如果 object 是 class 的一个实例,则 instanceof 运算符返回 true。如果 object 不是指定类的一个实例,或者 object 是 null,则返回 false。
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
return bitmapDrawable.getBitmap();
}
int w = drawable.getIntrinsicWidth();
int h = drawable.getIntrinsicHeight();
// ARGB指的是一种 色彩模式,里面A代表Alpha,R表示red,G表示green,B表示blue. ARGB_8888就是由4个8位组成即32位 ,代表32位ARGB位图.
Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, w, h);
drawable.draw(canvas);
return bitmap;
}
private void setBitmapShader() {
Drawable drawable = getDrawable();
if (null == drawable) {
return;
} else {
//首先获取到bitmap类型的图片
Bitmap bitmap = DrawableToBitmap(drawable);
//构造渲染器BitmapShader TileMode的取值有三种:CLAMP 拉伸 REPEAT 重复 MIRROR 镜像
BitmapShader mBitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
int mBitWidth = Math.min(bitmap.getWidth(), bitmap.getHeight());
float scale = mWidth * 1.0f / mBitWidth;
// shader的变换矩阵,我们这里主要用于放大或者缩小
Matrix mMatrix = new Matrix();
mMatrix.setScale(scale, scale);
mBitmapShader.setLocalMatrix(mMatrix);
mPaint.setShader(mBitmapShader);
}
}
}