Android Paint Shader 图像渲染

前面章节介绍 Paint 时有提到 Shader 包含了一个 setShader(Shader s ) 的方法,该方法用于控制 画笔 的渲染效果

Shader 使得我们不仅可以用颜色来填充图形,还可以使用 Shader 指定的渲染效果来填充图形

Shader 是一个抽象类,但它有以下几个实现类

类 说明
BitmapShader 使用位图平铺的渲染效果
LinearGradient 使用线性渐变来填充图形
RadialGradient 使用圆形渐变来填充图形
SweepGradient 使用角度渐变来填充图形
ComposeShader 使用组合渲染效果来填充图形

BitmapShader() 使用位图平铺的渲染效果

使用一张位图作为纹理来对某一区域进行填充

BitmapShader(Bitmap bitmap, Shader.TileMode tileX, Shader.TileMode tileY)

参数说明

参数 说明
bitmap 用来作为填充的位图
tileX X 轴方向上位图的衔接形式
tileY Y 轴方向上位图的衔接形式

而这个 Shader.TileMode 有三种

枚举常量 说明
CLAMP 就是如果渲染器超出原始边界范围,则会复制边缘颜色对超出范围的区域进行着色
REPEAT 则是平铺形式重复渲染
MIRROR 则是在横向和纵向上以镜像的方式重复渲染位图。

ComposeShader() 使用组合渲染效果来填充图形

渲染效果的叠加,比如将 BitmapShader 与 LinearGradient 的混合渲染 效果等

ComposeShader(Shader shaderA, Shader shaderB, PorterDuff.Mode mode);

参数说明

参数 说明
shaderA 第一种渲染效果
shaderB 第二种渲染效果
mode 两种渲染效果的叠加模式

LinearGradient() 使用线性渐变来填充图形

实现某一区域内颜色的线性渐变效果

LinearGradient(float x0, float y0, float x1, float y1, int[] colors, float[] positions, Shader.TileMode tile);

参数说明

参数 说明
x0 渐变的起始点 x 坐标
y0 渐变的起始点 y 坐标
x1 渐变的终点 x 坐标
y1 渐变的终点 y 坐标
colors 渐变的颜色数组
positions 颜色数组的相对位置
tile 平铺方式

RadialGradient() 使用圆形渐变来填充图形

实现某一区域内颜色的环形渐变效果

public RadialGradient (float x, float y, float radius, int[] colors, float[] positions, Shader.TileMode tile);

参数说明

参数 说明
x 环形的圆心 x 坐标
y 环形的圆心 y 坐标
radius 环形的半径
colors 环形渐变的颜色数组
positions 指定颜色数组的相对位置
tile 平铺方式

SweepGradient() 使用组合渲染效果来填充图形

扫描渲染,就是以某个点位中心旋转一周所形成的效果

public SweepGradient (float cx, float cy, int[] colors, float[] positions)

参数说明

参数 说明
cx 扫描的中心x坐标
cy 扫描的中心y坐标
colors 梯度渐变的颜色数组
positions 指定颜色数组的相对位置

范例

  1. 创建一个 空的 Android 项目 cn.twle.android.Shader

  2. 下载 /static/i/android/avatar_128x128.png 并放到 res/drawable 目录

  3. 自定义一个 View 类 MsView.java

    package cn.twle.android.shader;
    
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    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.RadialGradient;
    import android.graphics.Shader;
    import android.graphics.SweepGradient;
    import android.graphics.drawable.ShapeDrawable;
    import android.graphics.drawable.shapes.OvalShape;
    import android.util.AttributeSet;
    import android.view.View;
    
    public class MsView extends View {
    
        private Bitmap mBitmap = null;
        private ShapeDrawable sDrawable = null;
        private Paint mPaint = null;
        private int bitW = 0, bitH = 0;     //Bitmap宽高
    
        private Shader mBitmapShader = null;   //Bitmap渲染
        private Shader mLinearGradient = null; //线性渐变渲染
        private Shader mComposeShader = null; //混合渲染
        private Shader mRadialGradient = null; //环形渐变渲染
        private Shader mSweepGradient = null; //梯度渲染
    
        public MsView(Context context) {
            this(context, null);
        }
    
        public MsView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        public BitmapShaderView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        private void init() {
    
            mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.avatar_128x128);
            bitW = mBitmap.getWidth();
            bitH = mBitmap.getHeight();
            mPaint = new Paint();
    
            //创建BitmapShader
            mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR);
    
            //创建LinearGradient并设置渐变的颜色数组
            mLinearGradient = new LinearGradient(0, 0, 100, 100,
                    new int[]{Color.RED, Color.GREEN, Color.BLUE, Color.WHITE},
                    null, Shader.TileMode.REPEAT);
    
            //混合渲染,这里使用了BitmapShader和LinearGradient进行混合,可以试试其他~
            mComposeShader = new ComposeShader(mBitmapShader, mLinearGradient, PorterDuff.Mode.DARKEN);
    
            //环形渐变渲染
            mRadialGradient = new RadialGradient(50, 200, 50,
                    new int[]{Color.GREEN, Color.RED, Color.BLUE, Color.WHITE},
                    null, Shader.TileMode.REPEAT);
    
            //梯度渲染
            mSweepGradient = new SweepGradient(30, 30, new int[]{Color.GREEN, Color.RED,
                    Color.BLUE, Color.WHITE}, null);
    
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
            //将图片裁剪为椭圆形
            sDrawable = new ShapeDrawable(new OvalShape());
            sDrawable.getPaint().setShader(mBitmapShader);
            sDrawable.setBounds(0, 0, bitW, bitH);
            sDrawable.draw(canvas);
    
            //绘制线性渐变的矩形
            mPaint.setShader(mLinearGradient);
            canvas.drawRect(bitW, 0, bitW * 2, bitH, mPaint);
    
            //绘制混合渲染效果
            mPaint.setShader(mComposeShader);
            canvas.drawRect(0, bitH, bitW , bitH * 2, mPaint);
    
            //绘制环形渐变
            mPaint.setShader(mRadialGradient);
            canvas.drawCircle(bitW * 2.8f, bitH / 2, bitH / 2, mPaint);
    
            //绘制梯度渐变
            mPaint.setShader(mSweepGradient);
            canvas.drawRect(bitW, bitH, bitW * 2, bitH * 2, mPaint);
    
        }
    }
    
  4. 修改 MainActivity.java 设置 setContentView(new MsView(MainActivity.this))

    package cn.twle.android.shader;
    
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(new MsView(MainActivity.this));
        }
    }
    

Android 基础教程

关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

♥   简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.