shader初探之BitmapShader
2015-09-10 15:34
309 查看
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代码:
效果图:
CLAMP:
![](http://img.blog.csdn.net/20150910151211864?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
REPEAT :
![](http://img.blog.csdn.net/20150910151244347?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
MIRROR :
![](http://img.blog.csdn.net/20150910151328630?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20150910151641433?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
参考资料:/article/1875781.html
调用这个方法来产生一个画有一个位图的渲染器(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是其子类。
参考资料:/article/1875781.html
源码:http://yunpan.cn/c3f2qgcVtNSwP (提取码:2ccf)
相关文章推荐
- C#实验课:人民币和美元兑换
- 开展应用软件安全测试所需技术储备
- android 设计模式——单例模式
- 0909开启编译原理之路
- EF框架
- Eclispe怎么给工作空间下的项目分组
- css不用旋转实现返回箭头,圆点,三角形
- test2
- MYSQL 创建用户
- Linux Shell下的后台运行及其前台的转换 http://mobile.51cto.com/others-446925.htm
- 安卓驱动学习笔记1----关于友善之臂SD卡烧写的问题
- hessian入门与springMVC框架集成---客户端调用
- 沙盒中的数据存取
- Linux-LVS+keepalived-Testing
- css不用旋转实现返回箭头,圆点,三角形
- 海量数据处理
- 沈阳微信二维码营销技巧(不得不看)
- Chipsee BeagleBone Black完整启动日志
- 拆字
- CornerStone commit不成功解决方案