Загрузка WMF не удалась, но преобразование PNG в WMF прошло успешно, но потеря фона

Работая с RichTextBox, я отказался от попыток сделать PNG прозрачным фоном, и мне действительно не нравится код от Microsoft, который для преобразования объекта изображения в wmf необходимо написать два файла, а затем прочитать он вернулся в поток памяти, поэтому я открыл "Illustrator" и преобразовал одну эмоцию в WMF, так что якобы в формате, который требует RTF.

Прилагаются изображения в форматах, которые я пытаюсь:

  • WMF big-smile.wmf (пришлось связать это, так как SO не позволяет загружать WMF)
  • PNG большой 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;
}

Они оба возвращают соответствующий формат строки для встраивания файла wmf в элемент управления RichTextBox следующим образом

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

Я ищу способ получить соответствующее строковое значение для этого, который работает с компонентом WinForms RichTextBox.

Я чувствую, что это ОЧЕНЬ конкретный вопрос, относящийся к очень специфической проблеме, и он дал более чем достаточно кода и деталей, чтобы вы могли продублировать проблему. В идеале, если вы столкнулись с этой проблемой и нашли обходной путь, который не включает в себя работу с буфером обмена пользователя (мне известен метод копирования / вставки, который не только намного медленнее, но и мешает работе с буфером обмена пользователя. I Я также знаю об обходной проблеме буфера обмена, которая хранит старые данные буфера обмена в памяти и устанавливает их обратно, однако это не без недостатка, в некоторых случаях данные не могут быть восстановлены).

Я не ищу легкий путь, хотя к 2015 году вы бы подумали, что элемент управления RichTextBox в WinForms эволюционировал бы в течение 10 лет в.NET.

Я также понимаю, что другой вариант - использовать WPF, который открывает ящик Пандоры для решения всех других проблем (а также преимуществ) использования WPF. Я предпочитаю придерживаться языка, который в целом гораздо более зрелый.

То, что мне нужна помощь, очень специфично: я разместил другую ветку, ссылающуюся на что-то еще по этому вопросу, но она была закрыта под утверждением, что она не была конкретной. Это тот же вопрос, со множеством других деталей, в надежде, что вы увидите, насколько это конкретно.

C#> WinForms> RichTextBox> Заменить строку на изображение, которое требует, чтобы формат был очень специфичным, а в WMF - очень специфической байтовой строкой с очень специфическими тегами форматирования в виде строки> Проблема с загрузкой изображений должным образом в требуемом формате при сохранении прозрачности или, по крайней мере, используя определяемый цвет, если не удается сохранить прозрачность вектора.

0 ответов

Другие вопросы по тегам