当前位置:网站首页>C语言读取BMP文件
C语言读取BMP文件
2022-07-06 09:14:00 【imxlw00】
BMP图像编码
BMP即bitmap,也就是位图,一般由4部分组成:文件头信息块、图像描述信息块、颜色表(在真彩色模式无颜色表)和图像数据区。
在图像数据之前,如图所示,共有54位数据
其中,0x424d在十进制为19778,对应的ASCII码为BM,表示这是个bitmap文件。
Windows的数据是倒着念的,这是PC电脑的特色。如果一段数据为42 4D,倒着念就是4D 42,即0x4D42。
因此,如果bfSize的数据为A2 1E 04 00,实际上就成了0x00041EA2,也就是0x41EA2。
文件信息头[14字节]
存储着文件类型,文件大小等信息
// 文件信息头结构体
typedef struct tagBITMAPFILEHEADER{
unsigned short bfType; //必为"BM"
unsigned int bfSize; //文件字节数(2-5)
unsigned int bfReserved; //位图文件保留字,必为0(6-9)
unsigned int bfOffBits; //像素数据偏移 (10-13)
} bmpHeader;
图像描述信息[40字节]
#define uint unsigned int
#define ushort unsigned short
//图像信息头结构体
typedef struct tagBITMAPINFOHEADER{
uint biSize; // 结构体尺寸 (14-17)
int biWidth; // 图像宽度 (18-21)
int biHeight; // 图像高度 (22-25)
ushort biPlanes; // 目标设备的级别,为1(26-27)
ushort biBitCount; // 像素位数,为1、4、8或24(28-29)
uint biCompression; // 位图压缩类型,0为不压缩、1为BI_RLE8、2为BI_RLE4(30-33)
uint biSizeImage; // 单像素数据大小,等于bfSize-bfOffBits (34-37)
int biXPelsPerMeter; // 水平分辨率,一般为0 (38-41)
int biYPelsPerMeter; // 垂直分辨率,一般为0 (42-45)
uint biClrUsed; // 位图颜色表中的颜色数,0表示使用所有调色板项(46-49)
uint biClrImportant; // 重要颜色索引的数目,0表示都重要(50-53)
} infoHeader;
像素信息结构体
typedef struct _PixelInfo {
unsigned char rgbBlue; //蓝色分量 (0-255)
unsigned char rgbGreen; //绿色分量 (0-255)
unsigned char rgbRed; //红色分量 (0-255)
//unsigned char rgbReserved;// 保留,必须为0
} PixelInfo;
vs 2019 设置结构体对齐规则
示例图片
读取图像
int main()
{
BITMAPFILEHEADER fileHeader;
BITMAPINFOHEADER infoHeader;
PixelInfo pixel;
FILE* fp;
fp = fopen("images/123456.bmp", "rb");
//fp = fopen("images/b44.bmp", "rb");
fread(&fileHeader, sizeof(fileHeader), 1, fp);
fread(&infoHeader, sizeof(infoHeader), 1, fp);
if (fileHeader.bfType != 19778)
{
printf("%s", "err");
}
printf("%d\n", fileHeader.bfType);
printf("%d\n", fileHeader.bfSize);
unsigned char b;
unsigned char g;
unsigned char r;
unsigned char gray;
int x, y, count = 0;
int w = infoHeader.biWidth;
int h = infoHeader.biHeight;
char info[] = "* ";
int len = w * h + h + 1;
char* out = (char*)malloc(len * sizeof(char));
for (y = 0; y < h; y++)
{
for (x = 0; x < w; x++)
{
fread(&pixel, sizeof(pixel), 1, fp);
//printf("%d, %d , %d \n", pixel.rgbRed, pixel.rgbGreen, pixel.rgbBlue);
b = pixel.rgbBlue;
g = pixel.rgbGreen;
r = pixel.rgbRed;
gray = (int)(r * 0.299 + g * 0.587 + b * 0.114);
out[count++] = info[gray * strlen(info) / 256];
}
out[count++] = '\n';
}
out[count] = '\0';
printf("%s\n", out);
printf("helloWorld\n");
return 0;
}
由于坐标系不同,需要修改读取像素顺序
int main3()
{
BITMAPFILEHEADER fileHeader;
BITMAPINFOHEADER infoHeader;
PixelInfo pixel;
FILE* fp;
fp = fopen("images/123456.bmp", "rb");
//fp = fopen("images/b44.bmp", "rb");
fread(&fileHeader, sizeof(fileHeader), 1, fp);
fread(&infoHeader, sizeof(infoHeader), 1, fp);
if (fileHeader.bfType != 19778)
{
printf("%s", "err");
}
printf("%d\n", fileHeader.bfType);
printf("%d\n", fileHeader.bfSize);
unsigned char b;
unsigned char g;
unsigned char r;
unsigned char gray;
int x, y,count=0;
int w = infoHeader.biWidth;
int h = infoHeader.biHeight;
char info[] = "* ";
int len = w * h + h+1;
char* out = (char*)malloc(len * sizeof(char));
for (y = h - 1; y >= 0; y--)
{
count = (w + 1) * y;
for (x = 0; x < w; x++)
{
fread(&pixel, sizeof(pixel), 1, fp);
b = pixel.rgbBlue;
g = pixel.rgbGreen;
r = pixel.rgbRed;
gray = (int)(r * 0.299 + g * 0.587 + b * 0.114);
out[count++] = info[gray * strlen(info) / 256];
}
out[count++] = '\n';
}
out[len-1] = '\0';
printf("%s\n", out);
printf("helloWorld\n");
return 0;
}
图像变形
Windows规定一个扫描行所占的字节数必须是 4的倍数(即以long为单位),不足的以0填充。
一个扫描行所占的字节数计算方法:
DataSizePerLine= (biWidth* biBitCount+31)/8;
// 一个扫描行所占的字节数
DataSizePerLine= DataSizePerLine/44; // 字节数必须是4的倍数
位图数据的大小(不压缩情况下):
DataSize= DataSizePerLine biHeight;
int main()
{
BITMAPFILEHEADER fileHeader;
BITMAPINFOHEADER infoHeader;
PixelInfo pixel;
FILE* fp;
fp = fopen("images/123456.bmp", "rb");
//fp = fopen("images/b44.bmp", "rb");
fread(&fileHeader, sizeof(fileHeader), 1, fp);
fread(&infoHeader, sizeof(infoHeader), 1, fp);
if (fileHeader.bfType != 19778)
{
printf("%s", "err");
}
printf("%d\n", fileHeader.bfType);
printf("%d\n", fileHeader.bfSize);
unsigned char b;
unsigned char g;
unsigned char r;
unsigned char gray;
int x, y,count=0;
int w = infoHeader.biWidth;
int h = infoHeader.biHeight;
int DataSizePerLine = (w * infoHeader.biBitCount + 31) / 8 / 4 * 4; // 字节数必须是4的倍数
char info[] = "* ";
int len = w * h + h+1;
char* out = (char*)malloc(len * sizeof(char));
for (y = h - 1; y >= 0; y--)
{
count = (w + 1) * y;
for (x = 0; x < w; x++)
{
fread(&pixel, sizeof(pixel), 1, fp);
b = pixel.rgbBlue;
g = pixel.rgbGreen;
r = pixel.rgbRed;
gray = (int)(r * 0.299 + g * 0.587 + b * 0.114);
out[count++] = info[gray * strlen(info) / 256];
}
if (w % 4 != 0)
{
fseek(fp, DataSizePerLine - 3 * w,SEEK_CUR);
}
out[count++] = '\n';
}
out[len-1] = '\0';
printf("%s\n", out);
printf("helloWorld\n");
return 0;
}
参考链接 https://blog.csdn.net/qq_39400113/article/details/104750460
参考大牛视频 https://www.bilibili.com/video/BV1n5411N7T4?spm_id_from=333.999.0.0
边栏推荐
- Tcp/ip protocol (UDP)
- [recommended by bloggers] asp Net WebService background data API JSON (with source code)
- 机器学习--人口普查数据分析
- The virtual machine Ping is connected to the host, and the host Ping is not connected to the virtual machine
- 引入了junit为什么还是用不了@Test注解
- Summary of numpy installation problems
- Principes JDBC
- [蓝桥杯2017初赛]方格分割
- Idea import / export settings file
- Introduction and use of automatic machine learning framework (flaml, H2O)
猜你喜欢
[free setup] asp Net online course selection system design and Implementation (source code +lunwen)
Rhcsa certification exam exercise (configured on the first host)
[recommended by bloggers] C WinForm regularly sends email (with source code)
[number theory] divisor
[recommended by bloggers] C # generate a good-looking QR code (with source code)
机器学习笔记-Week02-卷积神经网络
Invalid global search in idea/pychar, etc. (win10)
Generate PDM file from Navicat export table
MySQL主从复制、读写分离
Postman uses scripts to modify the values of environment variables
随机推荐
Database advanced learning notes -- SQL statement
PyCharm中无法调用numpy,报错ModuleNotFoundError: No module named ‘numpy‘
AcWing 1294.樱花 题解
Picture coloring project - deoldify
TCP/IP协议(UDP)
Machine learning -- census data analysis
AcWing 1298. Solution to Cao Chong's pig raising problem
Software testing and quality learning notes 3 -- white box testing
Windows cannot start the MySQL service (located on the local computer) error 1067 the process terminated unexpectedly
Deoldify项目问题——OMP:Error#15:Initializing libiomp5md.dll,but found libiomp5md.dll already initialized.
L2-006 树的遍历 (25 分)
[recommended by bloggers] asp Net WebService background data API JSON (with source code)
Attention apply personal understanding to images
Detailed reading of stereo r-cnn paper -- Experiment: detailed explanation and result analysis
Invalid global search in idea/pychar, etc. (win10)
QT creator specify editor settings
double转int精度丢失问题
Remember a company interview question: merge ordered arrays
基于apache-jena的知识问答
Are you monitored by the company for sending resumes and logging in to job search websites? Deeply convinced that the product of "behavior awareness system ba" has not been retrieved on the official w