shader是啥?干嘛用的?
shader咋用? 举例 bitmapShader :
public class BitmapShaderView extends ImageView {
private Paint paint;
private Bitmap bitmap;
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() {
bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.cool);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
// BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
// BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR);
paint.setShader(bitmapShader);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
// canvas.drawRect(0, 0, bitmap.getWidth() * 2, bitmap.getHeight() * 2, paint);
canvas.drawRect(0, 0, getWidth(), getHeight(), paint);
}
}
shader的3种模式,效果如何?
mirror:
repeat:
clamp:
bitmapShader可以用来制作圆形图片和圆角图片:
bitmapShader可以改变bitmap的尺寸,如果bitmap图片尺寸较大,需要缩小尺寸的是bitmap,利用bitmapShader缩小bitmap。
bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.meifox);
BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR);
完整代码:
public class BitmapShaderView extends ImageView {
private Paint paint;
private Bitmap bitmap;
private float mRadius;
private int mWidth;
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() {
bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.meifox);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR);
paint.setShader(bitmapShader);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidth = Math.min(getMeasuredWidth(), getMeasuredHeight());
mRadius = mWidth / 2.0f;
setMeasuredDimension(mWidth, mWidth);
}
@Override
protected void onDraw(Canvas canvas) {
handleShader();
canvas.drawCircle(getWidth() / 2.0f, getHeight() / 2.0f, getWidth() / 2.0f, paint);
}
private void handleShader() {
bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.meifox);
int mBitWidth = Math.min(bitmap.getWidth(), bitmap.getHeight());
float scale = mWidth * 1.0f / mBitWidth;
Toast.makeText(getContext(), "" + scale, Toast.LENGTH_SHORT).show();
BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR);
Matrix localM = new Matrix();
localM.setScale(scale, scale);
bitmapShader.setLocalMatrix(localM);
paint.setShader(bitmapShader);
}
}
效果图: 圆形图片的下面是 原图(真实尺寸)
直接在bitmapShaderView里绘制外边框是行不通的。
分析:
bitmapShader是根据imageView的尺寸来显示的, 改变绘制半径是没有意义的。bitmapShader的目的就是为了填充整个imageView。只有改变imageView的尺寸 才能改变bitmapShader。
例如我把 绘制半径减小很多,绘制出的就是这样的。显然利用bitmapShader外面加圆环是做不到的,除非损失图片。
imageview的尺寸不改变,图片变小,只会在同一块画布上绘制重复的图片。 所以 妄想通过减小半径来加外边框,行不通。public class BitmapShaderView extends ImageView {
private Paint paint;
private Bitmap bitmap;
private float mRadius;
private int mWidth;
private Paint outPaint;
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() {
bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.meifox);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR);
paint.setShader(bitmapShader);
outPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
outPaint.setColor(Color.RED);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidth = Math.min(getMeasuredWidth(), getMeasuredHeight());
mRadius = mWidth / 2.0f;
setMeasuredDimension(mWidth, mWidth);
}
@Override
protected void onDraw(Canvas canvas) {
handleShader();
//画外圆
canvas.drawCircle(getWidth() / 2.0f, getHeight() / 2.0f, getWidth() / 2.0f, outPaint);
//画头像 参数一&参数二:圆心; 参数三: 半径; 参数四: 画笔。
canvas.drawCircle(getWidth() / 2.0f, getHeight() / 2.0f, getWidth() / 2.0f - 60, paint);
}
private void handleShader() {
bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.meifox);
int mBitWidth = Math.min(bitmap.getWidth(), bitmap.getHeight());
float scale = mWidth * 1.0f / mBitWidth;
Toast.makeText(getContext(), "" + scale, Toast.LENGTH_SHORT).show();
BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR);
Matrix localM = new Matrix();
localM.setScale(scale, scale);
bitmapShader.setLocalMatrix(localM);
paint.setShader(bitmapShader);
}
}
直接在bitmapShaderView里通过减小绘制半径来实现外边框,效果图如下:
bitmapShader以整个 imageView的尺寸作为画布。
总会有解决办法的:
在imageView外面包裹一层frameLayout,并利用shape给framelayout设置圆形背景。
shape: outborder.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#fff"></solid>
<size
android:width="1dp"
android:height="1dp"></size>
</shape>
布局:
<FrameLayout
android:background="@drawable/outborder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="1dp">
<com.adnonstop.bitmapshader.views.BitmapShaderView
android:id="@+id/id_iv_bitmap_shader"
android:layout_width="100dp"
android:layout_height="100dp"
app:outColor="#f000"
app:outSize="1dp" />
</FrameLayout>
效果图:
bitmapShaderView负责截取展示图片就好了:
public class BitmapShaderView extends ImageView {
private Paint paint;
private Bitmap bitmap;
private float mRadius;
private int mWidth;
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() {
bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.meifox);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR);
paint.setShader(bitmapShader);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidth = Math.min(getMeasuredWidth(), getMeasuredHeight());
mRadius = mWidth / 2.0f;
setMeasuredDimension(mWidth, mWidth);
}
@Override
protected void onDraw(Canvas canvas) {
handleShader();
//画头像
canvas.drawCircle(mRadius, mRadius, mRadius, paint);
}
private void handleShader() {
bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.meifox);
int mBitWidth = Math.min(bitmap.getWidth(), bitmap.getHeight());
float scale = mWidth * 1.0f / mBitWidth;
Toast.makeText(getContext(), "" + scale, Toast.LENGTH_SHORT).show();
BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR);
Matrix localM = new Matrix();
localM.setScale(scale, scale);
bitmapShader.setLocalMatrix(localM);
paint.setShader(bitmapShader);
}
}
绘制圆角:
效果图 :
代码 bitmapShaderViewRound.java
canvas.drawRoundRect
public class BitmapShaderViewRound extends ImageView {
private Paint paint;
private Bitmap bitmap;
private float mRadius;
private int mWidth;
public BitmapShaderViewRound(Context context) {
this(context, null);
}
public BitmapShaderViewRound(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public BitmapShaderViewRound(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initPaint();
}
private void initPaint() {
bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.meifox);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR);
paint.setShader(bitmapShader);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidth = Math.min(getMeasuredWidth(), getMeasuredHeight());
mRadius = mWidth / 2.0f;
setMeasuredDimension(mWidth, mWidth);
}
@Override
protected void onDraw(Canvas canvas) {
handleShader();
canvas.drawRoundRect(new RectF(0, 0, mWidth, mWidth), 30, 30, paint);
}
private void handleShader() {
bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.meifox);
int mBitWidth = Math.min(bitmap.getWidth(), bitmap.getHeight());
float scale = mWidth * 1.0f / mBitWidth;
Toast.makeText(getContext(), "" + scale, Toast.LENGTH_SHORT).show();
BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR);
Matrix localM = new Matrix();
localM.setScale(scale, scale);
bitmapShader.setLocalMatrix(localM);
paint.setShader(bitmapShader);
}
}