Skia API的简单应用

1 Skia 绘图概述


Skia Google 一个底层的图形、文本、图像、动画等多方面的图形库,是 Android 中图形系统的引擎。 Skia 作为第三方软件放在 external 目录下: external/skia/ skia 的源文件及部分头文件都在 src 目录下,导出的头文件在 include 目录下。

使用 Skia API 进行图形绘制时主要会用到一下几个类:

SkBitmap SkCanvas SkPaint SkRect ,其中 SkBitmap 用来设置像素, SkCanvas 写入位图, SkPaint 设置颜色和样式, SkRect 用来绘制矩形。其实现代码主要在 src/core 目录下。


2 使用 Skia 绘图的步骤


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

bitmap.setConfig(SkBitmap::kARGB_8888_Config, 200, 200);

其中 setConfig 为设置位图的格式,原型为 void setConfig(Config, int width, int height, int rowBytes = 0)
Config
为一个数据结构
enum Config {
kNo_Config, //
不确定的位图格式
kA1_Config, //1
( , ) 位图
kA8_Config, //8
( , ) 位图
kIndex8_Config, //
类似 windows 下的颜色索引表,具体请查看 SkColorTable 类结构
kRGB_565_Config, //16
位象素 565 格式位图,详情请查看 SkColorPriv.h 文件
kARGB_4444_Config, //16
位象素 4444 格式位图,详情请查看 SkColorPriv.h 文件
kARGB_8888_Config, //32
位象素 8888 格式位图,详情请查看 SkColorPriv.h 文件
kRLE_Index8_Config,
kConfigCount
};


b)
分配位图所占的空间

bitmap.allocPixels()
其实 allocPixels 为重载函数,原型为 bool allocPixels(SkColorTable* ctable = NULL)
参数 ctable 为颜色索引表,一般情况下为 NULL


c)
指定输出设备

SkCanvas canvas(new SkDevice(bitmap));
其中 canvas 为一个多构造函数,原型为

explicit SkCanvas(const SkBitmap& bitmap)

explicit SkCanvas(SkDevice* device = NULL)
explicit
关健字的意思为:不允许类型转换
输出设备可以为一个上下文 Device, 也可以指定为一张位图。


d)
设备绘制的风格
Paint paint;
SkRect r;
paint.setARGB(255, 255, 0, 0);
r.set(25, 25, 145, 145);
canvas.drawRect(r, paint);

paint
可以指定绘图的颜色,文本的大小及对齐方式,编码格式等等,因为以前位图的格式设置为 kARGB_8888_Config ,所以这里要设置绘制的颜色 setARGB(255, 255, 0, 0) ,第一位参数为透明颜色通道,其它三位分别为 R G B r 设置要绘制的范围,最后通过 drawRect 绘制出指定区域的一个方形。

这样,一个红色的矩形就绘制成功了。

SkCanvas 主要完成三种绘制功能:

a 基本图形绘制 ( drawARGB,drawLine 函数 )

b 图像文件绘制( drawBitmap 函数)

c 文本绘制( drawText 函数)

相关 API 有:

canvas.drawRect(rect, paint);
canvas.drawOval(oval, paint);
canvas.drawCircle(x, y, radius, paint);
canvas.drawRoundRect(rect, rx, ry, paint);
canvas.drawPath(path, paint);
canvas.drawBitmap(bitmap, x, y, &paint);
canvas.drawBitmapRect(bitmap, &srcRect, dstRect, &paint);
canvas.drawBitmapMatrix(bitmap, matrix, &paint);
canvas.drawText(text, length, x, y, paint);
canvas.drawPosText(text, length, pos[], paint);
canvas.drawTextOnPath(text, length, path, paint);

e) 例程

i )画点、线、圆、文字

#include "SkBitmap.h"

#include "SkDevice.h"

#include "SkPaint.h"

#include "SkRect.h"

#include "SkImageEncoder.h"

#include "SkTypeface.h"


using namespace std;


int main()

{

SkBitmap bitmap;

bitmap.setConfig(SkBitmap::kARGB_8888_Config,320,240);

bitmap.allocPixels();

SkCanvas canvas(new SkDevice(bitmap));

SkPaint paint;

// draw points with red.

paint.setARGB(255, 255, 0, 0);

paint.setStrokeWidth(4);

canvas.drawPoint(40,30, paint);

canvas.drawPoint(80,60, paint);

canvas.drawPoint(120,90, paint);

//draw a line with green.

paint.setARGB(255, 0, 255, 0);

paint.setStrokeWidth(4);

canvas.drawLine(160,10,320,110,paint);

//draw a circle with bule.

paint.setARGB(255, 0, 0, 255);

canvas.drawCircle(80,180,50,paint);

//draw text with red

SkTypeface *font = SkTypeface::CreateFromFile("simkai.ttf");

if ( font )

{

paint.setARGB(255, 255, 0, 0);

paint.setTypeface( font );

paint.setTextSize(24);

canvas.drawText("HELLO!:)", 8, 200, 180, paint);

}

SkImageEncoder::EncodeFile("snapshot.png", bitmap,SkImageEncoder::kPNG_Type,100);

return 0;

}

程序执行后,得到如下输出结果:

Skia API的简单应用_第1张图片


ii) 图像的编解码

该例程目前测试只支持 .png 格式的图片, .jpg 还不支持,还未找到原因。

#include "SkBitmap.h"

#include "SkDevice.h"

#include "SkPaint.h"


#include "SkRect.h"

#include "SkImageEncoder.h"

#include "SkImageDecoder.h"

#include


using namespace std;


int main()

{

int ret = -1;

SkBitmap bitmap;


//SkImageDecoder

ret = SkImageDecoder::DecodeFile("./old.png", &bitmap);

cout<< "get the decode type = "<< bitmap.config() << endl;


//SkImageEncoder

ret = SkImageEncoder::EncodeFile("new1.png",bitmap,SkImageEncoder::kPNG_Type,100);

cout<< "encode data to png result = "<< ret<< endl;


return 0;

}

SkImageDecoder::DecodeFile("./old.png", &bitmap);

png 转换成位图格式,并将数据放到 bitmap 变量中
SkImageEncoder::EncodeFile("snapshot.png", bitmap,SkImageEncoder::kPNG_Type,/* Quality ranges from 0..100 */ 100);

bitmap 中的数据编码输出为 .png 格式,第一位参数为 png 文件路径,第二位为指定的输出位图,第三位为文件的类型,第四位参数指定了输出位图的质量,范围为 0..100 ,默认为 80


3 图形图像特效

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


4 动画

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


5 界面 UI

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


6 其它

a) src/gl 目录: 这部分是 skia 调用 OpenGL OpenGL ES 来实现 3D 效果。
如果定义了 MAC ,则使用 OpenGL ,如果定义了 Android ,则使用嵌入式 系统 上的 esgl 三维图形库。

b)src/images 目录: 主要是 SkImageDecoder SkImageEncoder 以及 SkMovie 。主要是用来处理 images 的,能处理的图像类型包括: BMP

JPEG/PVJPEG PNG ICO ,而 SkMovie 是用来处理 gif 动画的。

c) src/opts 目录:性能优化的代码。

d) src/pdf 目录: 处理 PDF 文档,用了一个 fpdfemb 库。

e) src/ports 目录: 这部分是 skia 的一些接口在不同系统上的实现,平台相关的代码,比如字体、线程、时间等, 主要包括几个部分: Font Event File Thread Time XMLParser

这些与 Skia 的接口,需要针对不同的 操作系统 实现。

f) src/svg 目录:   矢量图像,Android不支持。
SkSVGPath, SkSVGPolyline, SkSVGRect, SkSVGText, SkSVGLine, SkSVGImage, SkSVGEllipse
等等。

g) src/text 目录:???

h) src/utils 目录: 是一些辅助工具类。
SkCamera, SkColorMatrix,SkOSFile,SkProxyCanvas,SkInterpolator
等文件。

i) src/xml 这是处理 xml 数据的部分, skia 在这里只是对 xml 解析器做了一层包装,具体的 xml 解析器的实现需要根据不同的操作系统及宿主程序来实现。

j) Third-party library

除了自身的所有文件外, skia 还使用了一些 third-party library 以及包含了不少 linux 上的头文件。

通过分析 skia 源程序,发现 skia 主要使用以下几个第三方库:
Zlib ,处理数据的压缩和解压缩
Jpeglib ,处理 jpeg 图像的编码解码
Pnglib ,处理 png 图像的编码解码
giflib ,处理 gif 图像
fpdfemb ,处理 pdf 文档

skia 还需要一些 linux/unix 下的头文件(可能还需要更多):
stdint.h
unistd.h
features.h
cdefs.h
stubs.h
posix_opt.h
types.h
wordsize.h
typesizes.h
confname.h
getopt.h
mman.h



你可能感兴趣的:(Android)