Skia brief outline

Google Skia is a complete 2D graphic library for drawing Text, Geometries, and Images.

  • 3×3 matrices w/ perspective
  • antialiasing, transparency, filters
  • shaders, xfermodes, maskfilters, patheffects
  • subpixel text

Skia是一个C++的开源2D图形库,Raster、OpenGL和PDF目前都在使用它。Skia可提供的功能包括:

  • 3 × 3 带角度的矩阵
  • 抗锯齿、透明化和滤镜
  • 阴影、XFER模式、模板过滤器、通道效果

picture from Google

Chrome开发者Elliot Poger宣布Chrome for Mac将很快换用Skia 2D图形库替换以前的Apple核心图形库,这也使得Linux、Windows和Mac OS X系统使用的图形库完全统一。

使用 Skia 的 API 进行图形绘制时主要会用到一下几个类:其实现代码主要在 src/core 目录下。

  • SkBitmap 用来设置像素;
  • SkCanvas 写入位图;
  • SkPaint 设置颜色和样式;
  • SkRect 用来绘制矩形。

使用 Skia 绘图的步骤:

a) 定义一个位图 32 位像素并初始化 SkBitmap bitmap;

b) 分配位图所占的空间

c) 指定输出设备

d) 设备绘制的风格

图形图像特效 

skia中effect文件夹中的类继承图

src/effects 目录的文件主要实现一些图形图像的特效,包括 遮罩、浮雕、模糊、滤镜、渐变色、离散、透明以及 PATH 的各种特效等。

除了颜色、笔画、字体大小这样的简单属性,paint也支持effect, effect是绘图管线不同方面的子类,(每个effect都是引用计数的)当一个effect被一个paint引用的时候,将会覆盖paint的绘制管线的一些部分。例如 ,使用gradient代替单个也是,给paint指定一个SkShader:

SkShader* shader = SkGradientShader::CreateLinear(...);
paint.setShader(shader);
shader->unref();

现在,所有使用这个paint绘制的东西都会使用由CreateLiner指定的gradient,CreateLiner返回的Shader对象是引用计数的。当一个像shader这样的effect对象被指定给一个paint的时候,paint会增加他的引用计数,为了平衡引用计数,上面的例子调用了shader的unref(),现在这个paint就是shader的唯一拥有者,这样,无论是出了paint作用域或者指定了其他的shader(可以为空),会自动调用shader的unref()。

有6种effect可以绑定到paint:

paint也保持SkTypeface的引用,SkTypeface代表指定的字体风格,可以用来测量和绘制文字,也就是说不仅可以用于绘制文本,还可以用来测量文本

动画

src/animator 目录的文件主要实现了 Skia 的动画效果,Android不支持。

界面 UI 库

src/view 目录 构建了一套界面 UI 库。 组件包括 Window,Menu, TextBox, ListView, ProgressBar, Widget, ScrollBar,TagList,Image 等。

Skia 的图像编解码部分

这部分的接口主要是:

  • external/include/image/SKImageDecoder.h // 把图像文件或者流解码到 skia 的内部内存 SKBitmap 中 ;
  • external/include/image/SKImageEncoder.h // 把 skia 内部内存 SKBitmap 编码成文件或流的形式;

这些接口需要具体的类实现,主要代码在 src/image 文件中。

Android 图形系统的 JNI 接口

主要提供了从 Skia 底层库到 Java 上层的支持,代码路径为:frameworks/base/core/jni/android/graphic/,主要为 Canvas.cpp 文件。

GDI+Windows的一套图形绘制库

Windows系统下,所有图形图像绘制,最终都是通过GDI来实现的。Android下也需要一套能绘制出点、线、面等复杂图形,或者渲染界面等图像方面的一个可供开发者调用的绘图函数接口,Skia就是这套绘制工具。

e.g.现在让你来画一幅画,比如我们的国画山水画。画一幅画需要哪些工具呢?从常识上来说,我们需要一张纸,比如白纸,或者带有某些背景图的纸张;需要毛笔不同型号的毛笔墨汁颜料等等。然后我们规定在纸张的哪个区域画图,用什么样的毛笔,用什么样的颜色,画什么样的图形,是点、线、面?还是花草等。Skia就是类似上面画图所有需要的一系列设备、工具等。要Android画图或者渲染图像,都需要Skia提供的API接口,或者是间接提供。

所有Activity或者View或者其他控件的显示,在底层都是通过Skia提供的函数进行显示的。常见的Canvas类,假如你跟踪一下代码,会发现,Canvas是通过Native方式,调用底层的SkCanvas的。Android系统下,通过OpenGL ES绘制的3d图形,最终还是被合并到Skia定义的显示缓存中进行显示的。

2393479_1.jpg

Skia 主要涉及到的3个库:

  •      libcorecg.so  包含/skia/src/core的部分内容,比如其中的Region,Rect是在SurfaceFlinger里面计算可是区域的操作基本单位
  •      libsgl.so        包含/skia/src/core|effects|images|ports|utils的部分和全部内容,这个实现了skia大部分的图形效果,以及图形格式的编解码
  •      libskiagl.so   包含/skia/src/gl里面的内容,主要用来调用opengl实现部分效果

要想在底层使用skia的接口来画图需要全面了解skia的一整套机制,实际上skia开源到现在还没多久,在网上能找到的资料是也是很粗浅的,如果将来真需要在这方面下功夫肯定是需要一定的工作量的。

Skiaandroid源码里的目录位置

  • 头文件(也可以说是internal API, 因为google没有在NDK里面提供他)位置:android/external/skia/include。其中还包含以下几个子目录:animator, core, effects, images, views…, 最重要的就是core目录了,我们在这里的分析也主要针对core目录里面的API。
  • 源文件位于: android/external/skia/src目录,子目录结构和头文件目录相同。
  • 封装层:android对Skia引擎进行了封装,以便让java代码方便的调用,对skia封装的代码存在于android/framework/base/core/jni以及android/framework/base/core/jni/android/graphics目录下面。主要是对Canvas, Bitmap, Graphics, Picture等等的封装,以及和libui库的结合使用。

在Android apk里面画图有2种方式 [2D]:

1、Simple Graphics in View
就是直接使用Android已经实现的一些画图操作,比如说images,shapes,colors,pre-defined animation等等,这些简单的画图操作实际上是由skia来提供的2D图形操作。

如贴一张背景图啊,画出简单地形状阿,实现一些简单的动画之类的操作。没有一笔一画地构造出一个图形出来,我们只是把我们的Graphic 资源放入View体系中,由系统 来将这些Graphic画出来。

种方式只能画静态或者极为简单的2D图画,对于实时性很强的动画,高品质的游戏都是没法实现 的。

2、Canvas
首先我们要明白这个Canvas是一个2D的概念,是在Skia中定义的。也就是说在这个方式下还是说的画2D图形。我们可以把这个Canvas理解成系统提供给我们的一块内存区域(但实际上它只是一套画图的API,真正的内存是下面的Bitmap),而且它还提供了一整套对这个内存区域进行操作的方法, 所有的这些操作都是画图API。

能一笔一划或者使用Graphic来画我们所需要的东西了,要画什么要显示什么都由我们自己 控制。这种方式根据环境还分为两种:

  • 使用普通View的canvas画图,适合处理量比较小,帧率比较小的动画,比如说象棋游戏之类的
  • 使用专门的SurfaceView的canvas来画图。主要用在游戏,高品质动画方面的画图。
    • 可以在SurfaceView中定义一个专门的线程来完成画图工作,应用程序不需要等待View的刷图,提高性能。

关于Activity的 :
(1) 首先尽量把UI的设计放在XML中实现,而不要放在代码中实现,这样方便设计,修改和移植
(2) 所有使用到的component都必须在manifest中声明,不然程序中找不到相应的conponet的时候会报错 ;
(3) 一般每一个Activity都对应于一个类和一个相应的布局文件xml
(4) 每一个Activity只有使用setContentView()绑定内容后才会显示,而且你才能从这个内容(比如xml中)获取到你需要的元素
(5) res/drawable和res/raw中的元素的区别是drawable中的元素像素可能会被系统优化,而raw中的不会被优化 ;
(6) 当多个Activity都从res/drawable中获得同一个元素,如果其中一个修改它的属性,所有其他的Activity中这个元素的相应属性都会改变 ;
(7) res/anim中保存的是动画相关的xml ;

2405240_1.png

https://sites.google.com/site/skiadocs/home

Android Graphic : apk and Skia/OpenGL|ES

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

I Am That I Am

Chasing tomorrow's sunrise.