简体   繁体   English

使用GDI(C ++)绘制轮廓的DrawText

[英]DrawText with outline using GDI (C++)

I'm using this code to sign a frame from webcam: 我正在使用以下代码对网络摄像头的框架进行签名:

Font = CreateFont(18, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, VARIABLE_PITCH, "times");

...

HDC hDC = CreateCompatibleDC(NULL);
unsigned char * img = 0;
HBITMAP hBitmap = CreateDIBSection(hDC, &BMI, DIB_RGB_COLORS, (void**)&img, NULL, 0);
memcpy(img, CameraFrame.data, CameraFrame.size());
free(CameraFrame.data);
CameraFrame.data = img;
SelectObject(hDC, hBitmap);
SelectObject(hDC, Font);
SetBkMode(hDC, TRANSPARENT);
SetTextColor(hDC, RGB(255,255,255));
string Text = "Test";
DrawTextA(hDC, Text.c_str(), Text.size(), &rect, DT_CENTER | DT_WORDBREAK);
DeleteDC(hDC);

Of course the color scale of frames will differ, and I need the text to be visible anyway. 当然,框架的色阶会有所不同,无论如何我都需要文本可见。

How to DrawText with outline? 如何用轮廓DrawText For example, white text with black outline. 例如,带有黑色轮廓的白色文本。

Two approaches: 两种方法:

  • Draw the Text in black, but scaled slightly larger by 2 pixels (good luck) and offset by (-1,-1) then normally in white in the center. 用黑色绘制文本,但以2像素(好运)的比例稍大一些,并偏移 (-1,-1),然后通常以白色为中心。

  • Draw the Text in black, but offset { (-1,-1), (1,1), (-1,1), (1,-1) } and then in white in the center. 以黑色绘制文本,但偏移{ (-1,-1), (1,1), (-1,1), (1,-1) } ,然后以白色为中心。

With GDI, you can use BeginPath, DrawText, EndPath, and then StrokeAndFillPath, as long as you're using an "outline" font (like TrueType or OpenType). 使用GDI,只要您使用的是“轮廓”字体(如TrueType或OpenType),就可以使用BeginPath,DrawText,EndPath,然后使用StrokeAndFillPath。

  ::BeginPath(ps.hdc);
  RECT rc;
  GetClientRect(&rc);
  ::DrawTextW(ps.hdc, L"Hello", 5, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
  ::EndPath(ps.hdc);
  ::StrokeAndFillPath(ps.hdc);

The StrokeAndFillPath will use the currently selected pen for the outline and the currently selected brush to fill it in. You can use TextOut or other GDI calls inside the BeginPath/EndPath. StrokeAndFillPath将使用当前选择的笔作为轮廓,并使用当前选择的笔刷进行填充。您可以在BeginPath / EndPath内部使用TextOut或其他GDI调用。

You won't get any anti-aliasing like you'd have with regular text output, so it won't be as crisp as your regular ClearType text. 您不会像常规文本输出那样获得任何抗锯齿功能,因此它不会像常规ClearType文本那样清晰。 At larger sizes, this isn't a big issue. 在较大尺寸下,这不是大问题。

Here is what I would recommend: 这是我的建议:

  1. Create a custom pen with a dashed style using CreatePen or ExtCreatePen with PS_DASH. 使用带有PS_DASH的CreatePen或ExtCreatePen创建虚线样式的自定义笔。
  2. DrawText using DT_CALCRECT and your desired styles to see where the text will actually go. 使用DT_CALCRECT和所需的样式绘制文本,以查看文本的实际位置。
  3. SelectObject the HPEN from #1 into your HDC 从#1将HPEN选择对象到HDC
  4. Use MoveToEx and LineTo to draw the 4 edges of your frame based on the rectangle retrieved in #2 (adding some padding as needed). 使用MoveToEx和LineTo根据在#2中检索到的矩形绘制框架的4个边缘(根据需要添加一些填充)。 Sample code here: https://msdn.microsoft.com/en-us/library/windows/desktop/dd145182(v=vs.85).aspx 此处的示例代码: https : //msdn.microsoft.com/zh-cn/library/windows/desktop/dd145182(v=vs.85).aspx

Step 1 happens when initializing. 初始化时发生步骤1。 Steps 2-4 happen each time you paint. 每次绘制时都会发生步骤2-4。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM