使用c#,是否有更好的方法将Windows位图转换为字节[],而不是保存到临时文件并使用FileStream读取结果?


当前回答

你也可以只是元帅。复制位图数据。没有中间内存流等和一个快速的内存拷贝。这应该适用于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);
    }

}

.

其他回答

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

你可以这样使用它:

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

我部分不同意prestomanifto关于ImageConverter的回答。不要使用ImageConverter。它在技术上并没有什么问题,只是它使用了对对象的装箱/拆箱,这一事实告诉我,它是来自。net框架的旧黑暗之处的代码,与图像处理一起使用并不理想(至少对于转换为字节[]来说有点过度了),特别是当你考虑以下问题时。

我查看了一下. net框架使用的ImageConverter代码,它在内部使用的代码几乎与我上面提供的代码相同。它创建了一个新的MemoryStream,以您提供它时的任何格式保存位图,并返回数组。通过使用MemoryStream跳过创建ImageConverter类的额外开销

我相信你可以简单地做到:

ImageConverter converter = new ImageConverter();
var bytes = (byte[])converter.ConvertTo(img, typeof(byte[]));

试试下面的方法:

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

byte[] byteArray = stream.GetBuffer();

确保你使用:

System.Drawing & using System.Drawing.Imaging;

使用内存流而不是文件流,就像这样:

MemoryStream ms = new MemoryStream();
bmp.Save (ms, ImageFormat.Jpeg);
byte[] bmpBytes = ms.ToArray();

你也可以只是元帅。复制位图数据。没有中间内存流等和一个快速的内存拷贝。这应该适用于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);
    }

}

.