当前位置:网站首页>Reading BMP file with C language
Reading BMP file with C language
2022-07-06 11:25:00 【imxlw00】
BMP Image coding
BMP namely bitmap, It's a bitmap , Generally by 4 Part of it is made up of : Header information block 、 Image description information block 、 color table ( No color table in true color mode ) And image data area .
Before the image data , As shown in the figure , share 54 Bit data
among ,0x424d In the decimal system is 19778, Corresponding ASCII Code for BM, It means it's a bitmap file .
Windows The data is read backwards , This is a PC Computer features . If a piece of data is 42 4D, Read it backwards 4D 42, namely 0x4D42.
therefore , If bfSize The data is A2 1E 04 00, In fact, it becomes 0x00041EA2, That is to say 0x41EA2.
File header [14 byte ]
Storing file types , File size and other information
// File header structure
typedef struct tagBITMAPFILEHEADER{
unsigned short bfType; // Must be "BM"
unsigned int bfSize; // File Bytes (2-5)
unsigned int bfReserved; // Bitmap file reserved word , Must be 0(6-9)
unsigned int bfOffBits; // Pixel data offset (10-13)
} bmpHeader;
Image description information [40 byte ]
#define uint unsigned int
#define ushort unsigned short
// Image header structure
typedef struct tagBITMAPINFOHEADER{
uint biSize; // Structure size (14-17)
int biWidth; // The width of the image (18-21)
int biHeight; // Height of the image (22-25)
ushort biPlanes; // The level of the target device , by 1(26-27)
ushort biBitCount; // Pixel digits , by 1、4、8 or 24(28-29)
uint biCompression; // Bitmap compression type ,0 For no compression 、1 by BI_RLE8、2 by BI_RLE4(30-33)
uint biSizeImage; // Single pixel data size , be equal to bfSize-bfOffBits (34-37)
int biXPelsPerMeter; // Horizontal resolution , It's usually 0 (38-41)
int biYPelsPerMeter; // Vertical resolution , It's usually 0 (42-45)
uint biClrUsed; // The number of colors in the bitmap color table ,0 Indicates that all palette items are used (46-49)
uint biClrImportant; // Number of important color indexes ,0 It means that everything is important (50-53)
} infoHeader;
Pixel information structure
typedef struct _PixelInfo {
unsigned char rgbBlue; // Blue weight (0-255)
unsigned char rgbGreen; // Green component (0-255)
unsigned char rgbRed; // Red component (0-255)
//unsigned char rgbReserved;// Retain , It has to be for 0
} PixelInfo;
vs 2019 Set the structure alignment rules
The sample picture
Read images
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;
}
Due to different coordinate systems , You need to modify the order of reading pixels
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;
}
Image distortion
Windows Specifies that the number of bytes occupied by a scan line must be 4 Multiple ( That is to long In units of ), Not enough to 0 fill .
How to calculate the number of bytes occupied by a scan line :
DataSizePerLine= (biWidth* biBitCount+31)/8;
// The number of bytes occupied by a scan line
DataSizePerLine= DataSizePerLine/44; // The number of bytes must be 4 Multiple
The size of bitmap data ( Without compression ):
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; // The number of bytes must be 4 Multiple
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;
}
Reference link https://blog.csdn.net/qq_39400113/article/details/104750460
Refer to Daniel video https://www.bilibili.com/video/BV1n5411N7T4?spm_id_from=333.999.0.0
边栏推荐
- Ansible practical Series II_ Getting started with Playbook
- Ansible实战系列二 _ Playbook入门
- In the era of DFI dividends, can TGP become a new benchmark for future DFI?
- Aborted connection 1055898 to db:
- [free setup] asp Net online course selection system design and Implementation (source code +lunwen)
- [number theory] divisor
- JDBC原理
- Test objects involved in safety test
- QT creator design user interface
- Neo4j installation tutorial
猜你喜欢
About string immutability
Pytorch基础
Integration test practice (1) theoretical basis
[number theory] divisor
Did you forget to register or load this tag 报错解决方法
Leetcode 461 Hamming distance
vs2019 使用向导生成一个MFC应用程序
How to build a new project for keil5mdk (with super detailed drawings)
Dotnet replaces asp Net core's underlying communication is the IPC Library of named pipes
连接MySQL数据库出现错误:2059 - authentication plugin ‘caching_sha2_password‘的解决方法
随机推荐
牛客Novice月赛40
How to configure flymcu (STM32 serial port download software) is shown in super detail
Picture coloring project - deoldify
What does usart1 mean
vs2019 第一个MFC应用程序
Introduction and use of automatic machine learning framework (flaml, H2O)
Machine learning notes week02 convolutional neural network
Solution: log4j:warn please initialize the log4j system properly
Error reporting solution - io UnsupportedOperation: can‘t do nonzero end-relative seeks
MySQL主从复制、读写分离
天梯赛练习集题解LV1(all)
记一次某公司面试题:合并有序数组
[蓝桥杯2017初赛]方格分割
Database advanced learning notes -- SQL statement
Armv8-a programming guide MMU (2)
QT creator specify editor settings
Kept VRRP script, preemptive delay, VIP unicast details
Some notes of MySQL
Pytorch基础
What does BSP mean