Windows平台下Skia使用技巧一


Windows平台下Skia使用技巧一

www.visual-gear.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和特效處理方法。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM