首页 文章

如何在Image中使用RenderTargetBitmap呈现FormattedText?

提问于
浏览
0

我在谷歌上找不到答案 .

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

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

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

从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符号) .

  • 更改了itemscontrol以包括:

ItemsControl.ItemContainerStyle样式TargetType =“{x:Type FrameworkElement} Setter Property =”Canvas.Top“Value =”“Setter Property =”Canvas.Left“Value =”“Setter Property =“Height”Value =“

  • 从转换器中删除了所有定位 . 转换器现在读为
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;
    }
}

1 回答

  • 1

    您需要任何 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>
    

    enter image description here

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

    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);
    }
    

相关问题