1. 位图渲染 BitmapShader 简介
( 1 ) 位图渲染综述 ( ① 三种方式 : Shader.TileMode.CLAMP | Shader.TileMode.REPEAT | Shader.TileMode.MIRROR | ② 流程 : 创建 Shader | 设置 Shader 到 Paint | 打开抗锯齿 | 绘制矩形 )
位图渲染 :
1.主要实现的功能 : 位图渲染就是 将一个位图, 通过特定的方式绘制到指定的矩形区域中, 解决 Bitmap 位图的宽高 与 绘制区域宽高 不一致时如何进行渲染 的 问题;
2.渲染流程 :
① 创建 BitmapShader
② 为 Paint 设置 着色器 Shader
③ 打开抗锯齿
④ 绘制一个矩形区域
3.创建 BitmapShader : 调用 BitmapShader 构造方法创建着色器, 同时 设置 位图引用, 和 绘制位图时 的 X 和 Y 方向的拉伸方式 , 位图的 拉伸方式 在后面有介绍 , 下面是三个参数说明 :
① Bitmap bitmap 参数 : 渲染所用的位图 ;
② TileMode tileX 参数 : 设置绘制位图时的 x 方向的拉伸方式 ;
③ TileMode tileY : 设置绘制位图时的 y 方向的拉伸方式 ;
/** * 调用该构造函数创建一个新的着色器, 用于绘制位图 * * @param bitmap 将要绘制的位图 * @param tileX 设置绘制位图时的 x 方向的拉伸方式 * @param tileY 设置绘制位图时的 y 方向的拉伸方式 */ public BitmapShader(@NonNull Bitmap bitmap, @NonNull TileMode tileX, @NonNull TileMode tileY) { this(bitmap, tileX.nativeInt, tileY.nativeInt); }
4.三种位图的拉伸方式 :
① Shader.TileMode.CLAMP : 如果绘制的位置超出了图像的边界, 那么超出部分 使用最后一个像素的颜色值绘制 ;
② Shader.TileMode.REPEAT : 绘图位置超出了边界, 使用 同样的位图进行平铺 剩余绘制的部分;
③ Shader.TileMode.MIRROR : 绘图位置超出了边界, 使用 位图反转镜像 平铺剩余绘制部分;
public class Shader { ... public enum TileMode { /** * replicate the edge color if the shader draws outside of its * original bounds */ CLAMP (0), /** * repeat the shader's image horizontally and vertically */ REPEAT (1), /** * repeat the shader's image horizontally and vertically, alternating * mirror images so that adjacent images always seam */ MIRROR (2); TileMode(int nativeInt) { this.nativeInt = nativeInt; } final int nativeInt; } ... }
5.为 画笔 设置 着色器 : 调用 Paint 对象 的 setShader 方法为 画笔设置 着色器;
6.打开抗锯齿 : 调用 Paint 对象的 setAntiAlias 方法, 打开抗锯齿, 这样 位图的边界会更平滑, paint.setAntiAlias(true) ;
7.绘制矩形 : 调用 Canvas 的 drawRect 的方法, 绘制矩形, 位图在该矩形中绘制; canvas.drawRect(new Rect(0,0 , 100, 100),mPaint); ;
8.使用示例 : 下面是位图渲染 的简单示例;
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.WHITE); Paint mPaint = new Paint(); Bitmap mBitmap = ((BitmapDrawable)getResources() .getDrawable(R.mipmap.aodesai)).getBitmap(); //1. 创建位图渲染对象, 并设置拉伸方式, 此处设置Shader.TileMode.CLAMP, // 如果绘制的位置超出了图像的边界, 那么超出部分 使用最后一个像素的颜色值绘制 BitmapShader bitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); //2. 设置渲染到 Paint 对象 mPaint.setShader(bitmapShader); //3. 打开抗锯齿 mPaint.setAntiAlias(true); //4. 绘制指定的矩形区域 canvas.drawRect(0, 0, getWidth(), getHeight(), mPaint); }
2. 位图渲染 BitmapShader 三种参数 及 代码示例
( 1 ) 位图渲染 CLAMP 拉伸 代码示例 及 效果 ( 绘制超出图片边界时, 就会绘制 水平 或 垂直方向 上最后一个像素, 填充剩余的位置 )
CLAMP 拉伸 :
1.CLAMP 说明 : 在创建 BitmapShader 的时候, 设置其 水平 和 垂直方向的 拉伸方式为 Shader.TileMode.CLAMP , 则在绘制超出图片边界时, 就会绘制 水平 或 垂直方向 上最后一个像素, 填充剩余的位置 ;
2.展示效果 :
2.代码示例 :
package com.hanshuliang.shader.widget; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.ComposeShader; import android.graphics.LinearGradient; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.Shader; import android.graphics.drawable.BitmapDrawable; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.view.View; import com.hanshuliang.shader.R; public class PaintBitmapShaderClamp extends View { public PaintBitmapShaderClamp(Context context) { super(context); } public PaintBitmapShaderClamp(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } public PaintBitmapShaderClamp(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.WHITE); Paint mPaint = new Paint(); Bitmap mBitmap = ((BitmapDrawable)getResources() .getDrawable(R.mipmap.aodesai)).getBitmap(); //1. 创建位图渲染对象, 并设置拉伸方式, 此处设置Shader.TileMode.CLAMP, // 如果绘制的位置超出了图像的边界, 那么超出部分 使用最后一个像素的颜色值绘制 BitmapShader bitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); //2. 设置渲染到 Paint 对象 mPaint.setShader(bitmapShader); //3. 打开抗锯齿 mPaint.setAntiAlias(true); //4. 绘制指定的矩形区域 canvas.drawRect(0, 0, getWidth(), getHeight(), mPaint); } }