2010-09-15 3 views
8

Sto scherzando con il sdk di Windows Phone 7 e sto cercando di rendere lo schermo simile a un vecchio display digitale di moda. In questo momento sto cercando di capire come rendere il testo "splendente" come uno di quei fantastici orologi digitali. Questo è il genere di cosa che presumerei che useresti gli shader, ma sembra che gli shader siano disabilitati per l'uso sul sistema operativo Windows Phone 7. Qualche idea? Per essere più specifici, voglio che il testo sembri una fonte di luce e che il colore "si disperda" leggermente rispetto al carattere reale.Il modo migliore per ottenere un telefono windows con effetto bagliore 7

+2

retagged a silverlight e C# invece delle versioni 4.0 di quelli. Winphone7 non usa Silverlight 4, è una versione 3. custom di Silverlight. –

+1

Immergetelo in alcuni Ready Brek :) –

risposta

12

Direi che è una scelta tra l'utilizzo di un'immagine come carattere o la sfocatura con WriteableBitmap.

L'utilizzo di un'immagine di font preconfigurata consente di rendere le lettere complesse come si desidera e di ottenere buoni risultati. SpriteFont2 è comodo in quanto può generare SpriteSheet con effetti come bagliore, tratto, ombra ed esportare un file xml contenente le posizioni delle lettere. Aggiungere i file png e xml generati alla soluzione e modificare l'azione di compilazione per il contenuto, inoltre verificare che si sia fatto riferimento a System.Xml.Linq.

È quindi possibile utilizzare la seguente classe.

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

Uso

//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"); 

Se si vuole sfocare vedere un'implementazione BoxBlur here o utilizzare WriteableBitmapEx.Convolute.

+0

Grazie! Usare SpriteFont2 è un ottimo suggerimento. – CoderDennis

0

Dovresti fare una copia del TextBlock a cui vuoi dare il bagliore. Associare la proprietà text del nuovo elemento alla proprietà text dell'oggetto originale (utilizzando il binding ElementName). Fai lo stesso per posizione/altezza/larghezza ecc. O qualsiasi altra proprietà che ritieni cambierà sull'oggetto originale. Imposta una trasparenza sul nuovo oggetto e un Effetto sfocatura. Questo ti darà un bell'effetto bagliore che desideri.

+1

Come notato nei commenti sull'altra risposta a questa domanda, gli Effetti sono stati rimossi e non sono più supportati in WP7. – CoderDennis

+0

il modo di pensare mi ha portato a una soluzione, grazie – CuiPengFei