将位图转换为字节数组

Jer*_*Gee 216 c# bitmap

使用C#,有没有更好的方式来在Windows转换Bitmap到一个byte[]比保存到临时文件和读取使用的结果FileStream

pre*_*sto 387

有几种方法.

ImageConverter

public static byte[] ImageToByte(Image img)
{
    ImageConverter converter = new ImageConverter();
    return (byte[])converter.ConvertTo(img, typeof(byte[]));
}
Run Code Online (Sandbox Code Playgroud)

这个很方便,因为它不需要很多代码.

记忆流

public static byte[] ImageToByte2(Image img)
{
    using (var stream = new MemoryStream())
    {
        img.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
        return stream.ToArray();
    }
}
Run Code Online (Sandbox Code Playgroud)

这个等同于你正在做的,除了文件保存到内存而不是磁盘.虽然更多的代码可以选择ImageFormat,但可以在保存到内存或磁盘之间轻松修改.

资料来源:http://www.vcskicks.com/image-to-byte.php

  • 使用'使用'时你不需要关闭流 (8认同)
  • 请注意,`ImageConverter`方法会将图像保存为Png,从而生成巨大的文件. (4认同)
  • 您还可以使用bitmap.Lockbits和Marshal.Copy进行简单的快速复制,而无需任何中间内存流等. (2认同)
  • 任何人都可以给我更多关于这个阵列结构的信息吗?它是以x = 0开始并循环每个y然后递增x吗?然后像这样存储:[0,0,1,1,1,1,0,0,1,1]? (2认同)

Chr*_*ens 88

一个MemoryStream的可对此很有帮助.你可以把它放在一个扩展方法中:

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

你可以像以下一样使用它:

var image = new Bitmap(10, 10);
// Draw your image
byte[] arr = image.ToByteArray(ImageFormat.Bmp);
Run Code Online (Sandbox Code Playgroud)

我部分不同意prestomanifto关于ImageConverter的回答. 不要使用ImageConverter. 它没有任何技术上的错误,但仅仅是它使用来自对象的装箱/拆箱这一事实告诉我它是来自.NET框架的旧暗处的代码,并且它不适合用于图像处理(转换为字节的过度杀伤) []至少),特别是考虑以下情况时.

我看了一下ImageConverter.Net框架使用的代码,在内部它使用的代码几乎与我上面提供的代码相同.它创建一个新的MemoryStream,Bitmap以您提供它时所处的格式保存,并返回该数组.ImageConverter通过使用来省略创建类的额外开销MemoryStream

  • +1用于查看ImageConverter并报告您的研究结果.但我不认为你发现的东西保证声明"不要使用ImageConverter".从字节数组到Image,它确实提供了另一种有用的服务,例如设置图像分辨率(dpi).并且"创建ImageConverter类的额外开销"大概可以忽略不计,只需要进行一次,无论您使用它多少次. (3认同)

dee*_*gee 42

你也可以只是Marshal.复制位图数据.没有中间存储器流等和快速存储器副本.这应该适用于24位和32位位图.

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);
    }

}
Run Code Online (Sandbox Code Playgroud)

.

  • @ mini-me - 我建议查看位图步幅与位图宽度的关系.这不是我的代码中的错误,这是Windows处理位图的方式.Stride可以在每一行(宽度)的末尾包括额外数据,以使每一行结束并从32位边界开始以进行存储器对齐和性能. (4认同)
  • 什么是虫子?包括我在内的许多程序员都在使用这种代码风格,并且工作正常. (3认同)
  • 这不是一个bug.http://msdn.microsoft.com/en-us/library/system.drawing.imaging.bitmapdata.stride%28v=vs.110%29.aspx (3认同)
  • 你好,我使用了这个方法,但是我无法再次将此字节数组转换回图像。位图 bitmap1 = new Bitmap(new MemoryStream(array)); 它抛出无效参数的异常。有没有什么错误? (2认同)

Chr*_*ter 15

将图像保存到MemoryStream,然后获取字节数组.

http://msdn.microsoft.com/en-us/library/ms142148.aspx

  Byte[] data;

  using (var memoryStream = new MemoryStream())
  {
    image.Save(memoryStream, ImageFormat.Bmp);

    data = memoryStream.ToArray();
  }
Run Code Online (Sandbox Code Playgroud)


小智 10

更简单:

return (byte[])System.ComponentModel.TypeDescriptor.GetConverter(pImagen).ConvertTo(pImagen, typeof(byte[]))
Run Code Online (Sandbox Code Playgroud)

  • 谢谢 - 就像一个魅力,但如果你添加关于它如何工作的解释,答案会更好。 (3认同)

Jef*_*ddy 9

使用a MemoryStream而不是a FileStream,像这样:

MemoryStream ms = new MemoryStream();
bmp.Save (ms, ImageFormat.Jpeg);
byte[] bmpBytes = ms.ToArray();
Run Code Online (Sandbox Code Playgroud)

  • 它可能具有不属于图像的填充数据.从docs:`注意缓冲区包含可能未使用的已分配字节.例如,如果将字符串"test"写入MemoryStream对象,则从GetBuffer返回的缓冲区长度为256而不是4,未使用252个字节.为了获得只有在缓冲区中的数据,使用ToArray的method.`所以现在从字节数组`GetBuffer`将返回图像加上未使用的字节,这可能会导致损坏的映像. (4认同)

Fra*_*ert 7

请尝试以下方法:

MemoryStream stream = new MemoryStream();
Bitmap bitmap = new Bitmap();
bitmap.Save(stream, ImageFormat.Jpeg);

byte[] byteArray = stream.GetBuffer();
Run Code Online (Sandbox Code Playgroud)

确保您使用:

System.Drawing & using System.Drawing.Imaging;
Run Code Online (Sandbox Code Playgroud)


Kev*_*vek 6

我相信你可能只是这样做:

ImageConverter converter = new ImageConverter();
var bytes = (byte[])converter.ConvertTo(img, typeof(byte[]));
Run Code Online (Sandbox Code Playgroud)


620*_*2SP 5

MemoryStream ms = new MemoryStream();
yourBitmap.Save(ms, ImageFormat.Bmp);
byte[] bitmapData = ms.ToArray();
Run Code Online (Sandbox Code Playgroud)