如何引入Skia项目
<p>打开VS,创建一个空项目,在项目目录中,创建“Skia”文件夹</p>
<ol>
<li>将Skia的include复制到“Skia”文件夹内</li>
<li>将Skia的out/Static复制到“Skia”文件夹内</li>
<li>项目 -> VC++ 目录 -> 包含目录 添加 $(ProjectDir)Skia</li>
<li>项目 -> 链接器 -> 附加库目录 添加 $(ProjectDir)Skia\Static</li>
<li>在调试时发现,Skia源码中min、max与C++内置宏冲突
解决办法:项目 -> C/C++ -> 预处理器 -> 预处理器定义 添加 NOMINMAX
注意:在此之前,必须已添加.h或.cpp文件</li>
<li>项目 -> 常规 -> C++ 语言标准 -> C++ 17 标准以上</li>
<li>项目 -> C/C++ -> 预处理器 -> 所有命令行 -> 运行库 多线程 (/MT)</li>
</ol>
<p><em>一个简单的例子</em></p>
<pre><code class="language-cpp">#include &lt;Windows.h&gt;
#include &quot;include/core/SkSurface.h&quot;
#include &quot;include/core/SkCanvas.h&quot;
#pragma comment(lib, &quot;Skia.lib&quot;)
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CREATE: {
break; }
case WM_PAINT: {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &amp;ps);
RECT rt;
GetClientRect(hWnd, &amp;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-&gt;bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfo-&gt;bmiHeader.biWidth = bmpw;
// biHeight为正时,bmpInfo-&gt;bmiColors像素是从图片的左下角开始。
// biHeight为负时,bmpInfo-&gt;bmiColors像素是从图片的左上角开始。
// 这是BMP的格式中指定。而skia绘制需要从上到下。
bmpInfo-&gt;bmiHeader.biHeight = -bmph;
bmpInfo-&gt;bmiHeader.biPlanes = 1;
bmpInfo-&gt;bmiHeader.biBitCount = 32; //图片每像素32位
bmpInfo-&gt;bmiHeader.biCompression = BI_RGB;
void* pixels = bmpInfo-&gt;bmiColors; //图片像素位置指针
// kBGRA_8888_SkColorType,这参数决定SkCanvas绘图像素的格式
// BGRA,ARGB,就好象cpu大端,小端之类的。
SkImageInfo info = SkImageInfo::Make(bmpw, bmph,
kBGRA_8888_SkColorType, kPremul_SkAlphaType);
sk_sp&lt;SkSurface&gt; surface = SkSurfaces::WrapPixels(info, pixels, bmpw * sizeof(uint32_t));
SkCanvas* canvas = surface-&gt;getCanvas();
canvas-&gt;clear(SK_ColorWHITE); //填充白色背景
SkPaint paint;
paint.setStrokeWidth(1);
paint.setARGB(0xff, 0xff, 0, 0);
SkRect rect = SkRect::MakeXYWH(20, 20, 80, 80);
canvas-&gt;drawRect(rect, paint);
StretchDIBits(hdc, 0, 0, bmpw, bmph,
0, 0, bmpw, bmph,
pixels, bmpInfo,
DIB_RGB_COLORS, SRCCOPY); //整张图绘制到DC
delete[] bmpInfo;
EndPaint(hWnd, &amp;ps);
break; }
case WM_LBUTTONDOWN: {
break; }
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
break;
}
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
}
int main()
{
// 注册窗口类
WNDCLASSEXW wcex = { 0 };
wcex.cbSize = sizeof(WNDCLASSEXW);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = [](HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -&gt; LRESULT {
SetWindowLongPtrW(hWnd, GWLP_WNDPROC, (LONG_PTR)WndProc); // 指向新的窗口过程
return WndProc(hWnd, uMsg, wParam, lParam);
};
wcex.hInstance = GetModuleHandleW(nullptr);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.hCursor = LoadCursorW(nullptr, IDC_ARROW);
wcex.lpszClassName = L&quot;Window.h2Gui.123&quot;;
RegisterClassExW(&amp;wcex);
// 创建窗口
HWND hWnd = CreateWindowExW(
0, L&quot;Window.h2Gui.123&quot;, L&quot;Window.Skia.Test&quot;,
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
200, 200, 800, 600,
nullptr, nullptr, GetModuleHandleW(nullptr), nullptr);
UpdateWindow(hWnd);
// 建立消息循环
MSG msg = { 0 };
while (GetMessageW(&amp;msg, nullptr, 0, 0) &gt; 0) {
TranslateMessage(&amp;msg);
DispatchMessageW(&amp;msg);
}
return (int)msg.wParam;
}</code></pre>