【发布时间】:2009-08-04 21:25:29
【问题描述】:
我正在整理一个原型,以使用 XAML 创建 PNG 按钮。基本思想是可以从本地化字符串生成漂亮的渐变图像按钮,而不是让它们由任何类型的图形部门创建。
实际上我发现的最直接的例子是构建一个 C# 程序集和call it from PHP。我将其转换为纯 C#。这是我的基本工作原型的样子。
XAML 文件如下所示:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Width="640" Height="480">
<Grid x:Name="LayoutRoot">
<Button HorizontalAlignment="Left" VerticalAlignment="Top" Content="Add To Cart" FontFamily="Arial" FontSize="11" Height="24" FontWeight="Bold" Margin="0,3,0,0">
<Button.Background>
<LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFF3F3F3" Offset="0"/>
<GradientStop Color="#FFEBEBEB" Offset="0.5"/>
<GradientStop Color="#FFDDDDDD" Offset="0.502"/>
<GradientStop Color="#FFCDCDCD" Offset="1"/>
</LinearGradientBrush>
</Button.Background>
</Button>
</Grid>
Program.cs 看起来像:
class Program
{
static void Main(string[] args)
{
FileInfo xamlFile = new FileInfo("Button.xaml");
var inputXaml = File.ReadAllText(xamlFile.FullName);
Thread pngCreationThread = new Thread((ThreadStart) delegate()
{
GenImageFromXaml(inputXaml);
});
pngCreationThread.IsBackground = true;
pngCreationThread.SetApartmentState(ApartmentState.STA);
pngCreationThread.Start();
pngCreationThread.Join();
}
public static void GenImageFromXaml(string xaml)
{
var element = (FrameworkElement)XamlReader.Parse(xaml);
var pngBytes = GetPngImage(element);
using(BinaryWriter binWriter =
new BinaryWriter(File.Open(@"output.png", FileMode.Create)))
{
binWriter.Write(pngBytes);
}
}
private static byte[] GetPngImage(FrameworkElement element)
{
var size = new Size(element.Width, element.Height);
element.Measure(size);
element.Arrange(new Rect(size));
var renderTarget =
new RenderTargetBitmap((int)element.RenderSize.Width,
(int)element.RenderSize.Height,
96, 96,
PixelFormats.Pbgra32);
var sourceBrush = new VisualBrush(element);
var drawingVisual = new DrawingVisual();
using (DrawingContext drawingContext = drawingVisual.RenderOpen())
{
drawingContext.DrawRectangle(
sourceBrush, null, new Rect(
new Point(0, 0),
new Point(element.RenderSize.Width,
element.RenderSize.Height)));
}
renderTarget.Render(drawingVisual);
var pngEncoder = new PngBitmapEncoder();
pngEncoder.Frames.Add(BitmapFrame.Create(renderTarget));
using (var outputStream = new MemoryStream())
{
pngEncoder.Save(outputStream);
return outputStream.ToArray();
}
}
}
我想要的是可以用作模板的 XAML 文件,并且按钮中的实际字符串被换出。我的原型在基本层面上工作,从输入的 XAML 文件中渲染出图像。
但是,XAML 文件明确指定了高度和宽度。动态提供按钮本身上的字符串将是一个问题,因为宽度不会提前知道,并且任何字体修改也会弄乱它。
我正在寻找的是一种在运行时计算高度和宽度的方法,或者一种基于文本字符串预先计算它们的简单方法。有什么想法吗?
【问题讨论】: