C# 在WPF中创建旋转文本
我正在尝试创建一些旋转文本,并将该图像保存到PNG文件中。生成的PNG不应大于所需大小(或最小填充)。我让它工作,只要没有旋转,但一旦我旋转文本,它会被剪掉在文件中。我确信这与调整旋转变换器的CenterX和CenterY或创建平移变换器有关,但我找不到任何关于如何正确操作的信息,我的尝试和错误测试变成了尝试和挫折 我的示例代码如下。我在寻找一个可以在任意角度下工作的解决方案,而不仅仅是-45度 最后,如果有人知道如何满足这些要求,但是说使用“旧式”图形对象而不是WPF工具,我也愿意接受这种解决方案C# 在WPF中创建旋转文本,c#,wpf,text,C#,Wpf,Text,我正在尝试创建一些旋转文本,并将该图像保存到PNG文件中。生成的PNG不应大于所需大小(或最小填充)。我让它工作,只要没有旋转,但一旦我旋转文本,它会被剪掉在文件中。我确信这与调整旋转变换器的CenterX和CenterY或创建平移变换器有关,但我找不到任何关于如何正确操作的信息,我的尝试和错误测试变成了尝试和挫折 我的示例代码如下。我在寻找一个可以在任意角度下工作的解决方案,而不仅仅是-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
和建议的RenderTransferMorigin
,结果如下图所示。而且,正如您所看到的,文本不会穿过画布的中间。那似乎是我的全部问题。如何旋转文本并使其正确居中
更新2
这次我决定尝试使用网格
而不是画布
,现在我可以在网格中正确居中放置文本,但是由于我不能使用格式化文本
对象,我似乎无法测量实际的边界框。文本块
或网格
的所有测量值返回时,就好像它根本没有旋转一样(查看实际宽度
,实际高度
,以及所需大小
)。如果无法获得旋转的边界框大小,则无法保存PNG而不进行剪裁
哦,我试着在一个未旋转的网格中旋转文本和旋转网格本身,在尝试确定尺寸时都会得到相同的结果。我认为您缺少的是需要设置为0.5,0.5,以便旋转变换围绕图像的中心,而不是左上角边缘
更新
作为对您上述更新的回应。问题在于使用画布。如果完全删除变换,您将看到文本块一开始没有居中。它实际上是绕着中心旋转的,只是中心不是画布的中心。试试这个:
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock TextAlignment="Center" RenderTransformOrigin="0.5,0.5">
<TextBlock.RenderTransform>
<RotateTransform Angle="-45"/>
</TextBlock.RenderTransform>
This is a test
</TextBlock>
</Grid>
这是一个测试
我认为您缺少的是需要设置为0.5,0.5,以便旋转变换围绕图像的中心,而不是左上角边缘
更新
作为对您上述更新的回应。问题在于使用画布。如果完全删除变换,您将看到文本块一开始没有居中。它实际上是绕着中心旋转的,只是中心不是画布的中心。试试这个:
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock TextAlignment="Center" RenderTransformOrigin="0.5,0.5">
<TextBlock.RenderTransform>
<RotateTransform Angle="-45"/>
</TextBlock.RenderTransform>
This is a test
</TextBlock>
</Grid>
这是一个测试
您可以尝试将文本包装到具有RenderTransferMorigin的元素中。对该元素进行更改。尝试画布或网格。您可以尝试将文本包装到具有RenderTransferMorigin的元素中。对该元素进行更改。试试帆布或网格。在马特和kbo4sho88的帮助下,我终于找到了正确的方法。除了其他海报的帮助外,我最终发现我需要调用TransformToVisual和TransformBounds来获得正确文件大小所需的边界框。但是,在此之前,我必须调用Measure and Arrange,因为这些对象没有显示在屏幕上
呸
当然,这只是一个示例(但有效)方法,最后一个方法将被参数化
拼图的最后一部分是在上找到的,在马特和kbo4sho88的帮助下,我终于找到了正确的方法。除了其他海报的帮助外,我最终发现我需要调用TransformToVisual和TransformBounds来获得正确文件大小所需的边界框。但是,在此之前,我必须调用Measure and Arrange,因为这些对象没有显示在屏幕上
呸
当然,这只是一个示例(但有效)方法,最后一个方法将被参数化
<谜题的最后部分在找到了故事情节板吗?你需要一个独立的PNG吗?@不,我没有考虑故事板。故事板如何获得独立的图像文件。是的,这个我需要一个文件,这个不是用来在屏幕上显示的。一个水印最终会被添加到一个PDF文档中,那么故事板就不起作用了。你考虑过故事板吗?你需要一个独立的PNG吗?@不,我没有考虑故事板。故事板如何获得独立的图像文件。是的,这个我需要一个文件,这个不是用来在屏幕上显示的。它是用于最终将添加到PDF文档中的水印。然后,not storyboard将不起作用。在上面的示例中,我没有看到RenderTransferorMorigin,但从MSDN描述中可以看出,如果我说rt.CenterX=textBox.Bounds.Width/2;和rt.CenterY=textBox.Bounds.Height/2;。虽然这给了我一个更好的答案,但它仍然被剪掉了。经过更多的调查