c 语言读取BMP格式文件源代码


// PrintBMPPixel.c
// c 语言读取BMP格式文件源代码
// 可同时处理没有压缩的BMP格式的二值图像, 索引图像, 真彩色图像。

#include 
#include 
 // 位图文件头
typedef struct tagBMPFILEHEADER
{
	unsigned short bfType;     // 2 bytes
	unsigned long bfSize;	   // 4 bytes
	WORD bfReserved1;			// 2 bytes
	WORD bfReserved2;			// 2 bytes
	unsigned long bfOffBits;    // 4 bytes
}BMPHEADER;

BMPHEADER bmpheader;

// 位图信息头
typedef struct tagBMPINFOHEADER
{
	DWORD  biSize;
	LONG  biWidth;
	LONG  biHeight;
	WORD  biPlanes;
	WORD biBitCount;
	DWORD biCompression;
	DWORD biSizeImage;
	LONG biXPelsPerMeter;
	LONG biYPelsPerMeter;
	DWORD biclrUsed;
	DWORD biClrImportant;
}BMPINFOHEADER;

BMPINFOHEADER bmpinfoheader;

// 调色板(可选)

typedef struct tagBMPRGBQUAD
{
	BYTE rgbBlue;   // typedef unsigned char BYTE 
	BYTE rgbGreen;
	BYTE rgbRed;
	BYTE rgbReserved;
}BMPRGBQUAD;

BMPRGBQUAD *bmprgbquad;

// 位图数据
typedef struct tagIMAGEDATA
{
	BYTE red;
	BYTE green;
	BYTE blue;
}IMAGEDATA;

IMAGEDATA *imagedata;
// 获得当前BMP文件的大小
int GetBmpSize(FILE *fp)
{
	long curpos;   // attention! this is a long type.
	int len;
	curpos = ftell(fp);
	fseek(fp, 0, SEEK_END);
	len = ftell(fp);
	fseek(fp, curpos, SEEK_SET);
	return len;
}

int main(int argc, char ** argv)
{
	FILE *fp;
	unsigned char *cp1, *cp2, *sp;
	int bTrueClr = 1;
	int i, j;
	int Width;
	unsigned char *paletteIndex;
	//scanf("%s", bmpfile);
	if (argc <= 1)
	{
		printf("Please input the filename: \n");
		system("pause");
		exit(0);
	}
	if ((fp = fopen(argv[1], "rb")) == NULL) // must be "rb" to indicate the position of the file while the pointer is moving!
	{
		printf("Can not open file\n");
		system("pause");
		exit(0);
	}
	fread(&bmpheader, sizeof(unsigned short), 1, fp);
	sp = (unsigned char *)&bmpheader;
	sp = sp + 4;
	fread(sp, sizeof(struct tagBMPFILEHEADER) - 4, 1, fp);
	fread(&bmpinfoheader, sizeof(struct tagBMPINFOHEADER), 1, fp);
	if (bmpinfoheader.biBitCount == 1 || bmpinfoheader.biBitCount == 4 || bmpinfoheader.biBitCount == 8)
	{
		bmprgbquad = (BMPRGBQUAD *)malloc(sizeof(struct tagBMPRGBQUAD)*(1 << bmpinfoheader.biBitCount));
		fread(bmprgbquad, sizeof(BMPRGBQUAD)*(1 << bmpinfoheader.biBitCount), 1, fp);  // 2 的幂,用右移来实现
		bTrueClr = 0;
	}
	if (bmpheader.bfType != 0x424d)
	{
		printf("The type of the image is not supported\n");
	}
	if (bmpinfoheader.biCompression != 0)
	{
		printf("The compression type are not supported.\n");
	}
	if (bmpheader.bfSize != GetBmpSize(fp))
	{
		printf("The size of the file is not matched\n");
	}
	// print the bmpfileheader value.
	cp1 = (unsigned char *)&(bmpheader.bfType);
	cp2 = cp1 + 1;
	printf("%c", *cp1);
	printf("%c\n", *cp2);
	printf("File size: %lu\n", bmpheader.bfSize);
	printf("Offset from the BOF to the virtual image data: %lu\n", bmpheader.bfOffBits);
	// print the bmpinfoheader value.
	printf("The size of the infoheader is: %lu\n", bmpinfoheader.biSize);
	printf("Width: %ld\n", bmpinfoheader.biWidth);
	printf("Height: %ld\n", bmpinfoheader.biHeight);
	printf("Planes: %d\n", bmpinfoheader.biPlanes);
	printf("Bit Depth: %d\n", bmpinfoheader.biBitCount);
	printf("Compression type: %lu\n", bmpinfoheader.biCompression);
	printf("Image data size: %lu\n", bmpinfoheader.biSizeImage);
	printf("XperMeter: %ld\n", bmpinfoheader.biXPelsPerMeter);
	printf("YperMeter: %ld\n", bmpinfoheader.biYPelsPerMeter);
	printf("Color used: %lu\n", bmpinfoheader.biclrUsed);
	printf("Important color: %lu\n", bmpinfoheader.biClrImportant);
	// 每一行的字节数必须为4的整数倍
	Width = (bmpinfoheader.biWidth*bmpinfoheader.biBitCount + 31)/8/4*4;
	// print the pixel of the imagedata
	imagedata = (IMAGEDATA *)malloc(sizeof(struct tagIMAGEDATA)*Width*bmpinfoheader.biHeight);
	paletteIndex = (unsigned char *)malloc(sizeof(unsigned char)*Width*bmpinfoheader.biHeight);
	if (!bTrueClr)
	{
		fread(paletteIndex, sizeof(unsigned char)*Width*bmpinfoheader.biHeight, 1, fp);
		for (i = 0; i < bmpinfoheader.biHeight; i++)
		{
			for (j = 0; j < Width; j++)
			{
				(*(imagedata + i * bmpinfoheader.biHeight + j)).blue = bmprgbquad[(BYTE)(*(paletteIndex + i*bmpinfoheader.biHeight + j))].rgbBlue;
				(*(imagedata + i * bmpinfoheader.biHeight + j)).green = bmprgbquad[(BYTE)(*(paletteIndex + i*bmpinfoheader.biHeight + j))].rgbGreen;
				(*(imagedata + i * bmpinfoheader.biHeight + j)).red= bmprgbquad[(BYTE)(*(paletteIndex + i*bmpinfoheader.biHeight + j))].rgbRed;
			}
		}
	}
	else
	{
		fread(imagedata, sizeof(struct tagIMAGEDATA)*Width*bmpinfoheader.biHeight, 1, fp);
	}
	for (i = 0; i< 1; i++)  // Print the first line pixel.
	{
		for (j = 0; j < bmpinfoheader.biWidth; j++)
		{
			
			if ((*(imagedata + i * bmpinfoheader.biHeight + j)).blue == (*(imagedata + i * bmpinfoheader.biHeight + j)).green && (*(imagedata + i * bmpinfoheader.biHeight + j)).blue == (*(imagedata + i * bmpinfoheader.biHeight + j)).red)
			{
				printf("%d ", (*(imagedata + i * bmpinfoheader.biHeight + j)).red);
			}
			else
			{
				printf("%d ", (*(imagedata + i * bmpinfoheader.biHeight + j)).blue);
				printf("%d ", (*(imagedata + i * bmpinfoheader.biHeight + j)).green);
				printf("%d ", (*(imagedata + i * bmpinfoheader.biHeight + j)).red);
			}
			if (0 == j%3)
			{
				printf("\n");
			}
		}
		printf("\n");
	}
	fclose(fp);
	system("pause");
	free(imagedata);
	free(paletteIndex);
	return 0;
}










你可能感兴趣的:(图像处理)