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

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

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);
    }
}




目录
相关文章
|
11天前
|
安全 算法 小程序
【03】微信支付商户申请下户到配置完整流程-微信开放平台创建APP应用-填写上传基础资料-生成安卓证书-获取Apk签名-申请+配置完整流程-优雅草卓伊凡
【03】微信支付商户申请下户到配置完整流程-微信开放平台创建APP应用-填写上传基础资料-生成安卓证书-获取Apk签名-申请+配置完整流程-优雅草卓伊凡
71 28
【03】微信支付商户申请下户到配置完整流程-微信开放平台创建APP应用-填写上传基础资料-生成安卓证书-获取Apk签名-申请+配置完整流程-优雅草卓伊凡
|
4月前
|
存储 XML 开发工具
探索安卓应用开发:从基础到进阶
在这篇文章中,我们将一起踏上安卓应用开发的旅程。不论你是编程新手还是希望提升技能的开发者,这里都有你需要的东西。我们会从最基础的概念开始,逐步深入到更复杂的主题。文章将涵盖开发环境设置、用户界面设计、数据处理以及性能优化等方面。通过理论与实践的结合,你将能够构建出既美观又高效的安卓应用。让我们一起开启这段技术之旅吧!
|
4月前
|
Android开发 Swift iOS开发
深入探索iOS与Android操作系统的架构差异及其对应用开发的影响
在当今数字化时代,移动设备已经成为我们日常生活和工作不可或缺的一部分。其中,iOS和Android作为全球最流行的两大移动操作系统,各自拥有独特的系统架构和设计理念。本文将深入探讨iOS与Android的系统架构差异,并分析这些差异如何影响应用开发者的开发策略和用户体验设计。通过对两者的比较,我们可以更好地理解它们各自的优势和局限性,从而为开发者提供有价值的见解,帮助他们在这两个平台上开发出更高效、更符合用户需求的应用。
|
1月前
|
前端开发 Java Shell
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
182 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
1月前
|
Dart 前端开发 Android开发
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
58 4
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
2月前
|
缓存 前端开发 Android开发
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
117 12
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
|
2月前
|
Dart 前端开发 Android开发
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
46 1
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
2月前
|
测试技术 Android开发 开发者
【03】优雅草央千澈详解关于APP签名以及分发-上架完整流程-第三篇安卓APP上架华为商店后面的步骤-华为应用商店相对比较麻烦一些-华为商店安卓上架
【03】优雅草央千澈详解关于APP签名以及分发-上架完整流程-第三篇安卓APP上架华为商店后面的步骤-华为应用商店相对比较麻烦一些-华为商店安卓上架
62 16
|
3月前
|
搜索推荐 Android开发 开发者
安卓应用开发中的自定义控件实践
在安卓应用开发的广阔天地中,自定义控件如同璀璨的星辰,点亮了用户界面设计的夜空。它们不仅丰富了交互体验,更赋予了应用独特的个性。本文将带你领略自定义控件的魅力,从基础概念到实际应用,一步步揭示其背后的原理与技术细节。我们将通过一个简单的例子——打造一个具有独特动画效果的按钮,来展现自定义控件的强大功能和灵活性。无论你是初学者还是资深开发者,这篇文章都将为你打开一扇通往更高阶UI设计的大门。
|
4月前
|
缓存 监控 前端开发
探索Android应用开发之旅:从新手到专家
【10月更文挑战第42天】本文将带你踏上Android应用开发的旅程,无论你是初学者还是有经验的开发者。我们将一起探索如何从零开始创建你的第一个Android应用,并逐步深入到更高级的主题,如自定义视图、网络编程和性能优化。通过实际示例和清晰的解释,你将学会如何构建高效、吸引人的Android应用。让我们一起开启这段激动人心的旅程吧!

热门文章

最新文章