Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在WPF中创建旋转文本_C#_Wpf_Text - Fatal编程技术网

C# 在WPF中创建旋转文本

C# 在WPF中创建旋转文本,c#,wpf,text,C#,Wpf,Text,我正在尝试创建一些旋转文本,并将该图像保存到PNG文件中。生成的PNG不应大于所需大小(或最小填充)。我让它工作,只要没有旋转,但一旦我旋转文本,它会被剪掉在文件中。我确信这与调整旋转变换器的CenterX和CenterY或创建平移变换器有关,但我找不到任何关于如何正确操作的信息,我的尝试和错误测试变成了尝试和挫折 我的示例代码如下。我在寻找一个可以在任意角度下工作的解决方案,而不仅仅是-45度 最后,如果有人知道如何满足这些要求,但是说使用“旧式”图形对象而不是WPF工具,我也愿意接受这种解决

我正在尝试创建一些旋转文本,并将该图像保存到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;。虽然这给了我一个更好的答案,但它仍然被剪掉了。经过更多的调查