我試圖將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