BMP图片读写函数

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

}

猜你喜欢

转载自blog.csdn.net/bvngh3247/article/details/88692352