2010-09-15 76 views
8

我正在搞亂Windows Phone 7 sdk,我試圖讓屏幕看起來像一箇舊時尚的數字顯示器。現在我試圖弄清楚如何讓文字像發光一樣,像那些很酷的數字時鐘一樣。這是我假設你會着眼於使用着色器的事情,但似乎着色器被禁用以用於Windows Phone 7操作系統。有任何想法嗎?更具體地說,我希望文本看起來好像是光源,並且顏色從實際字體略微「流血」。獲得發光效果的最佳方式windows phone 7

+2

被重新綁定到silverlight和c#而不是4.0版本的那些。 winphone7不使用silverlight 4,它是silverlight的3.custom版本。 – 2010-09-15 18:22:04

+1

將它浸入一些Ready Brek :) – 2011-03-25 22:25:43

回答

12

我想說,它使用圖像作爲字體或與WriteableBitmap模糊之間的選擇。

使用預製的字體圖像可以讓字母變得複雜,並且應該表現良好。 SpriteFont2很方便,因爲它可以生成具有發光效果,筆畫效果,陰影效果和導出包含字母位置的xml文件的SpriteSheet。 將生成的png和xml文件添加到解決方案中,並將Build Action更改爲內容,同時檢查是否引用了System.Xml.Linq。

然後可以使用以下類。

public static class BitmapFont 
{ 
    private class FontInfo 
    { 
     public FontInfo(WriteableBitmap image, Dictionary<char, Rect> metrics) 
     { 
      this.Image = image; 
      this.Metrics = metrics; 
     } 
     public WriteableBitmap Image { get; private set; } 
     public Dictionary<char, Rect> Metrics { get; private set; } 
    } 

    private static Dictionary<string, FontInfo> fonts = new Dictionary<string, FontInfo>(); 
    public static void RegisterFont(string fontFile, string fontMetricsFile) 
    { 
     string name = System.IO.Path.GetFileNameWithoutExtension(fontFile); 
     BitmapImage image = new BitmapImage(); 

     image.SetSource(App.GetResourceStream(new Uri(fontFile,UriKind.Relative)).Stream); 
     var metrics = XDocument.Load(fontMetricsFile); 
     var dict = (from c in metrics.Root.Elements() 
        let key = (char)((int)c.Attribute("key")) 
        let rect = new Rect((int)c.Element("x"), (int)c.Element("y"), (int)c.Element("width"), (int)c.Element("height")) 
        select new { Char = key, Metrics = rect }).ToDictionary(x => x.Char, x => x.Metrics); 

     fonts.Add(name,new FontInfo(new WriteableBitmap(image),dict)); 
    } 

    public static WriteableBitmap DrawFont(string text, string fontName) 
    { 
     var font = fonts[fontName]; 

     var letters = text.Select(x => font.Metrics[x]).ToArray(); 
     var height = (int)letters.Max(x => x.Height); 
     var width = (int)letters.Sum(x => x.Width); 

     WriteableBitmap bmp = new WriteableBitmap(width, height); 

     int[] source = font.Image.Pixels, dest = bmp.Pixels; 
     int sourceWidth = font.Image.PixelWidth; 
     int destX = 0; 
     foreach (var letter in letters) 
     { 
      for (int sourceY = (int)letter.Y, destY = 0; destY < letter.Height; sourceY++, destY++) 
      { 
       Array.Copy(source, (sourceY * sourceWidth) + (int)letter.X, dest, (destY * width) + destX, (int)letter.Width); 
      } 
      destX += (int)letter.Width; 
     } 

     return bmp; 
    } 

    public static Rectangle[] GetElements(string text, string fontName) 
    { 
     var font = fonts[fontName]; 

     return (from c in text 
       let r = font.Metrics[c] 
       select new Rectangle 
       { 
        Width = r.Width, 
        Height = r.Height, 

        Fill = new ImageBrush { 
         ImageSource = font.Image, 
         AlignmentX=AlignmentX.Left, 
         AlignmentY=AlignmentY.Top, 
         Transform = new TranslateTransform { X = -r.X, Y = -r.Y }, 
         Stretch=Stretch.None       
        }, 
       }).ToArray(); 
    } 
} 

使用

//Register the font once. 
BitmapFont.RegisterFont("Font.png", "Metrics.xml"); 

//Draws the text to a new bitmap, font name is image name without extension. 
image.Source = BitmapFont.DrawFont(DateTime.Now.ToLongTimeString(), "Font"); 

//Alternatively put these elements in a horizontal StackPanel, or ItemsControl 
//This doesn't create any new bitmaps and should be more efficient. 
//You could alter the method to transform each letter too. 
BitmapFont.GetElements(DateTime.Now.ToLongTimeString(), "Font"); 

如果你想模糊看到一個BoxBlur實現here或使用WriteableBitmapEx.Convolute

+0

謝謝!使用SpriteFont2是一個很好的建議。 – CoderDennis 2011-03-28 06:01:44

0

您應該製作一份您想要發光的TextBlock副本。將新項目的文本屬性綁定到原始項目的文本屬性(使用ElementName綁定)。對於位置/高度/寬度等,或者您認爲會在原始項目上改變的任何其他屬性,請執行相同操作。設置新項目的透明度以及模糊效果。這會給你一個很酷的發光效果,你想要的。

+1

正如對此問題的其他答案的評論中指出的那樣,效果已被刪除,並且在WP7中不再受支持。 – CoderDennis 2011-03-25 04:43:26

+0

的思維方式導致我的解決方案,謝謝 – CuiPengFei 2011-06-14 03:57:12