我正在尝试创建一些旋转的文本并将该图像保存到 PNG 文件中。生成的 PNG 不应大于所需(或最小填充)。只要没有旋转,我就可以使用它,但是一旦我旋转文本,它就会在文件中被剪掉。我确信这与调整 RotateTransform 的 CenterX 和 CenterY 或创建 TranslateTransform 有关,但我找不到任何关于如何正确执行此操作的信息,并且我的试错测试已经变成了试验-和-沮丧。
我的示例代码如下。我正在寻找一种可以使用任意角度而不仅仅是-45度的解决方案。
最后,如果有人知道如何满足这些要求,但说使用“旧式”图形对象而不是 WPF 工具,我也愿意接受该解决方案。
private static void CreateImageFile()
{
FormattedText ft;
Geometry textBox;
string fontName;
Typeface face;
DrawingVisual viz;
RotateTransform rt;
TranslateTransform tt;
Rect rect;
RenderTargetBitmap bmp;
PngBitmapEncoder encoder;
ft = CreateText("Lorem ipsum dolor sit amet, consectetur adipisicing" + Environment.NewLine + "elit, sed do eiusmod tempor", "Verdana", 12, false, false);
textBox = ft.BuildHighlightGeometry(new Point());
fontName = "Arial";
face = new Typeface(fontName);
// now create the visual we'll draw them to
viz = new DrawingVisual();
rt = new RotateTransform() { Angle = -45 };
rect = rt.TransformBounds(ft.BuildHighlightGeometry(new Point(0, 0)).Bounds);
using (DrawingContext dc = viz.RenderOpen())
{
dc.PushTransform(rt);
dc.DrawText(ft, new Point(0, 0));
dc.Pop();
}
bmp = new RenderTargetBitmap((int)rect.Width, (int)rect.Height, 96, 96, PixelFormats.Pbgra32);
bmp.Render(viz);
encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bmp));
using (FileStream file = new FileStream("TextImage.png", FileMode.Create))
encoder.Save(file);
}
private static FormattedText CreateText(string text, string typeface, double fontSize, bool bold, bool italic)
{
FontStyle fontStyle = FontStyles.Normal;
FontWeight fontWeight = FontWeights.Medium;
if (bold == true) fontWeight = FontWeights.Bold;
if (italic == true) fontStyle = FontStyles.Italic;
// Create the formatted text based on the properties set.
FormattedText formattedText = new FormattedText(
text,
CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
new Typeface(new FontFamily(typeface),
fontStyle,
fontWeight,
FontStretches.Normal),
fontSize,
Brushes.Black, // This brush does not matter since we use the geometry of the text.
null,
TextFormattingMode.Display
);
return formattedText;
}
更新
基于以下一些建议,我决定在 GUI 中尝试不同的策略和实验。我创建了一个这样的窗口:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="160" Width="160" Loaded="Window_Loaded">
<Grid>
<Canvas Name="WorkCanvas" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock RenderTransformOrigin="0.5,0.5">
<TextBlock.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="-45"/>
<TranslateTransform/>
</TransformGroup>
</TextBlock.RenderTransform>This is a test</TextBlock>
</Canvas>
</Grid>
</Window>
如您所见,它同时使用了 theRotateTransform
和建议RenderTransformOrigin
的 ,结果如下图所示。而且,如您所见,文本没有通过Canvas
. 这似乎是我的全部问题。如何旋转文本并使其正确居中。
更新 2
这次我决定尝试 aGrid
而不是 a Canvas
,我现在可以让文本在网格中正确居中,但由于我不能使用FormattedText
对象,我似乎无法测量实际的边界框。TextBlock
或 的所有测量值Grid
都返回,就好像它根本没有旋转(查看ActualWidth
、ActualHeight
和DesiredSize
)。如果我无法获得旋转的边界框大小,我无法保存 PNG 而不会被剪裁。
哦,我尝试在未旋转的网格中旋转文本并旋转网格本身,在尝试确定尺寸时都给出相同的结果。