【发布时间】:2012-09-27 19:17:28
【问题描述】:
我正在尝试创建一些旋转文本并将该图像保存到 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>
如您所见,它同时使用了RotateTransform 和建议的RenderTransformOrigin,结果如下图所示。而且,如您所见,文本确实不穿过Canvas 的中间。 那个似乎是我的全部问题。如何旋转文本并使其正确居中。
更新 2
我决定这次尝试使用Grid 而不是Canvas,我现在可以让文本在网格中正确居中,但由于我不能使用FormattedText 对象,我似乎无法测量实际的边界框。 TextBlock 或 Grid 的所有测量值都会返回,就好像它根本没有旋转一样(查看 ActualWidth、ActualHeight 和 DesiredSize)。如果我无法获得旋转的边界框大小,我无法保存 PNG 而不会被剪裁。
哦,我尝试在未旋转的网格中旋转文本并旋转网格本身,在尝试确定尺寸时都给出相同的结果。
【问题讨论】:
-
你考虑过故事板吗?您需要一个独立的 png 吗?
-
@Blam 不,我没有考虑故事板。故事板将如何获得独立的图像文件。是的,我需要一个文件,这不是为了在屏幕上显示。它用于最终将添加到 PDF 文档中的水印。
-
那么不是故事板是行不通的。