2009-07-28 71 views
3

所以,我有一个视频源,这是我进入图像的快照,抓住一个图形对象,然后在图像的右下角绘制一个时间戳。到目前为止没有问题。但是,我不能保证文本背后有什么颜色,所以无论使用哪种笔刷,它几乎都会与其上绘制的一些图像发生冲突,从而使文本无法读取。绘制字符串对比图像上

我想知道是否有人知道的一种方式(无论是在.NET的方法,还是一个不错的算法),用于确定基于其背后的图像上的字符串的最佳色彩。

干杯

回答

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 
+0

优秀的解决方案和简单,很好地完成。 – Kazar 2009-07-28 08:11:11

1

返回在64代子画面图形的日子里,如果你想要的东西站出来反对任何背景,则使用XOR位图传输。有人将此称为“反向视频”。

您可以绘制线条使用ControlPaint.DrawReversibleLine这种方式,但不会对文字工作。

CodeProject article演示了如何创建使用互操作,以gdi32.dll异或刷。

+0

那看起来不可怕吗? – peSHIr 2009-07-28 08:18:54

+0

它在相对平淡的背景下运作良好,但会给你非常难看的颜色。 – 2009-07-28 08:34:15

2

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

0

或者,如果它是允许的,你可以使用文本(例如,白色文本黑色背景),背景色(你的选择)。

否则,您需要捕获写入文本的矩形(对于每个帧),create the negative image of it,然后在矩形中获取median的颜色并使用它来写入文本。

一个更复杂的解决方案会让你使用两层(初始图片--L1和文本(透明背景,黑色文本)-L2), 并且在合并它们之前,从L2获取包含文本和改变的所有像素将文本的每个像素的颜色设置为L1的“负面”底层像素颜色值,但从“观看者”的角度来看,您不会获得太可用的内容。

0

这可能是the answer by reinier的一些变化。

  1. 绘制底层文本(由reinier提到的四个偏移的文本)不是黑色的,而是实际上与实际文本的前景颜色形成鲜明对比。
  2. 绘制文本两次:一次以对比色,但以粗体和/或稍大的尺寸,然后在文本前景颜色上。可能不得不用坐标来摆弄一下,甚至需要按照每个单词或甚至字符来绘制图形,以使两个通过很好地对齐,而不会给出一个丑陋的最终结果。
  3. Do what reinier suggested,但也许不是四次(四个方向),但也许三个甚至两次获得一种“阴影”的样子。
  4. 放开整个“使用API​​调用逐个像素绘制文本”的方法,并使用先进的多层合成技术,如WPF设计中的可用技术。

有关最后一个选项的一些示例,请查看SlideShare上Advanced OSM Cartography的幻灯片18和21。

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); 
}