2010-09-15 75 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