zoukankan      html  css  js  c++  java
  • 解决使用Skia图形库时遇到的几个问题

      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绘制即可。

  • 相关阅读:
    在谷歌地图上绘制行政区域轮廓【结合高德地图的API】
    用PL/SQL远程连接Oracle服务器
    找工作之离职篇
    linux设置定时备份mysql数据库
    使用NoSQL实现高并发CRM系统实践(源代码+解析)
    做领导应该注意的几个问题
    如何才能成为真正的程序员
    利用websocket实现手机扫码登陆后,同步登陆信息到web端页面
    利用laravel-echo主动向服务端发送消息,实现在线状态管理
    飞鱼CRM
  • 原文地址:https://www.cnblogs.com/jiayayao/p/6188201.html
Copyright © 2011-2022 走看看