Usando C #, existe uma maneira melhor de converter um Windows Bitmap
para um do byte[]
que salvar em um arquivo temporário e ler o resultado usando um FileStream
?
Usando C #, existe uma maneira melhor de converter um Windows Bitmap
para um do byte[]
que salvar em um arquivo temporário e ler o resultado usando um FileStream
?
Respostas:
Existem algumas maneiras.
ImageConverter
public static byte[] ImageToByte(Image img)
{
ImageConverter converter = new ImageConverter();
return (byte[])converter.ConvertTo(img, typeof(byte[]));
}
Este é conveniente porque não requer muito código.
Fluxo de memória
public static byte[] ImageToByte2(Image img)
{
using (var stream = new MemoryStream())
{
img.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
return stream.ToArray();
}
}
Este é equivalente ao que você está fazendo, exceto que o arquivo é salvo na memória em vez de no disco. Embora haja mais código, você tem a opção ImageFormat e pode ser facilmente modificado entre salvar na memória ou no disco.
ImageConverter
método salvará a imagem como Png, resultando em arquivos ENORMES.
ImageConverter
não é padrão .net você pode usarMemoryStream
Um MemoryStream pode ser útil para isso. Você pode colocá-lo em um método de extensão:
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();
}
}
}
Você poderia usá-lo como:
var image = new Bitmap(10, 10);
// Draw your image
byte[] arr = image.ToByteArray(ImageFormat.Bmp);
Discordo parcialmente da resposta do prestomanifto em relação ao ImageConverter. Não use o ImageConverter. Não há nada tecnicamente errado com isso, mas simplesmente o fato de usar o boxe / unboxing do objeto me diz que é um código dos antigos locais escuros da estrutura .NET e não é ideal para o processamento de imagens (é um exagero a conversão para um byte [] pelo menos), especialmente quando você considera o seguinte.
Dei uma olhada no ImageConverter
código usado pela estrutura .Net e, internamente, ele usa código quase idêntico ao que forneci acima. Ele cria um novo MemoryStream
, salva o Bitmap
formato que estava quando você o forneceu e retorna a matriz. Ignore a sobrecarga extra de criar uma ImageConverter
classe usandoMemoryStream
Você também pode apenas Marshal. Copiar os dados de bitmap. Não há fluxo de memória intermediário, etc., e uma cópia rápida da memória. Isso deve funcionar em bitmaps de 24 e 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);
}
}
.
Salve a imagem em um MemoryStream e, em seguida, pegue a matriz de bytes.
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
(ver: docs.microsoft.com/en-us/dotnet/api/... )
System.Drawing.Image does not exist
. Então .. não, não funciona :(
Use a em MemoryStream
vez de a FileStream
, assim:
MemoryStream ms = new MemoryStream();
bmp.Save (ms, ImageFormat.Jpeg);
byte[] bmpBytes = ms.ToArray();
ToArray
, não 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.
Agora, a matriz de bytes GetBuffer
retornará a imagem mais bytes não utilizados, o que provavelmente resultará em uma imagem corrompida.
Tente o seguinte:
MemoryStream stream = new MemoryStream();
Bitmap bitmap = new Bitmap();
bitmap.Save(stream, ImageFormat.Jpeg);
byte[] byteArray = stream.GetBuffer();
Verifique se você está usando:
System.Drawing & using System.Drawing.Imaging;
MemoryStream ms = new MemoryStream();
yourBitmap.Save(ms, ImageFormat.Bmp);
byte[] bitmapData = ms.ToArray();
Mais simples:
return (byte[])System.ComponentModel.TypeDescriptor.GetConverter(pImagen).ConvertTo(pImagen, typeof(byte[]))
Muito simples, use isso apenas em uma linha:
byte[] imgdata = File.ReadAllBytes(@"C:\download.png");