shader初探之BitmapShader

来源:互联网 发布:《人工智能ai》 编辑:程序博客网 时间:2024/05/29 16:16


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

调用这个方法来产生一个画有一个位图的渲染器(Shader)。

bitmap   在渲染器内使用的位图

tileX      The tiling mode for x to draw the bitmap in.   在位图上X方向渲染器平铺模式

tileY     The tiling mode for y to draw the bitmap in.    在位图上Y方向渲染器平铺模式

TileMode:

CLAMP  :如果渲染器超出原始边界范围,会复制范围内边缘染色。

REPEAT :横向和纵向的重复渲染器图片,平铺。

MIRROR :横向和纵向的重复渲染器图片,这个和REPEAT重复方式不一样,他是以镜像方式平铺。


下面说下Shader的使用步骤:

1. 构建Shader对象

2. 通过Paint的setShader方法设置渲染对象

3.绘制时使用这个Paint对象


activity代码:

package com.example.shader;import android.app.Activity;import android.graphics.*;import android.graphics.drawable.ShapeDrawable;import android.graphics.drawable.shapes.OvalShape;import android.os.Bundle;import android.util.Log;import android.widget.ImageView;public class MyActivity extends Activity {    ImageView image;    int width,height;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        image = (ImageView) findViewById(R.id.image);        width = ValueUtil.dp2px(this,300);        height = ValueUtil.dp2px(this,300);        Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.tupian); //创建bitmap时会依据屏幕密度缩放,如density为2,drawable-xhdpi下的图片不缩放        Log.e("bitmapwh",bitmap.getWidth()+"+"+bitmap.getHeight()); //352*220//        TileMode://        CLAMP  :如果渲染器超出原始边界(在这个例子中是bitmap的边界)范围,会复制范围内边缘染色,边缘拉伸.//        REPEAT :横向和纵向的重复渲染器图片,平铺。//        MIRROR :横向和纵向的重复渲染器图片,这个和REPEAT重复方式不一样,他是以镜像方式平铺,倒影式平铺        BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);        Bitmap bitmapTemp = Bitmap.createBitmap(width,height, Bitmap.Config.ARGB_8888);        Canvas canvas = new Canvas(bitmapTemp);        /* 第一种使用方式*/        Paint paint = new Paint();        paint.setShader(bitmapShader);        canvas.drawRect(new RectF(0, 0, width, height), paint);//        canvas.drawArc(new RectF(0,0,width,height),90,180,false,paint);//        canvas.drawOval(new RectF(0,0,width,height),paint);        /* 第二种使用方式        ShapeDrawable shapeDrawable = new ShapeDrawable(new OvalShape());        //得到画笔并设置渲染器        shapeDrawable.getPaint().setShader(bitmapShader);        //设置显示区域        shapeDrawable.setBounds(0, 0, width,height);        //绘制shapeDrawable        shapeDrawable.draw(canvas);        */        image.setImageBitmap(bitmapTemp);    }}

效果图:


CLAMP:




REPEAT :



MIRROR :



代码中第一种方式中的canvas.drawOval(new RectF(0,0,width,height),paint)的效果与第二种方式相同,效果图如下:



第二种方式其原理就是canvas的draw系列方法。

我们看shapeDrawable.draw(canvas);的源码:
public void draw(Canvas canvas) {        final Rect r = getBounds();        final ShapeState state = mShapeState;        final Paint paint = state.mPaint;        final int prevAlpha = paint.getAlpha();        paint.setAlpha(modulateAlpha(prevAlpha, state.mAlpha));        // only draw shape if it may affect output        if (paint.getAlpha() != 0 || paint.getXfermode() != null || paint.hasShadowLayer()) {            final boolean clearColorFilter;            if (mTintFilter != null && paint.getColorFilter() == null) {                paint.setColorFilter(mTintFilter);                clearColorFilter = true;            } else {                clearColorFilter = false;            }            if (state.mShape != null) {                // need the save both for the translate, and for the (unknown)                // Shape                final int count = canvas.save();                canvas.translate(r.left, r.top);                onDraw(state.mShape, canvas, paint);                canvas.restoreToCount(count);            } else {                canvas.drawRect(r, paint);            }            if (clearColorFilter) {                paint.setColorFilter(null);            }        }        // restore        paint.setAlpha(prevAlpha);    }

关键代码onDraw(state.mShape, canvas, paint);继续:
/**     * Called from the drawable's draw() method after the canvas has been set to     * draw the shape at (0,0). Subclasses can override for special effects such     * as multiple layers, stroking, etc.     */    protected void onDraw(Shape shape, Canvas canvas, Paint paint) {        shape.draw(canvas, paint);    }
继续看shape的draw方法,发现其是一个抽象方法,shape是个抽象类,在本例中,我们找shape子孙类OvalShape的draw方法。
@Override    public void draw(Canvas canvas, Paint paint) {        canvas.drawOval(rect(), paint);    }
其参数canvas就是我们最初shapeDrawable.draw(canvas)传入的canvas.

View关于背景drawable的绘制

view的draw()方法中会调用drawBackground(Canvas canvas)方法,该方法中调用了background.draw(canvas);而background是setBackgroundDrawable(Drawable background)
设置的。Drawable是抽象类,本例中的ShapeDrawable是其子类。

参考资料:http://blog.csdn.net/t12x3456/article/details/10366063


源码:http://yunpan.cn/c3f2qgcVtNSwP (提取码:2ccf)







0 0