【问题标题】:Add a bitmap header to a byte array then create a bitmap file将位图头添加到字节数组,然后创建位图文件
【发布时间】:2012-07-12 12:50:56
【问题描述】:

我有一个来自相机的字节数组,它只是一个流,没有位图头。

我已经搜索了一个演示,但它们都是 C++ 的。

我尝试在我的代码中添加位图头,但抛出了 ParameterException。如何从 ByteArray 制作位图文件?

【问题讨论】:

标签: c# image bitmap


【解决方案1】:

您不能直接使用没有位图标题的原始数据创建位图类。位图标题就像位图图像的配方。它包括关于宽度、高度、每像素位数、数据长度等的基本信息,以便为图像制作适当的数组。

如果您仔细查看位图标头结构here,制作位图标头相当容易


但没有什么比完整的源代码示例更好的了。

我将它们分解成几部分,并在整个过程中为您评论每个步骤。它可能看起来有点过分和冗长,但我想这对你来说会是一个很好的指南。


以下是 2×2 像素、24 位位图的示例(Windows DIB 标头 BITMAPINFOHEADER),像素格式为 RGB24。

BMP 文件格式 - 维基百科

#region Bitmap Making...

// BmpBufferSize : a pure length of raw bitmap data without the header.
// the 54 value here is the length of bitmap header.
byte[] BitmapBytes = new byte[BmpBufferSize + 54];

#region Bitmap Header
// 0~2 "BM"
BitmapBytes[0] = 0x42;
BitmapBytes[1] = 0x4d;

// 2~6 Size of the BMP file - Bit cound + Header 54
Array.Copy(BitConverter.GetBytes(BmpBufferSize + 54), 0, BitmapBytes, 2, 4);

// 6~8 Application Specific : normally, set zero
Array.Copy(BitConverter.GetBytes(0), 0, BitmapBytes, 6, 2);

// 8~10 Application Specific : normally, set zero
Array.Copy(BitConverter.GetBytes(0), 0, BitmapBytes, 8, 2);

// 10~14 Offset where the pixel array can be found - 24bit bitmap data always starts at 54 offset.
Array.Copy(BitConverter.GetBytes(54), 0, BitmapBytes, 10, 4);
#endregion

#region DIB Header
// 14~18 Number of bytes in the DIB header. 40 bytes constant.
Array.Copy(BitConverter.GetBytes(40), 0, BitmapBytes, 14, 4);
                    
// 18~22 Width of the bitmap.
Array.Copy(BitConverter.GetBytes(image.Width), 0, BitmapBytes, 18, 4);

// 22~26 Height of the bitmap.
Array.Copy(BitConverter.GetBytes(image.Height), 0, BitmapBytes, 22, 4);

// 26~28 Number of color planes being used
Array.Copy(BitConverter.GetBytes(0), 0, BitmapBytes, 26, 2);

// 28~30 Number of bits. If you don't know the pixel format, trying to calculate it with the quality of the video/image source.
if (image.PixelFormat == System.Drawing.Imaging.PixelFormat.Format24bppRgb)
{                        
    Array.Copy(BitConverter.GetBytes(24), 0, BitmapBytes, 28, 2);
}

// 30~34 BI_RGB no pixel array compression used : most of the time, just set zero if it is raw data.
Array.Copy(BitConverter.GetBytes(0), 0, BitmapBytes, 30, 4);

// 34~38 Size of the raw bitmap data ( including padding )
Array.Copy(BitConverter.GetBytes(BmpBufferSize), 0, BitmapBytes, 34, 4);

// 38~46 Print resolution of the image, 72 DPI x 39.3701 inches per meter yields
if (image.PixelFormat == System.Drawing.Imaging.PixelFormat.Format24bppRgb)
{
    Array.Copy(BitConverter.GetBytes(0), 0, BitmapBytes, 38, 4);
    Array.Copy(BitConverter.GetBytes(0), 0, BitmapBytes, 42, 4);
}

// 46~50 Number of colors in the palette
Array.Copy(BitConverter.GetBytes(0), 0, BitmapBytes, 46, 4);

// 50~54 means all colors are important
Array.Copy(BitConverter.GetBytes(0), 0, BitmapBytes, 50, 4);

// 54~end : Pixel Data : Finally, time to combine your raw data, BmpBuffer in this code, with a bitmap header you've just created.
Array.Copy(BmpBuffer as Array, 0, BitmapBytes, 54, BmpBufferSize);

#endregion - bitmap header process
#endregion - bitmap making process

【讨论】:

  • 你是一个救生员。非常感谢:)
  • 我仍然想知道为什么没有内置框架。
【解决方案2】:

使用 System.Drawing.Bitmap 类

【讨论】:

    【解决方案3】:
    【解决方案4】:
    【解决方案5】:

    这会起作用

    ...

    using System;
    using System.IO;
    using System.Drawing;
    

    ...

    public Image ByteArrayToImage(byte[] byteArrayIn)
    {
    
     MemoryStream ms = new MemoryStream(byteArrayIn);
                       Image img = Image.FromStream(ms);
                       return img;
    }
    

    【讨论】:

    • 存在这个问题是因为您提供的代码在某些(许多)情况下确实会导致错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-05
    • 2014-02-28
    • 2012-08-22
    • 1970-01-01
    • 2012-07-28
    相关资源
    最近更新 更多