Загрузка WMF не удалась, но преобразование PNG в WMF прошло успешно, но потеря фона
Работая с RichTextBox, я отказался от попыток сделать PNG прозрачным фоном, и мне действительно не нравится код от Microsoft, который для преобразования объекта изображения в wmf необходимо написать два файла, а затем прочитать он вернулся в поток памяти, поэтому я открыл "Illustrator" и преобразовал одну эмоцию в WMF, так что якобы в формате, который требует RTF.
Прилагаются изображения в форматах, которые я пытаюсь:
- WMF big-smile.wmf (пришлось связать это, так как SO не позволяет загружать WMF)
- 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 - очень специфической байтовой строкой с очень специфическими тегами форматирования в виде строки> Проблема с загрузкой изображений должным образом в требуемом формате при сохранении прозрачности или, по крайней мере, используя определяемый цвет, если не удается сохранить прозрачность вектора.