0

RichTextBox を使用して、PNG に透明な背景を持たせることをあきらめました。また、画像オブジェクトを wmf に変換するために 2 つのファイルを書き込んでから読み取る必要がある Microsoft のコードが本当に好きではありません。メモリ ストリームに戻したので、Illustrator をクラックして開き、1 つのエモートを WMF に変換して、RTF が必要とする形式になっていると言われています。

同封されているのは、私が試している形式の画像です:

  • WMF big-smile.wmf (SO では WMF のアップロードが許可されていないため、これをリンクする必要がありました)
  • PNGbig-smile.png

私が今抱えている問題は、次のコードで画像が表示されないことです。

public string GetImage( string file, int width, int height ) {
    float dpiX;
    float dpiY;
    string rtfimage;

    using ( Graphics g= this.CreateGraphics() ) {
        dpiX=g.DpiX;
        dpiY=g.DpiY;
    }

    using ( MemoryStream ms=new MemoryStream() ) {
        byte[] data=File.ReadAllBytes( file );
        ms.Write( data, 0, data.Length );
        rtfimage=@"{\pict\wmetafile8\picw"+(int)( ( (float)width/dpiX )*2540 )
                            +@"\pich"+(int)( ( (float)height/dpiY )*2540 )
                            +@"\picwgoal"+(int)( ( (float)width/dpiX )*1440 )
                            +@"\pichgoal"+(int)( ( (float)height/dpiY )*1440 )
                            +" "
                    +BitConverter.ToString( ms.ToArray() ).Replace( "-", "" ).ToLower()
                            +"}";
    }
    return rtfimage;
}

次のコードは機能しますが (ただし、非 wmf ファイルのみ):

public static string GetEmbedImageString( Image image ) {
    Metafile metafile=null;
    float dpiX;
    float dpiY;

    using ( Graphics g=Graphics.FromImage( image ) ) {
        IntPtr hDC=g.GetHdc();
        metafile=new Metafile( hDC, EmfType.EmfOnly );
        g.ReleaseHdc( hDC );
    }

    using ( Graphics g=Graphics.FromImage( metafile ) ) {
        g.CompositingMode = CompositingMode.SourceOver;
        g.CompositingQuality = CompositingQuality.HighQuality;
        g.DrawImage( image, 0, 0 );
        g.Clear( Color.White );
        dpiX=g.DpiX;
        dpiY=g.DpiY;
    }

    IntPtr _hEmf=metafile.GetHenhmetafile();
    uint _bufferSize=GdipEmfToWmfBits( _hEmf, 0, null, MM_ANISOTROPIC,
    EmfToWmfBitsFlags.EmfToWmfBitsFlagsDefault );
    byte[] _buffer=new byte[_bufferSize];
    GdipEmfToWmfBits( _hEmf, _bufferSize, _buffer, MM_ANISOTROPIC,
                                EmfToWmfBitsFlags.EmfToWmfBitsFlagsDefault );
    IntPtr hmf=SetMetaFileBitsEx( _bufferSize, _buffer );
    string tempfile=Path.GetTempFileName();
    CopyMetaFile( hmf, tempfile );
    DeleteMetaFile( hmf );
    DeleteEnhMetaFile( _hEmf );

    var stream=new MemoryStream();
    byte[] data=File.ReadAllBytes( tempfile );
    //File.Delete (tempfile);
    int count=data.Length;
    stream.Write( data, 0, count );

    string proto=@"{\pict\wmetafile8\picw"+(int)( ( (float)image.Width/dpiX )*2540 )
                      +@"\pich"+(int)( ( (float)image.Height/dpiY )*2540 )
                      +@"\picwgoal"+(int)( ( (float)image.Width/dpiX )*1440 )
                      +@"\pichgoal"+(int)( ( (float)image.Height/dpiY )*1440 )
                      +" "
                      +BitConverter.ToString( stream.ToArray() ).Replace( "-", "" )
                      +"}";

    return proto;
}

どちらも、次のように RichTextBox コントロールに wmf ファイルを埋め込むための適切な文字列形式を返します。

{\pict\wmetafile8\picw[WIDTH]\pich[HEIGHT]\picwgoal[WIDTH (twips)]\pichgoal[HEIGHT (twips)] [HEX BYTE ARRAY OF FILE]}

WinForms RichTextBoxコンポーネントで動作する適切な文字列値を取得する方法を探しています。

これは非常に具体的な問題に関連する非常に具体的な質問だと思います。問題を再現するために十分なコードと詳細を提供しました。理想的には、この問題を経験したことがあり、ユーザーのクリップボードをいじることを伴わない回避策を見つけた場合 (私は、コピー/貼り付けの方法が非常に遅いだけでなく、ユーザーのクリップボードに干渉することを認識しています。私は古いクリップボードのデータをメモリに保存して元に戻すというクリップボードの問題の回避策についても認識していますが、場合によってはデータを元に戻すことができないという欠陥がないわけではありません)。

2015 年までには、WinForms の RichTextBox コントロールは .NET での 10 年間に進化したと思うかもしれませんが、私は簡単な道を探しているわけではありません。

もう 1 つのオプションは、WPF を使用することの他のすべての問題 (および利点) にパンドラの箱を開く WPF を使用することであることも認識しています。私は、全体的にはるかに成熟した言語に固執することを好みます.

私が助けを必要としているのは、非常に具体的なものです。この件に関して別のことを参照する別のスレッドを投稿しましたが、具体的ではないという主張で閉鎖されました。これは同じ質問ですが、さらに多くの詳細が含まれています。

C# > WinForms > RichTextBox > 文字列を非常に具体的な形式にする必要があるイメージで文字列を置き換え、WMF では非常に具体的な書式タグを文字列として持つ非常に具体的なバイト文字列として使用する > 透明性を維持しながら必要な形式で画像を適切にロードする際の問題または、ベクトルの透明度を維持できない場合は、少なくとも定義可能な色を使用します。

4

0 に答える 0