0

Google で答えが見つかりません。

キャンバスに表示する文字列がたくさんあります。各文字列は、ItemsControl から呼び出される文字列コンバーター内で FormattedText() メソッドを使用して作成されます。

コードの問題は、各文字列の実際の幅はおよそ 700、実際の高さは 40 であるにも関わらず、すべての文字列を異なる位置に表示するには、RenderTargetBitmap() で非常に大きな幅と高さが必要になることです。ただし、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.ItemContainerStyle Style TargetType="{x:Type FrameworkElement} Setter Property="Canvas.Top" Value="{Binding topleft.Y}" Setter Property="Canvas.Left" Value="{Binding topleft.X}" セッターProperty="Height" Value="{Binding ft.Height}"

  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 に答える