En utilisant C #, existe-t-il un meilleur moyen de convertir un fichier Windows Bitmap
en un byte[]
qu'en enregistrant dans un fichier temporaire et en lisant le résultat à l'aide d'un fichier FileStream
?
Il y a deux façons.
ImageConverter
public static byte[] ImageToByte(Image img)
{
ImageConverter converter = new ImageConverter();
return (byte[])converter.ConvertTo(img, typeof(byte[]));
}
Celui-ci est pratique car il ne nécessite pas beaucoup de code.
Memory Stream
public static byte[] ImageToByte2(Image img)
{
using (var stream = new MemoryStream())
{
img.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
return stream.ToArray();
}
}
Celui-ci est équivalent à ce que vous faites, sauf que le fichier est enregistré dans la mémoire plutôt que sur le disque. Bien que plus de code, vous avez l'option d'ImageFormat et il peut être facilement modifié entre l'enregistrement sur la mémoire ou le disque.
Un MemoryStream peut être utile pour cela. Vous pouvez le mettre dans une méthode d'extension:
public static class ImageExtensions
{
public static byte[] ToByteArray(this Image image, ImageFormat format)
{
using(MemoryStream ms = new MemoryStream())
{
image.Save(ms, format);
return ms.ToArray();
}
}
}
Vous pouvez simplement l'utiliser comme:
var image = new Bitmap(10, 10);
// Draw your image
byte[] arr = image.ToByteArray(ImageFormat.Bmp);
Je suis en partie en désaccord avec la réponse de prestomanifto en ce qui concerne ImageConverter. N'utilisez pas ImageConverter. Il n'y a rien de techniquement faux avec cela, mais simplement le fait qu'il utilise la boxe/unboxing from object me dit que c'est du code du vieux dark Le framework .NET n’est pas idéal pour le traitement des images (c’est trop pour la conversion en octet [] au moins), en particulier si l’on considère ce qui suit.
J'ai jeté un coup d'œil au code ImageConverter
utilisé par le framework .Net et utilise en interne un code presque identique à celui que j'ai fourni ci-dessus. Il crée un nouveau MemoryStream
, enregistre le Bitmap
dans le format dans lequel il se trouvait lorsque vous l'avez fourni et renvoie le tableau. Ignorez la surcharge supplémentaire liée à la création d'une classe ImageConverter
à l'aide de MemoryStream
Vous pouvez également simplement Marshal.Copy les données bitmap. Pas de mémoire intermédiaire, etc. et une copie rapide de la mémoire. Cela devrait fonctionner à la fois sur les bitmaps 24 bits et 32 bits.
public static byte[] BitmapToByteArray(Bitmap bitmap)
{
BitmapData bmpdata = null;
try
{
bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat);
int numbytes = bmpdata.Stride * bitmap.Height;
byte[] bytedata = new byte[numbytes];
IntPtr ptr = bmpdata.Scan0;
Marshal.Copy(ptr, bytedata, 0, numbytes);
return bytedata;
}
finally
{
if (bmpdata != null)
bitmap.UnlockBits(bmpdata);
}
}
.
Enregistrez l'image dans un MemoryStream, puis récupérez le tableau d'octets.
http://msdn.Microsoft.com/en-us/library/ms142148.aspx
Byte[] data;
using (var memoryStream = new MemoryStream())
{
image.Save(memoryStream, ImageFormat.Bmp);
data = memoryStream.ToArray();
}
Utilisez un MemoryStream
au lieu d'un FileStream
, comme ceci:
MemoryStream ms = new MemoryStream();
bmp.Save (ms, ImageFormat.Jpeg);
byte[] bmpBytes = ms.ToArray();
Essayez ce qui suit:
MemoryStream stream = new MemoryStream();
Bitmap bitmap = new Bitmap();
bitmap.Save(stream, ImageFormat.Jpeg);
byte[] byteArray = stream.GetBuffer();
Assurez-vous que vous utilisez:
System.Drawing & using System.Drawing.Imaging;
Je crois que vous pouvez simplement faire:
ImageConverter converter = new ImageConverter();
var bytes = (byte[])converter.ConvertTo(img, typeof(byte[]));
MemoryStream ms = new MemoryStream();
yourBitmap.Save(ms, ImageFormat.Bmp);
byte[] bitmapData = ms.ToArray();
Plus simple:
return (byte[])System.ComponentModel.TypeDescriptor.GetConverter(pImagen).ConvertTo(pImagen, typeof(byte[]))