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

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.