美文网首页Android专题
Android之高级渲染Shader

Android之高级渲染Shader

作者: NoBugException | 来源:发表于2019-03-16 21:48 被阅读118次

    Shader可分为5种,分别是BitmapShader(位图图像渲染)、LinearGradient(线性渲染)、SweepGradient(渐变渲染/梯度渲染)、RadialGradient(环形渲染)、ComposeShader(组合渲染)

    (1)BitmapShader:位图图像渲染

    BitmapShader作用于Bitmap,用Bitmap对绘制的图形进行渲染。
    就以这个图片为例

    pic.jpg

    构造函数中需要传入图片的拉升模式TileMode,同时设置不同TileMode会展示的效果。

    BitmapShader(Bitmap bitmap, TileMode tileX, TileMode tileY)
    

    BitmapShader构造方法有三个参数,第一个参数是bitmap图像,第二个参数是x方向拉伸方式,第三个参数是y方向拉伸方式。

    代码如下

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mBitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.pic);
    
        mShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        //调用Paint的setShader(Shader shader)方法设置BitmapShader
        mPaint.setShader(mShader);
    
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int width = getWidth() * 2 / 3;
        int height = getHeight() / 2; //使用设置了Shader的Paint进行绘制
        canvas.drawRect(0,0,width,height,mPaint);
    }
    

    随着修改拉伸方式,图像所展示的效果不同

    • TileMode.CLAMP:拉伸最后一个像素铺满。
    图片.png
    • TileMode.MIRROR:镜像平铺


      图片.png
    • TileMode.REPEAT:重复平铺

    图片.png

    在现实项目中,往往我们会接到绘制圆形头像之类的需求,那么我们可以使用BitmapShader来实现

    代码如下:

        mBitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.pic);
        BitmapShader bitmapShader = new BitmapShader(mBitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
        mPaint.setShader(bitmapShader);
    
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int radius = Math.min(mBitmap.getWidth(), mBitmap.getHeight()) / 2;
    
        canvas.drawCircle(radius, radius, radius, mPaint);
    
        RectF rectf = new RectF();
        rectf.left = 0;
        rectf.top = radius * 3;
        rectf.right = mBitmap.getWidth() / 2;
        rectf.bottom = radius * 3 + mBitmap.getHeight();
        canvas.drawOval(rectf, mPaint);
    }
    

    效果如下:

    图片.png

    最后请关注下已经写好的圆形图像类:
    圆形图片工具

    (2)LinearGradient:线性渲染

    它的渲染方式是线性的,顾名思义就是沿着一条线段进行渲染

    LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1, TileMode tile)
    LinearGradient(float x0, float y0, float x1, float y1, int[] colors, float[] positions, TileMode tile)
    

    前四个参数是确定线段的两点位置,后面分别是颜色、位置、拉伸模式。

    代码如下

    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    LinearGradient mLinearGradient = new LinearGradient(0,300,300,300,new int[]{Color.RED,Color.BLUE,Color.RED,Color.BLUE},new float[]{0f, 0.3f, 0.6f, 0.7f}, Shader.TileMode.CLAMP);
    mPaint.setShader(mLinearGradient);
    
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawRect(0,0,300,300,mPaint);
    }
    

    效果如下

    图片.png

    其中大致位置我已经标出

    图片.png

    (3)SweepGradient:渐变渲染/梯度渲染

    它是以某个基准点开始,360度向周围渐变的渲染机制(类似于雷达、钟表)

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

    前两个参数是某个点, 后面参数分别是颜色、位置。

    代码如下

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        SweepGradient mSweepGradient = new SweepGradient(250, 250, new int[]{Color.GREEN, Color.YELLOW, Color.RED, Color.BLACK}, new float[]{0.0f,0.5f,0.8f,1f});
        mPaint.setShader(mSweepGradient);
    
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawCircle(250, 250, 250, mPaint);
    }
    

    效果如下:

    图片.png

    (4)RadialGradient:环形渲染

    RadialGradient(float centerX, float centerY, float radius, int[] colors, float[] stops, TileMode tileMode)
    RadialGradient(float centerX, float centerY, float radius, int centerColor, int edgeColor, TileMode tileMode)
    

    前两个参数是圆心点,后面的参数分别是圆的半径、位置、拉伸模式。

    代码如下:

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        RadialGradient mRadialGradient = new RadialGradient(250, 250, 250, new int[]{Color.BLACK, Color.CYAN, Color.BLUE}, new float[]{0f, 0.9f, 1f}, Shader.TileMode.REPEAT);
        mPaint.setShader(mRadialGradient);
    
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawCircle(250, 250, 250, mPaint);
    }
    

    效果如下:

    图片.png

    (5)ComposeShader:组合渲染

    ComposeShader会将两种渲染叠加。

    ComposeShader(Shader shaderA, Shader shaderB, Xfermode mode)
    ComposeShader(Shader shaderA, Shader shaderB, Mode mode)
    

    代码如下:

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        LinearGradient mLinearGradient = new LinearGradient(0,300,300,300,new int[]{Color.RED,Color.BLUE,Color.RED,Color.BLUE},new float[]{0f, 0.3f, 0.6f, 0.7f}, Shader.TileMode.CLAMP);
        mBitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.pic);
        BitmapShader bitmapShader = new BitmapShader(mBitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
        //ComposeShader composeShader = new ComposeShader(mLinearGradient, bitmapShader, PorterDuff.Mode.ADD);
        ComposeShader composeShader = new ComposeShader(mLinearGradient, bitmapShader, new PorterDuffXfermode(PorterDuff.Mode.ADD));
        mPaint.setShader(composeShader);
    
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawCircle(250, 250, 250, mPaint);
    }
    

    效果如下:

    图片.png

    相关文章

      网友评论

        本文标题:Android之高级渲染Shader

        本文链接:https://www.haomeiwen.com/subject/xwixgftx.html