Я собираю прототип для использования XAML для создания кнопок PNG. Основная идея заключается в том, что красивые градиентные кнопки изображения могут быть сгенерированы из локализованных строк вместо того, чтобы создавать их любым графическим отделом.
Самый простой пример, который я нашел, на самом деле заключался в том, чтобы собрать сборку C # и вызвать ее из 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 явно указывает высоту и ширину. Это будет проблемой, если строка на самой кнопке будет предоставлена динамически, так как ширина не будет известна заранее, и любые изменения шрифта могут помешать ей.
То, что я ищу, - это способ рассчитать высоту и ширину либо во время выполнения, либо простой способ предварительно рассчитать их на основе текстовой строки. Есть идеи?