我试图将Drawing.Bitmap
转换为Imaging.Metafile
,以便将元文件插入到Forms.RichTextBox
中。 (作为参考,将位图嵌入图元文件是将位图置入richtext的推荐做法(请参阅RTF格式(RTF)规范版本1.9.1,第149页)。不幸的是,它似乎也是嵌入一个图像到一个Forms.RichTextBox,因为我无法获取任何设备相关或设备无关的方法将位图插入到RichTextBox中工作)。将Drawing.Bitmap转换为Imaging.Metafile - 像素完美
后来,我必须从元文件中检索像素数据。我需要元文件的像素完全匹配位图的像素。但是,当我执行转换时,像素略有改变。 (?也许是由于GDI图像颜色管理(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。
你是否能够实现你想要的,或者你需要进一步的帮助?如果其中一个答案有帮助,请不要忘记在赏金到期之前接受它(让它过期不会将点返回给您,它们会丢失 - 请参阅http://stackoverflow.com/faq#bounty关于这方面的细节)。 – Lucero 2010-10-10 11:37:56