paint画笔的一些方法和应用 oil painting brush

canvas.drawColor(Color.WHITE);
//—–设置画笔无锯齿
Paint paint1 = new Paint();
canvas.drawCircle(40, 30, 20, paint1);
paint1.setAntiAlias(true);
canvas.drawCircle(100, 30, 20, paint1);
//—–设置画笔的透明度
canvas.drawText(“无透明度”, 100, 70, new Paint());
Paint paint2 = new Paint();
paint2.setAlpha(0x77);
canvas.drawText(“半透明度”, 20, 70, paint2);
Paint paint5 = new Paint();
//设置画笔不填充
paint5.setStyle(Style.STROKE);
canvas.drawRect(new Rect(60,140,80,160), paint5);
//——设置画笔颜色
Paint paint6 = new Paint();
paint6.setColor(Color.GRAY);
canvas.drawText(“灰色”, 30, 180, paint6);
//——设置画笔的ARGB分量
Paint paint9 = new Paint();
paint9.setARGB(0x77, 0xff, 0x00, 0x00);
canvas.drawText(“红色半透明”, 20, 290, paint9);

Canvas

Android框架APIs提供了一系列2D绘画APIs使你可以在一个canvas上画出你自己的图形或修改已存在的View来定制它们的外观.当画2D图形时,典型情况下,你将使用以下两方法之一:

  • a.把你的图形或动画绘制到你的layout中的一个View上.你的图形的绘制被系统的标准View绘制过程所处理— 你只需定义进入View的图形即可.
  • b.在一个Canvas中直接绘制图形.用此方法,你需亲自调用恰当的类的onDraw()方法(把它传给你的Canvas),或Canvas的draw…()方法们中的一个(比如drawPicture()).在这样做时,你也可以任意控制动画.

用Canvas绘画

当你正在写一个应用,在其中你想执行特殊的绘画并且/控制图形动画,你应该使用Canvas作画.一个其实只是一个中间层,只是一个接口,它代表了实际的图形绘制到的表面— 它承受了所有的绘画调用.通过Canvas,你的绘制实际执行到一个后台Bitmap上,这个Bitmap被放在窗口中.

在响应绘画事件的onDraw()回调方法中,提供给你了Canvas,于是你只需把你的绘制调用传给它就行了.当处理一个SurfaceView对象时,你可以从SurfaceHolder.lockCanvas()获取一个Canvas.然而,如果你需要创建一个新的Canvas,那么你必须定义实际绘制所在的Bitmap.Bitmap是Canvas永远所需要的.你可以像下面这样创建一个新的Canvaslike this:

Bitmap b =Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
Canvas c =new Canvas(b);

现在你的Canvas将画到所定义的Bitmap上.使用Canvas画完后,你可以使用任一个Canvas.drawBitmap(Bitmap,…)方法把你的Bitmap移到另一个Canvas.推荐你最终还是使用View.onDraw()或SurfaceHolder.lockCanvas()提供给你的Canvas作画.

Canvas类有很多绘制方法可以使用,比如drawBitmap(…),drawRect(…),drawText(…)等等.也有其它类也具有draw()方法.例如,你有一个Drawable对象要放到Canvas上,Drawable具有它自己的draw()方法,你只需把你的Canvas作为一个参数传给这个方法即可.

自定义绘图

自定义视图最重要的部分是它的外观.你可以根据应用的需求简单或复杂的实现它.http://wiki.eoeandroid.com/Custom_Drawing

重写onDraw()

绘制自定义视图里最重要的一步是重写onDraw()方法.

onDraw()的参数是视图可以用来绘制自己的Canvas对象. Canvas定义用来绘制文本、线条、位图和其他图像单元. 你可以在onDraw()里使用这些方法创建你的自定义用户界面(UI). 不过, 在你调用任何绘画的方法之前, 你必须创建Paint对象.

创建绘画对象

android.graphics框架把绘图分成了两部分:

  • 画什么, 由Canvas处理(形状)
  • 怎么画, 由Paint处理(颜色,样式,字体等)

例如, Canvas提供画线条的方法, 而Paint提供定义线条颜色的方法Canvas提供画矩形的方法, 而Paint定义是否用颜色填充矩形或让它为空. 简而言之, Canvas定义你可以在屏幕上画的形状, 而Paint为你画的每个形状定义颜色、样式、字体等等.

所以, 在你画任何东西之前, 你需要创建一个或多个Paint对象. PieChart(饼图)例子的init()方法里有这样的实现, 这个方法在构造函数里调用,如init(); 提前创建对象是一个很重要的优化. 视图频繁的被重画, 并且许多绘图对象初始化需要消耗大量的资源. 在onDraw()方法里创建绘图对象会严重降低性能, 并可以让你的UI显得有些迟钝.

处理布局事件

为了正确的绘制你的自定义视图, 你需要知道它的大小. 复杂的自定义视图经常需要根据它的大小和在屏幕上的图形区域执行多次布局计算.

永远不应该假设视图在屏上的大小. 即使只有一个应用使用你的视图, 应用也需要处理不同的屏幕尺寸, 多种屏幕分辨率, 以及在横屏和竖屏模式下的各种高宽比.

surface encapsulated by SurfaceView supports OpenGL ES library (Using OpenGL we can draw 2D and 3D objects)

To start drawing custom widgets 3basic drawing components are required

1)    Canvas : provides surface for drawing your widgets

2)    Paint: While physically drawing a picture we make use of paint brushes of different sizes and different brushes for different colors. Similarly Paint object is used to draw widgets of different colors and textures.

3)    Bitmap: Bitmap is the surface under the canvas. It holds the raw pixel values of the images draw on the canvas. While drawing on the canvas we do not color individual pixels we draw upon continuous area, the corresponding pixel values are then placed on the Bitmap.

How to make custom brush for canvas in android?

enter image description hereenter image description here

 mPaint.setPathEffect(new DashPathEffect(new float[] { 8, 8 }, 0)); 
mEmboss = new EmbossMaskFilter(new float[] { 1, 1, 1 }, 0.4f, 6, 3.5f);

 mBlur = new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL);

i want some brush effects like: crayon, spray, oil painting brush, a Chinese writing brush…etc.

The Canvas and Paint API is very powerful and you can get a lot of effects.

Using paints you can draw lines, paths shapes and gradients, even bitmaps. You can use porter duff blending modes, blur masking and color filters.

PathEffect

Graphics->PathEffects

android.graphics.Path允许使用线段,二次曲线,三次曲线构成路径

  • e[0] = null;     // no effect
  • e[1] = new CornerPathEffect(10); //从尖角改为可以指定圆弧半径的圆角连接
  • e[2] = new DashPathEffect(new float[] {10, 5, 5, 5}, phase); //虚线显示效果,使用数组来指定需线和间隔的长度。数组中序数为偶数表示虚线的实线长度,奇数为虚线的间隔长度。 只对Paint设为STROKE 或STROKE_AND_FILL时有效。
  • e[3] = new PathDashPathEffect(makePathDash(), 12, phase, PathDashPathEffect.Style.ROTATE); //和DashPathEffect类似显示虚线,但可以自定义虚线(本例为一箭头)的模式(DashPathEffect使用的是矩形,而PathDashPathEffect允许使用Path对象自定义虚线的模式),同样只对Paint设为STROKE 或STROKE_AND_FILL时有效。
  • e[4] = new ComposePathEffect(e[2], e[1]); //使用e[2]和e[1]综合效果,虚线并圆弧连接。
  • e[5] = new ComposePathEffect(e[3], e[1]); // 使用e[3]和e[1]综合效果,自定义虚线并圆弧连接。

注意 onDraw的这两行:

1 mPhase += 1;
2 invalidate();

mPhase 指定的是虚线上虚实偏移,每次加1,相当于交换虚处和实处的位置,而invalidate()将再次出发onDraw ,这样虚实不断变换给人以动画的效果。

private static Path makePathDash() {
Path p = new Path();
p.moveTo(4, 0);
p.lineTo(0, -4);
p.lineTo(8, -4);
p.lineTo(12, 0);
p.lineTo(8, 4);
p.lineTo(0, 4);
return p;
}

BitmapShader –

Shader used to draw a bitmap as a texture. The bitmap can be repeated or mirrored by setting the tiling mode.

So you need a small Bitmap which acts as a mask containing the small lines and dots which make up the Brush. Use Shader.TileMode.REPEAT or MIRROR. To change the color of the brush you apply ColorFilter to the Paint with setColorFilter.

Shader类包括了5个直接子类,分别为:

  • BitmapShader用于图像渲染;使用一张位图作为纹理来对某一区域进行填充
  • ComposeShader用于混合渲染;实现渲染效果的叠加,如BitmapShader与LinearGradient的混合渲染效果等。
  • LinearGradient用于线性渲染;实现某一区域内颜色的线性渐变效果。
  • RadialGradient用于环形渲染;在某一区域内实现环形的渐变效果。
  • SweepGradient则用于梯度渲染。扫描渲染,是指在某一中心以x轴正方向逆时针旋转一周而形成的扫描效果的渲染形式。

使用Shader类进行图像渲染时,首先需要构建Shader对象,然后通过Paint的setShader()方法来设置渲染对象,最后将这个Paint对象绘制到屏幕上即可。

最上面的是BitmapShader效果图;第二排的左边是LinearGradient的效果图;第二排的右边是RadialGradient的效果图;第三排的左边是ComposeShader的效果图(LinearGradient与RadialGradient的混合效果);第三排的右边是SweepGradient的效果图。

1. BitmapShader

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

//参数bitmap表示用来作为纹理填充的位图;参数tileX表示在位图X方向上位图衔接形式;参数tileY表示在位图Y方向上位图衔接形式。Shader.TileMode有3种参数可供选择,分别为CLAMP、REPEAT和MIRROR。CLAMP的作用是如果渲染器超出原始边界范围,则会复制边缘颜色对超出范围的区域进行着色。REPEAT的作用是在横向和纵向上以平铺的形式重复渲染位图。MIRROR的作用是在横向和纵向上以镜像的方式重复渲染位图。

2. LinearGradient

public        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:这个也是一个数组用来指定颜色数组的相对位置 如果为null 就沿坡度线均匀分布  tile:平铺方式

Paint p=new Paint();
LinearGradient lg=new LinearGradien(0,0,100,100,Color.RED,Color.BLUE,Shader.TileMode.MIRROR);
Gradient是基于Shader类,所以我们通过Paint的setShader方法来设置这个渐变,代码如下:
p.setShader(lg);
canvas.drawCicle(0,0,200,p); //参数3为画圆的半径,类型为float型。

3.


第四个RoundRect 有些奇形怪状。这是因为绘制这个RoundRectShape的Paint 使用了PathEffect:
PathEffect pe = new DiscretePathEffect(10, 4);
PathEffect pe2 = new CornerPathEffect(4);
mDrawables[3].getPaint().setPathEffect(new ComposePathEffect(pe2, pe));  

PathEffect 可以影响Paint绘制图形时几何形体的形状,Android提供了ComposePathEffect ,ConerPathEffect, DashPathEffec, DiscretePathEffect, PathDashPathEffect, SumPathEffect 等几种PathEffect。其中DiscretePathEffect可以随机的偏移原路径位置,才有了本例的效果。

via

Android ApiDemos示例解析(65):Graphics->Drawable->ShapeDrawable

Android学习笔记12:图像渲染(Shader)

android Shader类简介_渲染图像示例

Graphics中PorterDuff.Mode

Android ApiDemos示例解析:总结

Android简明开发教程十六:Button 画刷示例

SkPaint

Android Graphic : apk and Skia/OpenGL|ES

Android apk 里面的画图分为2D和3D两种:2D是由Skia 来实现的,也就是我们在框架图上看到的SGL,SGL也会调用部分opengl 的内容来实现简单的3D效果;3D部分是由OpenGL|ES实现的,OpenGL|ES是Opengl的嵌入式版本

android.graphic【android】

Canvas

It represents a surface that can have things drawn to it. The Canvas class provides methods for you to:

  • Draw primitives such as simple shapes and paths
  • Draw bitmaps
  • Draw text
  • Clip drawing operations
  • Translate, scale, rotate, or otherwise transform the canvas’s image
  • Save and restore drawing states

Paint

The Paint class in Android functions in a similar capacity of the physical brush: several different brushes that all have different properties, and you use each one for a different purpose.

  • could  give a Paint object which contains the properties with which you want that drawing operation to use.
  • could have as many different paint objects as you like, and you can use any of them for each drawing operation performed on a canvas.
  • can use any of them for each drawing operation performed on a canvas

The properties that a Paint object encapsulates are:

  • Drawing Color
  • Primitive drawing style (solid ‘fill’ or outline ‘stroke’)
  • Stroke style attributes
  • Fill shader
  • Text drawing font attributes
  • Color filter
  • Mask filter
  • Transfer mode
  • Shadow layer

Paint类相当于一个笔刷和调色板。它可以选择如何使用上面描述的draw方法来渲染绘制在画布上的基本图形。通过修改Paint对象,可以在绘图的时候控制颜色、样式、字体和特殊效果。除了这些简单的控制之外,Paint类还支持透明度,另外,它也可以通过使用各种各样的阴影、过滤器效果进行修改,从而提供由更丰富的、复杂的画笔和颜料组成的调色板

Android SDK包含了一些非常好的实例,它们说明了Paint类中可用的大部分功能。你可以在API demos的graphics子目录中找到它们:sdk root folder]\samples\ApiDemos\src\com\android\samples\graphics

使用透明度
Android中的所有颜色都包含了一个不透明组件(alpha通道)
当创建一个颜色的时候,可以使用argb或者parseColor方法来定义它的alpha值,如下所示:
// 使用红色,并让它50%透明
int opacity = 127;
int intColor = Color.argb(opacity, 255, 0, 0);
int parsedColor = Color.parseColor("#7FFF0000");
//也可以使用setAlpha方法来设置已存在的Paint对象的透明度:让颜色50%透明
int opacity = 127;
myPaint.setAlpha(opacity);

可以在任何使用了颜色的类或者方法中使用透明效果,包括Paint、ShaderMask Filter

Shader介绍

Shader类的派生类可以创建允许使用多种固体颜色填充绘图对象的Paint。
对Shader最常见的使用是定义渐变填充;渐变是在2D图像中添加深度和纹理的最佳方式之一。Android包含了一个Bitmap Shader和一个Compose Shader,同时,还包含了三个渐变的Shader。
Bitmap
Every canvas has exactly one underlying Bitmap object.

The bitmap holds the actual pixel data of the image. Whereas the Canvas class provides a high level interface to draw shapes, paths, text, and so on, the Bitmap class provides a more low-level interface to the image, allowing you to manipulate the pixels directly.

Bitmap.Config是内部枚举类表示位图的颜色配置,

  • 它的颜色配置有ALPHA_8、ARGB_4444、ARGB_8888、RGB_565

Bitmap是使用像素阵列来表示的图像,每个像素的颜色信息由RGB组合或者灰度值表示。根据颜色信息所需的数据位分为1、4、8、16、24及32位等,位数越高颜色越丰富,相应的数据量越大。

  • 使用1位表示一个像素颜色的位图因为一个数据位只能表示两种颜色,所以又称为二值位图。
  • 使用24位RGB组合数据位表示的的位图称为真彩色位图。
  • 一般来说,位图是没有经过压缩的,位图文件体积比较大。(位图常用的压缩算法是通过“索引颜色表”实现的),
  • 位图大多支持alpha通道(透明通道)。
  • RGB编码方式: 位图颜色的一种编码方法,用红、绿、蓝三原色的光学强度来表示一种颜色。 直接用于屏幕显示。
  • CMYK编码方式: 位图颜色的一种编码方法,用青、品红、黄、黑四种颜料含量来表示一种颜色。直接用于彩色印刷。
  • 色彩位数,即位图中要用多少个二进制位来表示每个点的颜色,是分辨率的一个重要指标。常用有1位(单色),2位(4色,CGA),4位(16色,VGA),8 位(256色),16位(增强色),24位和32位(真彩色)等。色深16位以上的位图还可以根据其中分别表示RGB三原色或CMYK四原色色深16位以上的位图还可以根据其中分别表示RGB三原色或CMYK四原色的位数进一步分类,如16位位图图片还可分为R5G6B5,R5G5B5X1(有1位不携带信息),R5G5B5A1,R4G4B4A4 等等。

Xfermode

Xfermode is the base class for objects that are called to implement custom “transfer-modes” in the drawing pipeline. 通过修改Paint的Xfermode来影响在Canvas已有的图像上面绘制新的颜色的方式 : 在已有的图像上绘图将会在其上面添加一层新的形状。如果新的Paint是完全不透明的,那么它将完全遮挡住下面的Paint;如果它是部分透明的,那么它将会被染上下面的颜色。

color blending, image compositing, small explanation about Transfer modes algorithms, source color, destenation color and op color

AvoidXfermode avoid = new AvoidXfermode(Color.BLUE, 10, AvoidXfermode.Mode. AVOID);    borderPen.setXfermode(avoid);

Xfermode子类:

  • AvoidXfermode  指定了一个颜色和容差,强制Paint避免在它上面绘图(或者只在它上面绘图)。
  • PixelXorXfermode  当覆盖已有的颜色时,应用一个简单的像素XOR操作
  • PorterDuffXfermode  这是一个非常强大的转换模式,使用它,可以使用图像合成的16条Porter-Duff规则的任意一条来控制Paint如何与已有的Canvas图像进行交互

16条Porter-Duff规则:
1.PorterDuff.Mode.CLEAR
2.PorterDuff.Mode.SRC //
表示下面要绘制的文本应在上面绘制的圆的上层
3.PorterDuff.Mode.DST
4.PorterDuff.Mode.SRC_OVER
5.PorterDuff.Mode.DST_OVER
6.PorterDuff.Mode.SRC_IN
7.PorterDuff.Mode.DST_IN
8.PorterDuff.Mode.SRC_OUT
9.PorterDuff.Mode.DST_OUT
10.PorterDuff.Mode.SRC_ATOP
11.PorterDuff.Mode.DST_ATOP
12.PorterDuff.Mode.XOR
13.PorterDuff.Mode.DARKEN
14.PorterDuff.Mode.LIGHTEN
15.PorterDuff.Mode.MULTIPLY
16.PorterDuff.Mode.SCREEN

Paint p = new Paint();
p.setAntiAlias(true);
p.setAlpha(0x80);/设置颜色透明度为十六进制80(半透明),0x00全透明0xFF不透明
c.drawCircle(x/2, y/2, x/2, p);//在位图矩阵区域内画一个相切的圆
p.setAlpha(0x30);
p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));//用指定的PorterDuff模型创建xformode


   Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(), Config.ARGB_4444);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
paint.setAntiAlias(true);//在绘制一个新的Paint对象时,可以通过传递给它一些标记来影响它被渲染的方式。ANTI_ALIAS_FLAG可以保证在绘制斜线的时候使用抗锯齿效果来平滑该斜线的外观。要创建更加平滑的文本效果,可以应用SUBPIXEL_TEXT_FLAG,它将会应用子像素抗锯齿效果。也可以手工地使用setSubpixelText和setAntiAlias方法来设置这些标记
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
//paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
//MULTIPLY 多层阴影
paint.setXfermode(new PorterDuffXfermode(mode));
canvas.drawBitmap(bitmap, rect, rect, paint);

after

生活在西班牙

自己动手丰衣足食

BlueAsteroid

Just another WordPress.com site

Jing's Blog

Just another WordPress.com site

Start from here......

我的心情魔方

天才遠私廚

希望能做一個分享各種資訊的好地方

语义噪声

西瓜大丸子汤的博客

笑对人生,傲立寰宇

Just another WordPress.com site

Where On Earth Is Waldo?

A Project By Melanie Coles

the Serious Computer Vision Blog

A blog about computer vision and serious stuff

Cauthy's Blog

paper review...

Cornell Computer Vision Seminar Blog

Blog for CS 7670 - Special Topics in Computer Vision

datarazzi

Life through nerd-colored glasses

Luciana Haill

Brainwaves Augmenting Consciousness

槑烎

1,2,∞

Dr Paul Tennent

and the university of nottingham

turn off the lights, please

A bunch of random, thinned and stateless thoughts around the Web

John's Weblog

Just another WordPress.com weblog