Я пытаюсь преобразовать Drawing.Bitmap
в Imaging.Metafile
для вставки метафайла в Forms.RichTextBox
.(Для справки, встраивание растрового изображения в метафайл является рекомендуемой практикой для помещения растрового изображения в формат Richtext (см. Спецификация Rich Text Format (RTF), версия 1.9.1, стр. 149.) К сожалению, это также, кажется, единственный способ встраиванияизображение в Forms.RichTextBox, поскольку я не могу заставить работать любые зависящие от устройства или устройства способы вставки растрового изображения в RichTextBox.)
Позже я должен получить данные пикселей изметафайл.Я требую, чтобы пиксели метафайла точно совпадали с пикселями растрового изображения.Однако когда я выполняю преобразование, пиксели слегка изменяются.(Возможно, из-за GDI Image Color Management (ICM)?)
Вот мой метод:
public static Imaging.Metafile BitmapToMetafileViaGraphicsDrawImage(Forms.RichTextBox rtfBox, Drawing.Bitmap bitmap)
{
Imaging.Metafile metafile;
using (IO.MemoryStream stream = new IO.MemoryStream())
using (Drawing.Graphics rtfBoxGraphics = rtfBox.CreateGraphics())
{
IntPtr pDeviceContext = rtfBoxGraphics.GetHdc();
metafile = new Imaging.Metafile(stream, pDeviceContext);
using (Drawing.Graphics imageGraphics = Drawing.Graphics.FromImage(metafile))
{
//imageGraphics.DrawImage(bitmap, new Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height));
imageGraphics.DrawImageUnscaled(bitmap, new Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height));
}
rtfBoxGraphics.ReleaseHdc(pDeviceContext);
}
return metafile;
}
В этом случае я получаю доступ к пикселям метафайла следующим образом:
metafile.Save(stream, Imaging.ImageFormat.Png);
Bitmap bitmap = new Bitmap(stream, false);
bitmap.GetPixel(x, y);
Я также безуспешно пытался использовать технику BitBlt.
Техника BitBlt:
[System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")]
static extern int BitBlt(
IntPtr hdcDest, // handle to destination DC (device context)
int nXDest, // x-coord of destination upper-left corner
int nYDest, // y-coord of destination upper-left corner
int nWidth, // width of destination rectangle
int nHeight, // height of destination rectangle
IntPtr hdcSrc, // handle to source DC
int nXSrc, // x-coordinate of source upper-left corner
int nYSrc, // y-coordinate of source upper-left corner
System.Int32 dwRop // raster operation code
);
public static Imaging.Metafile BitmapToMetafileViaBitBlt(Forms.RichTextBox rtfBox, Drawing.Bitmap bitmap)
{
const int SrcCopy = 0xcc0020;
Graphics bitmapGraphics = Graphics.FromImage(bitmap);
IntPtr pBitmapDeviceContext = bitmapGraphics.GetHdc();
RectangleF rect = new RectangleF(new PointF(0, 0), new SizeF(bitmap.Width, bitmap.Height));
Imaging.Metafile metafile = new Imaging.Metafile(pBitmapDeviceContext, rect);
Graphics metafileGraphics = Graphics.FromImage(metafile);
IntPtr metafileDeviceContext = metafileGraphics.GetHdc();
BitBlt(pBitmapDeviceContext, 0, 0, bitmap.Width, bitmap.Height,
metafileDeviceContext, 0, 0, SrcCopy);
return metafile;
}
Я даже не уверен, что эта техника корректнакопирование пиксельных данных.Эта методика не работает, когда я пытаюсь получить доступ к данным в метафайле позже:
IntPtr h = metafile.GetHenhmetafile(); // ArgumentException "Parameter is not valid."
byte[] data;
uint size = GetEnhMetaFileBits(h, 0, out data);
data = new byte[size];
GetEnhMetaFileBits(h, size, out data);
stream = new IO.MemoryStream(data);
Как преобразовать растровое изображение в метафайл без изменения пикселей, а затем позже получить данные пикселей снова?Спасибо!
Установка разрешения растрового изображения
Вот как я пытаюсь установить разрешение растрового изображения так, чтобы разрешение метафайла соответствовало:
Drawing.Bitmap bitmap = new Drawing.Bitmap(width, height,
Imaging.PixelFormat.Format32bppArgb); // Use 32-bit pixels so that each component (ARGB) matches up with a byte
// Try setting the resolution to see if that helps with conversion to/from metafiles
Drawing.Graphics rtfGraphics = rtfBox.CreateGraphics();
bitmap.SetResolution(rtfGraphics.DpiX, rtfGraphics.DpiY);
// Set the pixel data
...
// Return the bitmap
return bitmap;
rtfBoxтот же самый, отправленный BitmapToMetafileViaGraphicsDrawImage.