前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Android 应用开发】Paint 渲染 之 BitmapShader 位图渲染 ( 渲染流程 | CLAMP 拉伸最后像素 | REPEAT 重复绘制图片 | MIRROR 绘制反向图片 )

【Android 应用开发】Paint 渲染 之 BitmapShader 位图渲染 ( 渲染流程 | CLAMP 拉伸最后像素 | REPEAT 重复绘制图片 | MIRROR 绘制反向图片 )

作者头像
韩曙亮
发布2023-03-27 16:11:53
1.6K0
发布2023-03-27 16:11:53
举报
文章被收录于专栏:韩曙亮的移动开发专栏

文章目录

相关代码地址 :

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 方向的拉伸方式 ;
代码语言:javascript
复制
    /**
     * 调用该构造函数创建一个新的着色器, 用于绘制位图
     *
     * @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 : 绘图位置超出了边界, 使用 位图反转镜像 平铺剩余绘制部分;
    在这里插入图片描述
    在这里插入图片描述
代码语言:javascript
复制
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.使用示例 : 下面是位图渲染 的简单示例;
代码语言:javascript
复制
    @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.代码示例 :
代码语言:javascript
复制
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);
    }
}

( 2 ) 位图渲染 REPEAT 拉伸 代码示例 及 效果 ( 绘制超出图片边界时, 就会绘制 同样的图片 填充剩余部分 )

REPEAT 拉伸 :

  • 1.REPEAT 说明 : 在创建 BitmapShader 的时候, 设置其 水平 和 垂直方向的 拉伸方式为 Shader.TileMode.REPEAT , 则在绘制超出图片边界时, 就会绘制 同样的图片 填充剩余部分 ;
  • 2.展示效果 :
在这里插入图片描述
在这里插入图片描述
  • 2.代码示例 :
代码语言:javascript
复制
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.Paint;
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 PaintBitmapShaderRepeat extends View {

    public PaintBitmapShaderRepeat(Context context) {
        super(context);
    }

    public PaintBitmapShaderRepeat(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public PaintBitmapShaderRepeat(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.REPEAT, Shader.TileMode.REPEAT);

        //2. 设置渲染到 Paint 对象
        mPaint.setShader(bitmapShader);

        //3. 打开抗锯齿
        mPaint.setAntiAlias(true);

        //4. 绘制指定的矩形区域
        canvas.drawRect(0, 0, getWidth(), getHeight(), mPaint);
    }
}

( 3 ) 位图渲染 MIRROR 拉伸 代码示例 及 效果 ( 在垂直和水平方向绘制图片的对应方向的反向图片 )

MIRROR 拉伸 :

  • 1.MIRROR 说明 : 在创建 BitmapShader 的时候, 设置其 水平 和 垂直方向的 拉伸方式为 Shader.TileMode.MIRROR , 则在绘制超出图片边界时, 就会绘制 图片的 镜像翻转方式 铺满剩余部分;
  • 2.展示效果 :
在这里插入图片描述
在这里插入图片描述
  • 2.代码示例 :
代码语言:javascript
复制
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.Paint;
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 PaintBitmapShaderMirror extends View {

    public PaintBitmapShaderMirror(Context context) {
        super(context);
    }

    public PaintBitmapShaderMirror(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public PaintBitmapShaderMirror(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.MIRROR, Shader.TileMode.MIRROR);

        //2. 设置渲染到 Paint 对象
        mPaint.setShader(bitmapShader);

        //3. 打开抗锯齿
        mPaint.setAntiAlias(true);

        //4. 绘制指定的矩形区域
        canvas.drawRect(0, 0, getWidth(), getHeight(), mPaint);
    }
}

相关代码地址 :

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-06-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 1. 位图渲染 BitmapShader 简介
    • ( 1 ) 位图渲染综述 ( ① 三种方式 : Shader.TileMode.CLAMP | Shader.TileMode.REPEAT | Shader.TileMode.MIRROR | ② 流程 : 创建 Shader | 设置 Shader 到 Paint | 打开抗锯齿 | 绘制矩形 )
    • 2. 位图渲染 BitmapShader 三种参数 及 代码示例
      • ( 1 ) 位图渲染 CLAMP 拉伸 代码示例 及 效果 ( 绘制超出图片边界时, 就会绘制 水平 或 垂直方向 上最后一个像素, 填充剩余的位置 )
        • ( 2 ) 位图渲染 REPEAT 拉伸 代码示例 及 效果 ( 绘制超出图片边界时, 就会绘制 同样的图片 填充剩余部分 )
          • ( 3 ) 位图渲染 MIRROR 拉伸 代码示例 及 效果 ( 在垂直和水平方向绘制图片的对应方向的反向图片 )
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档