给BMP格式的8位灰度图 加个文件头 C语言实现

8位灰度图是256色位图的一种,它有调色板的颜色表,表中都是灰度色。文件头的大小是(14文件头+40信息+1024调色盘=1078字节)。
在我的项目中,下位机传来的数据只有具体的图像数据,缺少文件头,下面这个函数就可以给"raw"数据加上8位灰度图的头。

//AddBITMAPHEAD
//by pipawancui
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <math.h>

typedef unsigned char BYTE;
typedef unsigned long DWORD;
typedef unsigned short WORD;
typedef long LONG;

/* bits表示一个位,要转换成字节必须  bits/8   但是这样可能产生问题,
例如该字节是32个字节则占4位,那么33个字节呢,
按上面的办法把33--64个字节的图像字节,都认为它占8位。
所以如果不到32的整数   加一个31再除32乘8便可以解决零头化为4的倍数了。 */
#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)

typedef struct _BMPFILEHEAD
{
    //WORD bfType;      //文件类型,必须为 "BM"(0x4D42)
    DWORD bfSize;     //文件大小
    WORD bfReserved1; //保留字,不考虑
    WORD bfReserved2; //保留字,同上
    DWORD bfOffBits;  //实际位图数据的偏移字节数,即前三个部分长度之和
} BMPFILEHEAD;
//上面定义的结构体长度刚好为12,4的倍数 bfType拿出来

typedef struct _BMPFILETYPE
{
    WORD bfType; //文件类型,必须为 "BM"(0x4D42)
} BMPFILETYPE;

typedef struct _BMPINFOHEAD
{
    DWORD biSize;         //指定此结构体的长度,为40
    LONG biWidth;         //位图宽
    LONG biHeight;        //位图高
    WORD biPlanes;        //平面数,为1
    WORD biBitCount;      //采用颜色位数,可以是1,2,4,8,16,24,新的可以是32
    DWORD biCompression;  //压缩方式,可以是0,1,2,其中0表示不压缩
    DWORD biSizeImage;    //实际位图数据占用的字节数
    LONG biXPelsPerMeter; //X方向分辨率
    LONG biYPelsPerMeter; //Y方向分辨率
    DWORD biClrUsed;      //使用的颜色数,如果为0,则表示默认值(2^颜色位数)
    DWORD biClrImportant; //重要颜色数,如果为0,则表示所有颜色都是重要的
} BMPINFOHEAD;

typedef struct _RGBQUAD
{
    //public:
    BYTE rgbBlue;     //蓝色分量
    BYTE rgbGreen;    //绿色分量
    BYTE rgbRed;      //红色分量
    BYTE rgbReserved; //保留值,必须为0
} RGBQUAD;

/* 
* 函数名: add8GreyBmpHead
* 功能: 给未加工的原始数据加上一个8位灰度图的头
* 参数:
* 参数名         参数类型      IN/OUT/INOUT      备注
* pixData        void *        IN               原始数据
* width          long          IN               图片高
* height         long          IN               图片宽
* desFile        const char*   OUT              输出的文件路径
* 返回值:
* 类型:int
* 取值:0:成功,其它:无
* 其它:by pipawancui
 */
int add8GreyBmpHead(void *pixData, long width, long height,char const *desFile)
{
    BYTE bitCount = 8, color = 128;

    FILE *out;
    BMPFILETYPE bft;
    BMPFILEHEAD bfh;
    BMPINFOHEAD bih;
    RGBQUAD rgbquad[256];
    DWORD LineByte, ImgSize;
    LineByte = WIDTHBYTES(width * bitCount); //计算位图一行的实际宽度并确保它为32的倍数
    ImgSize = height * LineByte;             //图片像素大小

    for (int p = 0; p < 256; p++)
    {
        rgbquad[p].rgbBlue = (BYTE)p;
        rgbquad[p].rgbGreen = (BYTE)p;
        rgbquad[p].rgbRed = (BYTE)p;
        rgbquad[p].rgbReserved = (BYTE)0;
    }
    //bmp file's type
    bft.bfType = 0x4d42;

    //bmp fileheader's info
    bfh.bfSize = (DWORD)(54 + 4 * 256 + ImgSize);
    bfh.bfReserved1 = 0;
    bfh.bfReserved2 = 0;
    bfh.bfOffBits = (DWORD)(54 + 4 * 256);

    //bmp file's infoheader
    bih.biSize = 40; //本位图信息头的长度,为40字节
    bih.biWidth = width;
    bih.biHeight = height;
    bih.biPlanes = 1;
    bih.biBitCount = bitCount; //位图颜色位深
    bih.biCompression = 0;     //是否压缩:0不压缩
    bih.biSizeImage = ImgSize; //像素数据大小;
    bih.biXPelsPerMeter = 0;
    bih.biYPelsPerMeter = 0;
    bih.biClrUsed = 0;      //用到的颜色数,为0则是 2^颜色位深
    bih.biClrImportant = 0; //重要的颜色数,为0则全部都重要
    fopen_s(&out, desFile, "w+b");

    if (out)
    {
        //write bmp file's type
        fwrite(&bft, sizeof(BMPFILETYPE), 1, out);
        //write bmp file's header info
        fwrite(&bfh, sizeof(BMPFILEHEAD), 1, out);
        //write bmp file's infoheader
        fwrite(&bih, sizeof(BMPINFOHEAD), 1, out);
        //write bmp file's RGBQUAD data
        fwrite(&rgbquad, sizeof(RGBQUAD), sizeof(rgbquad) / sizeof(RGBQUAD), out);
        //writing pix data to file
        fwrite(pixData, sizeof(BYTE), ImgSize, out);
    }
    if (out)
        fclose(out);
    //--------------------------------------
    return 0;
}
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页