J'essaie de convertir un Drawing.Bitmap
en un Imaging.Metafile
afin d'insérer le métafichier dans un Forms.RichTextBox
. (Pour référence, l'intégration d'un bitmap dans un métafichier est la pratique recommandée pour placer un bitmap dans richtext (voir la version 1.9.1 de la spécification RTF (Rich Text Format), page 149.) Malheureusement, il semble également être le seul moyen d'intégrer une image dans un Forms.RichTextBox, car je ne peux obtenir aucune méthode dépendant du périphérique ou du périphérique pour insérer une image bitmap dans un RichTextBox.)Convertir Drawing.Bitmap en Imaging.Metafile - Pixel Perfect
Plus tard, je dois récupérer les données de pixels du métafichier . Je demande que les pixels du métafichier correspondent exactement à ceux du bitmap. Lorsque j'effectue la conversion, cependant, les pixels sont légèrement modifiés. (? Peut-être en raison de l'image GDI de gestion des couleurs (ICM))
est ma technique ici:
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;
}
Dans ce cas, j'accéder aux pixels du métafichier de cette façon:
metafile.Save(stream, Imaging.ImageFormat.Png);
Bitmap bitmap = new Bitmap(stream, false);
bitmap.GetPixel(x, y);
J'ai également essayé d'utiliser une technique BitBlt sans succès.
technique 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;
}
Je ne suis même pas sûr que cette technique est la copie correctement les données pixel. Cette technique échoue lorsque je tente d'accéder aux données dans le métafichier plus tard:
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);
Comment puis-je convertir un bitmap dans un métafichier sans altérer les pixels, puis récupérer les données pixel plus tard? Je vous remercie!
Réglage de la résolution Bitmap
Voici comment je tente de définir la résolution bitmap afin que la résolution du métafichier correspond:
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;
Le rtfBox est le même que celui envoyé à BitmapToMetafileViaGraphicsDrawImage.
Avez-vous réussi à obtenir ce que vous vouliez ou avez-vous besoin d'aide supplémentaire? Si l'une des réponses était utile, n'oubliez pas de l'accepter avant l'expiration de la prime (la laisser expirer ne vous renvoie pas les points, elle serait simplement perdue - voir http://stackoverflow.com/faq#bounty pour les détails à ce sujet). – Lucero