2009-07-28 62 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); 
}