0

我在谷歌上找不到答案。

我有很多字符串要在画布上呈现。每个字符串都将使用从 ItemsControl 调用的字符串转换器中的 FormattedText() 方法创建。

代码的问题在于,它需要 RenderTargetBitmap() 中的一个大得离谱的宽度和高度来显示不同位置的所有字符串,即使每个字符串的实际宽度约为 700,实际高度为 40。(看起来像虽然 RenderTargetBitmap() 需要足够大,不仅可以容纳字符串,还可以容纳该字符串在绘图上下文中的位置)。

您如何创建一个仅包含格式化文本的正确实际高度和宽度的单个格式化文本字符串的图像,然后将该图像正确定位在“左上角”点?

从 ItemsControl 调用的转换器定义为:

 public class InkConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var stringviewmodel = value as StringViewModel;
        if (stringviewmodel != null)
        {
           stringviewmodel.ft = new FormattedText(
           stringviewmodel.text,
           CultureInfo.CurrentCulture,
           FlowDirection.LeftToRight,
           new Typeface(new FontFamily("Segoe Script"), FontStyles.Italic, FontWeights.Normal, FontStretches.Normal),
           stringviewmodel.emSize,
           stringviewmodel.color);

           stringviewmodel.ft.TextAlignment = TextAlignment.Left;
           stringviewmodel.ft.LineHeight =(double)stringviewmodel.lineheight;

            Image myImage = new Image();

            DrawingVisual dw = new DrawingVisual();
            DrawingContext dc = dw.RenderOpen();
            dc.DrawText(stringviewmodel.ft, stringviewmodel.topleft);
            dc.Close();


            int Width = 2000;
            int Height = 2000;
            RenderTargetBitmap bmp = new RenderTargetBitmap(Width, Height, 120, 96, PixelFormats.Pbgra32);  

            bmp.Render(dw);
            myImage.Source = bmp;

            return myImage;
        }
        else
        {
            return null;
        }
    }

    public object  ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }

}

附录:

我写了这个解决了这个问题,但没有回答我的问题。(删除了 gt 和 lt 符号)。

  1. 将 itemscontrol 更改为包括:

    ItemsControl.ItemContainerStyle Style TargetType="{x:Type FrameworkElement} Setter Property="Canvas.Top" Value="{Binding topleft.Y}" Setter Property="Canvas.Left" Value="{Binding topleft.X}" Setter属性="高度" 值="{绑定英尺高度}"

  2. 移除了转换器的所有定位。转换器现在读取为

    public object Convert(object value, Type targetType, object parameter,   
    System.Globalization.CultureInfo culture)
    {
        var stringviewmodel = value as StringViewModel;
        if (stringviewmodel != null)
        {
           stringviewmodel.ft = new FormattedText(
           stringviewmodel.text,
           CultureInfo.CurrentCulture,
           FlowDirection.LeftToRight,
           new Typeface(new FontFamily("Segoe Script"), FontStyles.Italic, FontWeights.Normal, FontStretches.Normal),
           stringviewmodel.emSize,
           stringviewmodel.color);
    
    
            stringviewmodel.ft.TextAlignment = TextAlignment.Left;
            stringviewmodel.ft.LineHeight =(double)stringviewmodel.lineheight;
    
            Image myImage = new Image();
            DrawingVisual dw = new DrawingVisual();
            DrawingContext dc = dw.RenderOpen();
    
            dc.DrawText(stringviewmodel.ft, new Point(0,0));
    
            dc.Close();
    
           double width = stringviewmodel.ft.text.Width - stringviewmodel.text.OverhangLeading -   stringviewmodel.text.OverhangTrailing;
    
            RenderTargetBitmap bmp = new RenderTargetBitmap(
            (int)(width,
            (int)stringviewmodel.ft.Height,
            96d,            
            96d,
            PixelFormats.Pbgra32);  
    
            bmp.Render(dw);
            myImage.Source = bmp;
    
            return myImage;
        }
        else
        {
            return null;
        }
    }
    
4

1 回答 1

1

你生活在过去,所有看起来像 WinForms 的代码......这就是 WPF!首先,您不需要任何FormattedText对象,因为您可以非常轻松地在 XAML 中完成这一切。以这个基本示例为例:

<TextBlock Name="TextBlockToGetImageFrom">
    <Run FontFamily="Arial" FontWeight="Bold" FontSize="40" Foreground="Red" Text="W" />
    <Run FontFamily="Tahoma" Text="indows" FontSize="20" BaselineAlignment="Bottom" />
    <Run FontFamily="Arial" FontWeight="Bold" FontSize="40" Foreground="Red" Text=" P" />
    <Run FontFamily="Tahoma" Text="resentation" FontSize="20" BaselineAlignment="Center" />
    <Run FontFamily="Arial" FontWeight="Bold" FontSize="40" Foreground="Red" Text=" F" />
    <Run FontFamily="Tahoma" Text="ormat" FontSize="20" BaselineAlignment="Top" />
</TextBlock>

在此处输入图像描述

这只是展示了 WPF 的一些灵活性,还有更多的选项没有在这里展示。因此,一旦您根据需要进行了设置,您就可以使用TextBlock将其转换为图像,只需几行代码:RenderTargetBitmap

RenderTargetBitmap renderTargetBitmap = 
    new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
renderTargetBitmap.Render(TextBlockToGetImageFrom); 
PngBitmapEncoder pngImage = new PngBitmapEncoder();
pngImage.Frames.Add(BitmapFrame.Create(renderTargetBitmap));
using (Stream fileStream = File.Create(filePath))
{
    pngImage.Save(fileStream);
}
于 2014-09-02T13:26:31.290 回答