Windows平台下Skia使用技巧一

2019-09-08

www.qt-ui.com 原创技术文章

Windows平台下有两大绘图API,分别是GDI和GDI+

GDI

由于没有复杂的抗锯齿处理,绘图效率非常不错,但是同样的绘制质量不好。没有半透明的处理功能,在对界面要求不高而对性能要求比较高的应用程序里面使用比较多,比如股票软件。

GDI+

GDI的升级版本,Windows独立提供了一个GDIPlus.dll的动态库,具有跨语言特性,C++,C#,VB都可以使用。 API封装性也比较好,支持丰富的半透明处理功能和文字处理特效。 具备抗锯齿绘制的能力。同样的也有其弊端,主要表现在:

  1. 绘制性能低下,连续绘制1000张大图片CPU基本就扛不住了
  2. 部分API存在bug,最典型的就是文字大小计算,计算不准确,在文字处理场景下存在一定的弊端。
  3. 没有特效的处理能力,比如模糊处理,发光处理,三维旋转效果,只提供了2D的选择和矩阵透视变形特效。

所以使用GDI和GDI+在一些复杂的场景下使用非常受限。

有人说可以用OpenGL和DirectX来处理,这两个API库需要实现大量的底层功能,比如文字栅格化等等,另外依赖显卡的驱动,对低配置计算机不是很友好。

除了以上的选择之外Google的Skia的推出确实帮助我们解决了一部分问题,在此基础上我们做对应的扩展即可让我们实现复杂的绘制效果。

接下来我们详细介绍Skia的使用。

Skia

Skia一个开源的2D图形库,后面被Google收购调之后做了改进,然后在大量的设备和软件上使用,比如他们家的Chrome,Android。

官方网站:https://skia.org/

开发示例

Windows下Skia的绘制流程:

以下示例如何绘制一张32位的内存位图

新建一张内存位图和内存DC

    HBITMAP CreateGDIBitmap(int nWid, int nHei, void ** ppBits)
    {
        BITMAPINFO bmi;
        memset(&bmi, 0, sizeof(bmi));
        bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        bmi.bmiHeader.biWidth = nWid;
        bmi.bmiHeader.biHeight = -nHei;
        bmi.bmiHeader.biPlanes = 1;
        bmi.bmiHeader.biBitCount = 32;
        bmi.bmiHeader.biCompression = BI_RGB;
        bmi.bmiHeader.biSizeImage = 0;

        HDC hdc = GetDC(NULL);
        LPVOID pBits = NULL;
        HBITMAP hBmp = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, ppBits, 0, 0);
        ReleaseDC(NULL, hdc);
        return hBmp;
    }

    ...

    _hBmp = CreateGDIBitmap(_w, _h, &_pBmpBits);

这张位图我们会后面会传递给Skia,让他在上面绘制,替代之前的GDI/GDI+绘制过程。

新建一个位图对象 SkBitmap

            if (_skBitmap == UIGNull)
            {
                _skBitmap = new SkBitmap();
            }

            _skBitmap->setConfig(SkImageInfo::Make(_w, _h, kN32_SkColorType, kPremul_SkAlphaType));
            _skBitmap->setPixels(_pBmpBits);

_pBmpBits 是我们创建内存位图拿到的位图数据地址

新建一个画布对象 SkCanvas

            if (_canvas == UIGNull)
            {
                _canvas = new SkCanvas(*_skBitmap);
            }
            else
            {
                delete ((SkCanvas*)_canvas);
                _canvas = new SkCanvas(*_skBitmap);
            }

通过传入skbimap给skcanvas可以可以利用skcanvas的api来进行绘图了

清空位图

        if (_canvas)
        {
            SkColor color = SkColorSetARGBInline(0, 0, 0, 0);

            SkRect skRect = SkRect::MakeXYWH((SkScalar)rect._x, (SkScalar)rect._y, (SkScalar)rect._w, (SkScalar)rect._h);
            SkPaint paint;
            paint.setARGB(0, 0, 0, 0);
            paint.setXfermodeMode(SkXfermode::kClear_Mode);
            _canvas->drawRect(skRect, paint);
        }

设置绘图模式为 ClearMode就可以清空位图

以上是基本的位图处理过程,后面我们会逐步介绍Skia绘图API和特效处理方法。

Qt商用模板项目

支持C++/Python语言,支持Windows\Linux\MacOS系统,支持X86\ARM\MIPS架构

img02

Qt Stock Exchange Sys

View more

Qt股票交易系统

Qt Stock Exchange System

img02

Qt Robot

View more

QtRobot 视频高清机器人控制系统

Qt Robot System

img02

Qt LED Editor

View more

Qt LED 灯效编辑器

Qt LED Editor

img02

Qt IOT Bike

View more

Qt IOT 物联网自行车

Qt IOT Bike

img02

Qt ECG Monitor

View more

Qt嵌入式床旁心电监护仪

Qt ECG Monitor

img02

Qt AutoDashboard

View more

Qt汽车仪表盘系统

Qt Auto Dashboard

img02

Qt DataMonitor

View more

Qt数据监控系统

Qt Data Monitor

img02

Qt Conference

View more

Qt会议终端系统

Qt Conference System

img02

Qt Video Player

View more

Qt视频播放器

Qt Video Player

img02

Qt NetDisk

View more

Qt网盘系统

Qt SkyDrive

img02

Qt IM

View more

Qt即时通讯系统

Qt IM

img02

Qt Cashier

View more

Qt便利店收银系统

Qt CashierSystem

产品文档

0基础赋能高级Qt界面开发

author

Qt控件库 API

author

使用视频教程

author

New Qt Designer使用文档

author

模板项目文档



武汉维仕杰科技有限公司 ( Wuhan VisualGear Co.,ltd )
Copyright © 2018-2024 www.qt-ui.com
鄂ICP备20004169号