// PrintBMPPixel.c
// c 语言读取BMP格式文件源代码
// 可同时处理没有压缩的BMP格式的二值图像, 索引图像, 真彩色图像。
#include <stdio.h>
#include <Windows.h>
// 位图文件头
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;
}
c 语言读取BMP格式文件源代码
最新推荐文章于 2022-01-08 22:42:52 发布
这是一个C语言程序,用于读取并打印BMP格式文件的像素数据,支持不同位深的图像,包括二值图像、索引图像和真彩色图像。程序首先定义了位图文件头、位图信息头和调色板结构体,然后读取文件并检查其格式和压缩类型,最后打印图像信息并输出图像的第一行像素数据。
251

被折叠的 条评论
为什么被折叠?



