C++文件流写入bmp图像

283 阅读1分钟

今天工作遇到的需求(Linux下C++通过图像灰度数组生成BMP图像),特此记录下

语言/平台

c++ Linux

示例代码

#include "ImgUtil.h"
#include <stdio.h>
#include<string.h>

typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned int DWORD;
//typedef unsigned long LONG;  Windows下要把注释打开,Linux不用
//参考https://blog.csdn.net/gaoyu1253401563/article/details/106467681
#pragma pack(1)

typedef struct tagBITMAPFILEHEADER {
    WORD    bfType;
    DWORD   bfSize;
    WORD    bfReserved1;
    WORD    bfReserved2;
    DWORD   bfOffBits;
} BITMAPFILEHEADER;


typedef struct tagBITMAPINFOHEADER {
    DWORD      biSize;
    DWORD       biWidth;
    DWORD       biHeight;
    WORD       biPlanes;
    WORD       biBitCount;
    DWORD      biCompression;
    DWORD      biSizeImage;
    DWORD       biXPelsPerMeter;
    DWORD       biYPelsPerMeter;
    DWORD      biClrUsed;
    DWORD      biClrImportant;
} BITMAPINFOHEADER;


typedef struct tagRGBQUAD {
    BYTE    rgbBlue;
    BYTE    rgbGreen;
    BYTE    rgbRed;
    BYTE    rgbReserved;
} RGBQUAD;
#pragma pack()

//pData 图像灰度数组 iWidth 图像宽度 iHeight 图像高度
void ImgUtil::SaveImg(unsigned char* pData, int iWidth, int iHeight)
{
    BITMAPFILEHEADER targetfileheader;
    BITMAPINFOHEADER targetinfoheader;
    memset(&targetfileheader, 0, sizeof(BITMAPFILEHEADER));
    memset(&targetinfoheader, 0, sizeof(BITMAPINFOHEADER));

    targetfileheader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD);
    targetinfoheader.biSize = iWidth * iHeight + sizeof(RGBQUAD) * 256 + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
    targetfileheader.bfReserved1 = 0;
    targetfileheader.bfReserved2 = 0;
    targetfileheader.bfType = 0x4D42;

    targetinfoheader.biBitCount = 8;
    targetinfoheader.biSize = sizeof(BITMAPINFOHEADER);
    targetinfoheader.biHeight = iHeight;
    targetinfoheader.biWidth = iWidth;
    targetinfoheader.biPlanes = 1;
    targetinfoheader.biCompression = 0;
    targetinfoheader.biSizeImage = 0;
    targetinfoheader.biXPelsPerMeter = 0;
    targetinfoheader.biYPelsPerMeter = 0;
    targetinfoheader.biClrImportant = 0;
    targetinfoheader.biClrUsed = 0;

		//调色板
    RGBQUAD rgbquad[256];
    for (int i = 0; i < 256; i++)
    {
        rgbquad[i].rgbBlue = i;
        rgbquad[i].rgbGreen = i;
        rgbquad[i].rgbRed = i;
        rgbquad[i].rgbReserved = 0;
    }

    FILE* fp = fopen("out.bmp", "wb");
    fwrite(&targetfileheader, sizeof(BITMAPFILEHEADER), 1, fp);
    fwrite(&targetinfoheader, sizeof(BITMAPINFOHEADER), 1, fp);
    fwrite(&rgbquad, sizeof(RGBQUAD), 256, fp);

    for (int i = 0; i < iHeight; i++)
    {
        fwrite(pData + (iHeight - 1 - i) * iWidth, iWidth, 1, fp);
    }
    fclose(fp);
}