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.