当前位置:网站首页>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
边栏推荐
- AcWing 179.阶乘分解 题解
- Did you forget to register or load this tag
- Basic use of redis
- Request object and response object analysis
- Solution: log4j:warn please initialize the log4j system properly
- 数据库高级学习笔记--SQL语句
- Invalid global search in idea/pychar, etc. (win10)
- QT creator specifies dependencies
- Database advanced learning notes -- SQL statement
- Attention apply personal understanding to images
猜你喜欢

A trip to Macao - > see the world from a non line city to Macao

Unable to call numpy in pycharm, with an error modulenotfounderror: no module named 'numpy‘

La table d'exportation Navicat génère un fichier PDM

MySQL master-slave replication, read-write separation

In the era of DFI dividends, can TGP become a new benchmark for future DFI?

Navicat 導出錶生成PDM文件

Detailed reading of stereo r-cnn paper -- Experiment: detailed explanation and result analysis

Why can't I use the @test annotation after introducing JUnit

Use dapr to shorten software development cycle and improve production efficiency

安装numpy问题总结
随机推荐
AcWing 179.阶乘分解 题解
[recommended by bloggers] C MVC list realizes the function of adding, deleting, modifying, checking, importing and exporting curves (with source code)
What does BSP mean
JDBC原理
Leetcode 461 Hamming distance
QT creator support platform
AcWing 1294.樱花 题解
Idea import / export settings file
L2-006 树的遍历 (25 分)
基于apache-jena的知识问答
Software testing - interview question sharing
The virtual machine Ping is connected to the host, and the host Ping is not connected to the virtual machine
打开浏览器的同时会在主页外同时打开芒果TV,抖音等网站
Deoldify project problem - omp:error 15:initializing libiomp5md dll,but found libiomp5md. dll already initialized.
L2-001 紧急救援 (25 分)
Error connecting to MySQL database: 2059 - authentication plugin 'caching_ sha2_ The solution of 'password'
Introduction to the easy copy module
[recommended by bloggers] background management system of SSM framework (with source code)
Summary of numpy installation problems
[蓝桥杯2021初赛] 砝码称重