当前位置:网站首页>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
边栏推荐
- 自动机器学习框架介绍与使用(flaml、h2o)
- [recommended by bloggers] asp Net WebService background data API JSON (with source code)
- About string immutability
- Deoldify project problem - omp:error 15:initializing libiomp5md dll,but found libiomp5md. dll already initialized.
- QT creator specify editor settings
- Basic use of redis
- Ubuntu 20.04 安装 MySQL
- [recommended by bloggers] C # generate a good-looking QR code (with source code)
- Case analysis of data inconsistency caused by Pt OSC table change
- Software I2C based on Hal Library
猜你喜欢

保姆级出题教程

Learn winpwn (2) -- GS protection from scratch
![[Thesis Writing] how to write function description of jsp online examination system](/img/f8/13144e0febf4a576bbcc3290192079.jpg)
[Thesis Writing] how to write function description of jsp online examination system

vs2019 第一个MFC应用程序

Dotnet replaces asp Net core's underlying communication is the IPC Library of named pipes

AcWing 242. A simple integer problem (tree array + difference)
C语言读取BMP文件

QT creator test

机器学习--人口普查数据分析

学习问题1:127.0.0.1拒绝了我们的访问
随机推荐
In the era of DFI dividends, can TGP become a new benchmark for future DFI?
01项目需求分析 (点餐系统)
[recommended by bloggers] C WinForm regularly sends email (with source code)
Knowledge Q & A based on Apache Jena
AcWing 1294. Cherry Blossom explanation
One click extraction of tables in PDF
ES6 Promise 对象
Database advanced learning notes -- SQL statement
[AGC009D]Uninity
Deoldify project problem - omp:error 15:initializing libiomp5md dll,but found libiomp5md. dll already initialized.
数数字游戏
L2-007 家庭房产 (25 分)
Armv8-a programming guide MMU (2)
Introduction and use of automatic machine learning framework (flaml, H2O)
DICOM: Overview
引入了junit为什么还是用不了@Test注解
Some notes of MySQL
MTCNN人脸检测
Record a problem of raspberry pie DNS resolution failure
Why can't I use the @test annotation after introducing JUnit