BMP读函数:
#include <stdio.h>
#include <fcntl.h>
typedef unsigned short U16;
typedef unsigned long U32;
#pragma pack(1) //设置1字节对齐模式,pack()将对齐模式取消
/*位图文件头*/
typedef struct BMP_FILE_HEADER
{
U16 bType; /* 文件标识符 */
U32 bfSize; /* 文件的大小,单位字节 */
U16 bReserved1; /* 保留值,必须设置为0 */
U16 bReserved2; /* 保留值,必须设置为0 */
U32 bOffset; /* 文件头的最后到图像数据位开始的偏移量 */
} BMPFILEHEADER;
/*位图信息头*/
typedef struct BMP_INFO
{
U32 bInfoSize; /* 信息头的大小 */
U32 bWidth; /* 图像的宽度 */
U32 bHeight; /* 图像的高度 */
U16 bPlanes; /* 图像的位面数 */
U16 bBitCount; /* 每个像素的位数 */
U32 bCompression; /* 压缩类型 */
U32 bmpImageSize; /* 图像的大小,以字节为单位 */
U32 bXPelsPerMeter; /* 水平分辨率 */
U32 bYPelsPerMeter; /* 垂直分辨率 */
U32 bClrUsed; /* 使用的色彩数 */
U32 bClrImportant; /* 重要的颜色数 */
} BMPINF;
#pragma pack()
/*彩色表*/
typedef struct RGB_QUAD
{
U16 rgbBlue; /* 蓝色强度 */
U16 rgbGreen; /* 绿色强度 */
U16 rgbRed; /* 红色强度 */
U16 rgbReversed; /* 保留值 */
} RGBQUAD;
int read_bmp(const char *path, char *img_src_r, char * img_src_g, char * img_src_b, int *width, int *height)
{
FILE* fp;
BMPFILEHEADER fileHeader = { 0 };
BMPINF infoHeader = { 0 };
long offset, bmpImageSize, bytesPerPixel, size, bitCount;
int i = 0, j = 0, count = 0;
int lcount = 0;
int cl[3] = { 0 };
U16 c;
char *bmpData;
int lineByte = 0;
fp = fopen(path, "rb");
if (fp == NULL) {
return -1;
}
fread(&fileHeader, sizeof(BMPFILEHEADER), 1, fp);
fread(&infoHeader, sizeof(BMPINF), 1, fp);
//定义变量,计算图像每行像素所占的字节数(必须是4的倍数)
lineByte = (infoHeader.bWidth * infoHeader.bBitCount / 8 + 3) / 4 * 4;
bmpData = (char *)malloc((infoHeader.bHeight*infoHeader.bWidth * 3) * sizeof(char));
fseek(fp, fileHeader.bOffset, SEEK_SET);
fread(bmpData, 1, infoHeader.bHeight*infoHeader.bWidth * 3, fp);
for (i = 0; i < infoHeader.bHeight; ++i) {
for (j = 0; j < infoHeader.bWidth; ++j) {
img_src_b[i*infoHeader.bWidth + j] = bmpData[i*infoHeader.bWidth * 3 + j * 3];
img_src_g[i*infoHeader.bWidth + j] = bmpData[i*infoHeader.bWidth * 3 + j * 3 + 1];
img_src_r[i*infoHeader.bWidth + j] = bmpData[i*infoHeader.bWidth * 3 + j * 3 + 2];
}
}
free(bmpData);
fclose(fp);
return 0;
}
写函数
void saveBmp(char * filename, unsigned char * imageData, int height, int width, int channels)
{
bmpFileHead bh;
bmpHeadInfo bi;
RGBQUAD rq[256];
FILE * fout = fopen(filename, "wb");
unsigned short fileType = 0x4D42;
fwrite(&fileType, sizeof(unsigned short), 1, fout);
int step = channels * width;
int offset = step % 4;
if (offset != 0)
step += (4 - offset);
if (channels == 1)
bh.bfSize = height * step + 1078;
else
bh.bfSize = height * step + 54;
bh.bfReserved1 = 0;
bh.bfReserved2 = 0;
if (channels == 1)
bh.bfOffBits = 1078;
else
bh.bfOffBits = 54;
fwrite(&bh, sizeof(bmpFileHead), 1, fout);
// printf("%d\n", (int)bh.bfType);
// printf("%ld\n", bh.bfSize);
// printf("%d\n", (int)bh.bfReserved1);
// printf("%d\n", (int)bh.bfReserved2);
// printf("%ld\n", bh.bfOffBits);
int r;
for (r = 0; r < 256; r++)
{
rq[r].rgbBlue = rq[r].rgbGreen = rq[r].rgbRed = r;
rq[r].rgbReserved = 0;
// printf("%d\n", rq[r].rgbBlue);
// printf("%d\n", rq[r].rgbGreen);
// printf("%d\n", rq[r].rgbRed);
// printf("%d\n", rq[r].rgbReserved);
}
bi.biSize = 40;
bi.biWidth = width;
//bi.biHeight =-height;
bi.biHeight = height; //hujianhua
bi.biPlanes = 1;
bi.biBitCount = 8 * channels;
bi.biCompression = 0;
bi.biSizeImage = height*step;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
// printf("%ld\n", bi.biSize);
// printf("%ld\n", bi.biWidth);
// printf("%ld\n", bi.biHeight);
// printf("%d\n", bi.biPlanes);
// printf("%d\n", bi.biBitCount);
// printf("%ld\n", bi.biCompression);
// printf("%ld\n", bi.biSizeImage);
// printf("%ld\n", bi.biXPelsPerMeter);
// printf("%ld\n", bi.biYPelsPerMeter);
// printf("%ld\n", bi.biClrUsed);
// printf("%ld\n", bi.biClrImportant);
fwrite(&bi, sizeof(bmpHeadInfo), 1, fout);
if (channels == 1)
fwrite(&rq, 4, 256, fout);
//unsigned char dc[channels];
unsigned char def = 0;
// fseek(fout, 1078, SEEK_SET);
int i, j, c;
for (i = height - 1; i >= 0; i--)
{
for (j = 0; j < width; j++)
{
for (c = 0; c < channels; c++)
{
int value = imageData[(i * width + j) * channels + c];
// if(value > 255)
// printf("%d\t", value);
fwrite(&imageData[(i * width + j) * channels + c], sizeof(unsigned char), 1, fout);
}
}
if (offset != 0)
{
for (j = 0; j < 4 - offset; j++)
{
fwrite(&def, sizeof(unsigned char), 1, fout);
}
}
}
fclose(fout);
}