加载WMF失败,但将PNG转换为WMF成功但失去了背景

时间:2015-06-15 06:00:08

标签: c# .net winforms graphics wmf

使用RichTextBox,我放弃了尝试让PNG具有透明背景,我真的不喜欢Microsoft的代码,为了将图像对象转换为wmf,你必须写两个文件,然后把它读回内存流,所以我破解了打开的Illustrator,并将一个表情转换为WMF,因此据称它的格式是RTF所需。

附上我正在尝试的格式的图像:

  • WMF big-smile.wmf(必须将此链接为SO,因为不允许上传WMF)
  • PNG big-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年内发展。

我也意识到,另一种选择是使用WPF打开Pandora的盒子来解决使用WPF的所有其他问题(以及好处)。我更喜欢坚持总体上更成熟的语言。

我需要帮助的是非常具体的:我发布了另一个引用此事的其他线程,但是根据声称它并不具体而已经关闭了。这是同样的问题,有许多更多的细节,希望你会看到这是多么具体。

C#> WinForms> RichTextBox>将Image替换为需要格式非常具体的字符串,并将WMF替换为非常特定的字节字符串,并将非常特定的格式化标记作为字符串>在保持透明度的情况下使图像以所需格式正确加载的问题或者如果无法保持矢量的透明度,至少使用可定义的颜色。

0 个答案:

没有答案