En utilisant C #, y a-t-il une meilleure façon de convertir un Windows Bitmap
en un byte[]
qu'en enregistrant dans un fichier temporaire et en lisant le résultat en utilisant un FileStream
?
En utilisant C #, y a-t-il une meilleure façon de convertir un Windows Bitmap
en un byte[]
qu'en enregistrant dans un fichier temporaire et en lisant le résultat en utilisant un FileStream
?
Réponses:
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.
Flux de mémoire
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 ImageFormat et il peut être facilement modifié entre l'enregistrement sur la mémoire ou le disque.
ImageConverter
méthode enregistrera l'image au format Png, ce qui entraînera d'énormes fichiers.
ImageConverter
n'est pas la norme .net que vous pourriez utiliserMemoryStream
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 partiellement en désaccord avec la réponse de prestomanifto concernant l'ImageConverter. N'utilisez pas ImageConverter. Il n'y a rien de mal sur le plan technique, mais simplement le fait qu'il utilise la boxe / unboxing de l'objet me dit que c'est du code provenant des anciens endroits sombres du framework .NET et que ce n'est pas idéal à utiliser avec le traitement d'image (c'est exagéré pour la conversion en octet [] au moins), surtout si l'on considère les éléments suivants.
J'ai jeté un coup d'œil au ImageConverter
code utilisé par le framework .Net, et en interne, il utilise un code presque identique à celui que j'ai fourni ci-dessus. Il en crée un nouveau MemoryStream
, l'enregistre Bitmap
dans le format dans lequel il se trouvait lorsque vous l'avez fourni et renvoie le tableau. Évitez les frais généraux supplémentaires liés à la création d'une ImageConverter
classe en utilisantMemoryStream
Vous pouvez également simplement Marshal.Copy les données bitmap. Pas de mémoire intermédiaire, etc. et une copie de mémoire rapide. Cela devrait fonctionner 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 saisissez 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();
}
System.Drawing.Image
(voir: docs.microsoft.com/en-us/dotnet/api/… )
System.Drawing.Image does not exist
. Alors .. non, ça ne marche pas :(
Utilisez un MemoryStream
au lieu d'un FileStream
, comme ceci:
MemoryStream ms = new MemoryStream();
bmp.Save (ms, ImageFormat.Jpeg);
byte[] bmpBytes = ms.ToArray();
ToArray
, non GetBuffer
.
Note that the buffer contains allocated bytes which might be unused. For example, if the string "test" is written into the MemoryStream object, the length of the buffer returned from GetBuffer is 256, not 4, with 252 bytes unused. To obtain only the data in the buffer, use the ToArray method.
Alors maintenant, le tableau d'octets de GetBuffer
retournera l'image plus les octets inutilisés, ce qui entraînera probablement une image corrompue.
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;
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[]))
Très simple, utilisez ceci en une seule ligne:
byte[] imgdata = File.ReadAllBytes(@"C:\download.png");