Skia是一个开源的2D图形库,提供通用的API,适用于工作中遇到的各种硬件和软件平台。这是谷歌浏览器Chrome OS,Android的图形引擎,Mozilla Firefox浏览器和Firefox OS,和许多其他产品。
官方网站:https://skia.org/
编译及配置方法可以参考Skia简介以及在Windows下编译操作步骤。注意Windows下还需要添加链接库:windowscodecs.lib usp10.lib以及需要添加一些预定义。
简单说一下我在用的时候遇到的几个坑。
1. 画任意曲线时,需要设置SkPaint的style,这个比较坑,找了好久,发现需要设置一下风格,否则使用SkPath类的moveTo()和lineTo()之后,画出的任意曲线是填充过的。这个跟Qt或者其他图形引擎不大相同。
SkPaint paint;
paint.setStyle(SkPaint::kStroke_Style);
2. 画一张带有透明背景的图片,alpha和rgb是4个字节,设置alpha值为0,填充后的图片即是透明的,之后再画一张bitmap即可。
SkCanvas canvas(new SkDevice(bitmap)); canvas.clear(0x00000000);
3. 注意2的例子是网上好多人写的,项目中用的时候发现内存泄漏的问题,new SkDevice改成栈上的就OK了。
简单例子:
#include "stdafx.h" #include "SkBitmap.h" #include "SkDevice.h" #include "SkPaint.h" #include "SkRect.h" #include "SkImageEncoder.h" #include "SkTypeface.h" #include "SkCanvas.h" #pragma comment(lib,"core.lib") #pragma comment(lib,"images.lib") #pragma comment(lib,"ports.lib") #pragma comment(lib,"opts.lib") #pragma comment(lib,"utils.lib") const char *pText = "Hello world!"; int _tmain(int argc, _TCHAR* argv[]) { const int width = 1024; const int height = 768; SkBitmap bitmap; SkPath path; SkPaint paint; paint.setStyle(SkPaint::kStroke_Style); paint.setColor(0xff1f78b4); paint.setStrokeWidth(8); bitmap.setConfig(SkBitmap::kARGB_8888_Config,width,height); bitmap.allocPixels(); SkCanvas canvas(new SkDevice(bitmap)); canvas.clear(0x00000000);// 背景为透明色 { SkRect rc; rc.fLeft = 123; rc.fTop = 0; rc.fRight = 222; rc.fBottom = 50; canvas.drawOval(rc, paint); } { paint.setARGB(255, 255, 0, 0); paint.setTextSize(50); canvas.drawText(pText, strlen(pText), 500, 500, paint); } { paint.setColor(SK_ColorYELLOW); canvas.drawCircle(100, 100, 50, paint); } { SkPaint paint1, paint2, paint3; paint1.setTextSize(64.0f); paint1.setAntiAlias(true); paint1.setColor(0xff4281A4); paint1.setStyle(SkPaint::kFill_Style); paint2.setTextSize(64.f); paint2.setAntiAlias(true); paint2.setColor(0xff9CAFB7); paint2.setStyle(SkPaint::kStroke_Style); paint2.setStrokeWidth(SkIntToScalar(3)); paint3.setTextSize(64.0f); paint3.setAntiAlias(true); paint3.setColor(0xffE6B89C); paint3.setTextScaleX(SkFloatToScalar(1.5f)); const char text[] = "jiayayao@126.com"; canvas.drawText(text, strlen(text), 200.0f, 64.0f, paint1); canvas.drawText(text, strlen(text), 200.0f, 144.0f, paint2); canvas.drawText(text, strlen(text), 200.0f, 224.0f, paint3); } SkImageEncoder::EncodeFile("testSkia.png", bitmap,SkImageEncoder::kPNG_Type,100); return 0; }
Skia一个大的优势是跨平台,比如在Windows平台可以用Direct3D图形API或者Gdiplus负责底层实现,用Skia在上层绘图,这样绘图逻辑基本可以不用修改,直接将bitmap的指针(char*)bitmap.getAddr32(0, 0)交给D3D绘制即可。