【skia】win32中使用skia图形库

正文

废话少说,下面,这个win32的消息回调函数,学过的都明白。

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

这里使用skia,其实是先分配内存,在内存里绘图之后通过StretchDIBits函数绘制到窗口DC。

下面,主要看case WM_PAINT,窗口重绘,就会接收这消息。

#include "SkString.h"
#include "SkSurface.h"
#include "SkCanvas.h"

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {

    switch (message)
    {

    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hWnd, &ps);

        RECT rt;
        GetClientRect(hWnd, &rt);
        int bmpw = rt.right - rt.left;
        int bmph = rt.bottom - rt.top;
        
        const size_t bmpSize = sizeof(BITMAPINFOHEADER) + bmpw * bmph * sizeof(uint32_t);
        BITMAPINFO* bmpInfo = (BITMAPINFO*)new BYTE[bmpSize]();
        bmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        bmpInfo->bmiHeader.biWidth = bmpw;

        // biHeight为正时,bmpInfo->bmiColors像素是从图片的左下角开始。
        // biHeight为负时,bmpInfo->bmiColors像素是从图片的左上角开始。
        // 这是BMP的格式中指定。而skia绘制需要从上到下。
        bmpInfo->bmiHeader.biHeight = -bmph;  

        bmpInfo->bmiHeader.biPlanes = 1;
        bmpInfo->bmiHeader.biBitCount = 32;  //图片每像素32位
        bmpInfo->bmiHeader.biCompression = BI_RGB;
        void* pixels = bmpInfo->bmiColors;  //图片像素位置指针

        // kBGRA_8888_SkColorType,这参数决定SkCanvas绘图像素的格式
        // BGRA,ARGB,就好象cpu大端,小端之类的。
        SkImageInfo info = SkImageInfo::Make(bmpw, bmph,
            kBGRA_8888_SkColorType,kPremul_SkAlphaType);

        sk_sp<SkSurface> surface = SkSurface::MakeRasterDirect(info, pixels, bmpw * sizeof(uint32_t));
        SkCanvas* canvas = surface->getCanvas();

        canvas->clear(SK_ColorWHITE); //填充白色背景

        Draw(canvas, bmpw, bmph); //这里调用函数,传入指针绘图。

        StretchDIBits(  hdc, 0, 0, bmpw, bmph, 
                        0, 0, bmpw, bmph, 
                        pixels, bmpInfo,
                        DIB_RGB_COLORS, SRCCOPY );  //整张图绘制到DC
        
        delete[] bmpInfo;
        EndPaint(hWnd, &ps);
    }
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    default:
        goto label_msg_end;
        break;
    }
    return 0;

label_msg_end:
    return DefWindowProc(hWnd, message, wParam, lParam);
}

绘图函数

Draw(SkCanvas* canvas,int w,int h)
void Draw(SkCanvas* canvas,int w,int h) {

    SkPaint paint;
    paint.setStrokeWidth(1);
    paint.setARGB(0xff, 0xff, 0, 0);

    for (int i = 0; i < h; i++)
    {
        canvas->drawPoint(0, i, paint);
    }

    for (int i = w; i > 0 ; i--)
    {
        canvas->drawPoint(i-1, h-1, paint);
    }

    SkPaint textpaint;
    textpaint.reset();
    textpaint.setTextSize(16);
    textpaint.setColor(SkColor(0xffff0000));
    textpaint.setAntiAlias(true);
    SkString string("Hello World");

    canvas->drawString(string, 1, 16, textpaint);

    canvas->flush(); //这函数是用于GPU surface。这里其实不需要。例如使用OpenGL的上下文。
}

SkPaint相当于画笔属性,setStrokeWidth像素点大小,setColor颜色。

编译运行后,大概下面的效果:

效果图

附录、

BITMAPINFOHEADER 详细内容,可参考下面的MSDN链接
https://msdn.microsoft.com/zh...
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值