3

所以,我有一个视频源的快照,我将它放入一个 Image 中,为其抓取一个 Graphics 对象,然后在图像的右下角绘制一个时间戳。到目前为止没有问题。但是,我不能保证文本后面会是什么颜色,所以无论我使用什么画笔,它几乎肯定会与它所绘制的某些图像发生冲突,从而使文本无法阅读。

我想知道是否有人知道一种方法(.net 中的方法或不错的算法),用于根据字符串背后的图像确定字符串的最佳颜色。

干杯

4

6 回答 6

7
 just draw the string 5 times.
 One time 1(or2) pixels to the left in black
 One time 1(or2) pixels to the right in black
 One time 1(or2) pixels above it in black
 One time 1(or2) pixels below it in black
 and the final time in white on the place where you want it
于 2009-07-28T08:06:33.193 回答
2

唯一可靠的方法是使用对比鲜明的轮廓。

于 2009-07-28T08:07:15.110 回答
1

回到 Commodore 64 sprite 图形的时代,如果您想要在任何背景下脱颖而出,您可以使用 XOR blitting。有人将此称为“反向视频”。

您可以使用 以这种方式绘制线条ControlPaint.DrawReversibleLine,但这不适用于文本。

这篇CodeProject 文章展示了如何使用 interop to 创建 XOR 画笔gdi32.dll

于 2009-07-28T08:06:08.357 回答
0

或者,如果允许,您可以为文本使用背景颜色(您的选择)(例如黑色背景上的白色文本)。

否则,您需要捕获写入文本的矩形(对于每一帧),创建它的负图像,然后获取矩形中的中间颜色并使用它来编写文本。

更复杂的解决方案是让您使用两个图层(初始图片 - L1 和文本(透明背景,黑色文本) - L2),然后在组合它们之前,从 L2 中获取包含文本的所有像素并更改每个图层的颜色文本的像素到 L1 的“负”基础像素颜色值,但是从“查看者”的角度来看,您不会得到太有用的东西。

于 2009-07-28T08:12:50.107 回答
0

这可能是reinier 答案的多种变化。

  1. 绘制底层文本(reinier 提到的四个偏移的)不是黑色,而是实际使用与实际文本的前景色形成对比的颜色。
  2. 绘制文本两次:一次以对比色但以粗体和/或稍大的尺寸绘制,然后以文本前景色绘制。可能需要稍微调整一下坐标,甚至需要按单词甚至字符进行绘图,以使两个通道都能很好地对齐并且不会给出丑陋的最终结果。
  3. 按照 reinier 的建议去做,但可能不是四次(所有四个方向),而是可能三次甚至两次以获得一种“阴影”外观。
  4. 放弃整个“使用 API 调用逐像素绘制文本”方法,并使用 WPF 设计中可用的高级多层合成技术。

有关最后一个选项的一些示例,请查看SlideShare 上的高级 OSM 制图中的幻灯片 18 和 21。

于 2009-07-28T08:30:48.790 回答
0

以下片段显示了如何反转颜色(背景),然后应用 Dinah 的建议使用 Graphics.DrawString() 创建背景。

private static Color InvertColor(Color c)
{
  return Color.FromArgb(255 - c.R, 255 - c.G, 255 - c.B);
}
// In the following, constants and inplace vars can be parameters in your code
const byte ALPHA = 192;
var textColor = Color.Orange;
var textBrush = new SolidBrush(Color.FromArgb(ALPHA, textColor));
var textBrushBkg = new SolidBrush(Color.FromArgb(ALPHA, InvertColor(textColor)));
var font = new Font("Tahoma", 7);
var info = "whatever you wanna write";
var r = new Rectangle(10, 10, 10, 10);

// write the text
using (var g = Graphics.FromImage(yourBitmap))
{
  g.Clear(Color.Transparent);
  // to avoid bleeding of transparent color, must use SingleBitPerPixelGridFit
  g.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit;
  // Draw background for text
  g.DrawString(info, font, textBrushBkg, r.Left - 1, r.Top - 1);
  g.DrawString(info, font, textBrushBkg, r.Left + 1, r.Top + 1);
  g.DrawString(info, font, textBrushBkg, r.Left + 1, r.Top - 1);
  g.DrawString(info, font, textBrushBkg, r.Left - 1, r.Top + 1);
  // Draw text
  g.DrawString(info, font, textBrush, r.Left, r.Top);
}
于 2017-01-25T19:18:03.293 回答