Usando C #, c'è un modo migliore per convertire un Windows Bitmap
in byte[]
che salvarlo in un file temporaneo e leggere il risultato usando un FileStream
?
Usando C #, c'è un modo migliore per convertire un Windows Bitmap
in byte[]
che salvarlo in un file temporaneo e leggere il risultato usando un FileStream
?
Risposte:
Ci sono un paio di modi.
ImageConverter
public static byte[] ImageToByte(Image img)
{
ImageConverter converter = new ImageConverter();
return (byte[])converter.ConvertTo(img, typeof(byte[]));
}
Questo è conveniente perché non richiede molto codice.
Flusso di memoria
public static byte[] ImageToByte2(Image img)
{
using (var stream = new MemoryStream())
{
img.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
return stream.ToArray();
}
}
Questo equivale a quello che stai facendo, tranne per il fatto che il file viene salvato in memoria anziché su disco. Anche se più codice hai l'opzione di ImageFormat e può essere facilmente modificato tra il salvataggio in memoria o su disco.
ImageConverter
metodo salverà l'immagine come Png, risultando in file ENORMI.
ImageConverter
non è lo standard .net che potresti usareMemoryStream
Un MemoryStream può essere utile per questo. Potresti metterlo in un metodo di estensione:
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();
}
}
}
Potresti semplicemente usarlo come:
var image = new Bitmap(10, 10);
// Draw your image
byte[] arr = image.ToByteArray(ImageFormat.Bmp);
In parte non sono d'accordo con la risposta di prestomanifto riguardo a ImageConverter. Non utilizzare ImageConverter. Non c'è nulla di tecnicamente sbagliato in esso, ma semplicemente il fatto che usi il boxing / unboxing dall'oggetto mi dice che è il codice dai vecchi luoghi bui del framework .NET e non è l'ideale da usare con l'elaborazione delle immagini (è eccessivo per la conversione in byte [] almeno), soprattutto se si considera quanto segue.
Ho dato un'occhiata al ImageConverter
codice utilizzato dal framework .Net e internamente utilizza un codice quasi identico a quello che ho fornito sopra. Crea un nuovo MemoryStream
, salva il Bitmap
formato in qualunque formato fosse quando lo hai fornito e restituisce l'array. Salta il sovraccarico extra di creare una ImageConverter
classe utilizzandoMemoryStream
Puoi anche solo Marshal.Copia i dati bitmap. Nessun memorystream intermedio ecc. E una copia di memoria veloce. Questo dovrebbe funzionare su bitmap a 24 e 32 bit.
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);
}
}
.
Salvare l'immagine su MemoryStream e afferrare l'array di byte.
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
(vedi: docs.microsoft.com/en-us/dotnet/api/… )
System.Drawing.Image does not exist
. Quindi .. no, non funziona :(
Usa a MemoryStream
invece di a FileStream
, in questo modo:
MemoryStream ms = new MemoryStream();
bmp.Save (ms, ImageFormat.Jpeg);
byte[] bmpBytes = ms.ToArray();
ToArray
, no 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.
Quindi ora l'array di byte GetBuffer
restituirà l'immagine più i byte non utilizzati, il che probabilmente provocherà un'immagine corrotta.
Prova quanto segue:
MemoryStream stream = new MemoryStream();
Bitmap bitmap = new Bitmap();
bitmap.Save(stream, ImageFormat.Jpeg);
byte[] byteArray = stream.GetBuffer();
Assicurati di utilizzare:
System.Drawing & using System.Drawing.Imaging;
MemoryStream ms = new MemoryStream();
yourBitmap.Save(ms, ImageFormat.Bmp);
byte[] bitmapData = ms.ToArray();
Più semplice:
return (byte[])System.ComponentModel.TypeDescriptor.GetConverter(pImagen).ConvertTo(pImagen, typeof(byte[]))
Molto semplice usalo solo in una riga:
byte[] imgdata = File.ReadAllBytes(@"C:\download.png");