James Hoi's Blog

C语言读取BMP格式图片并修改保存

Word count: 553Reading time: 3 min
2021/05/10 Share

朋友之前请教我BMP图片格式的问题,网上查了查参考这个https://blog.csdn.net/u013066730/article/details/82625158
刚好学习了一波,代码如下(其实准确来讲这个是c++代码,但除了用到了cout,其他都与c一致)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include <iostream>
#include <windows.h>
using namespace std;

typedef struct
{
BYTE b;
BYTE g;
BYTE r;
}RGB;

typedef struct
{
BYTE b;
BYTE g;
BYTE r;
BYTE a;
}RGBA;

RGBA imgOpr32(RGBA a)
{
RGBA b;
b.b = 255 - a.b;
b.g = 255 - a.g;
b.r = 255 - a.r;
b.a = a.a;
return b;
}

RGB imgOpr24(RGB a)
{
RGB b;
b.b = 255 - a.b;
b.g = 255 - a.g;
b.r = 255 - a.r;
return b;
}

int main()
{
BITMAPFILEHEADER fileHeader;
BITMAPINFOHEADER infoHeader;
FILE* pfin = fopen("./test2_32.bmp", "rb");
FILE* pfout = fopen("./test3.bmp", "wb");
//Read the Bitmap file header;
fread(&fileHeader, sizeof(BITMAPFILEHEADER), 1, pfin);
//Read the Bitmap info header;
fread(&infoHeader, sizeof(BITMAPINFOHEADER), 1, pfin);
//Define variable of Bitmap;
int ImageHeight = infoHeader.biHeight;
int ImageWidth = infoHeader.biWidth;
int BitsPerPixel = infoHeader.biBitCount;
//Calculate
int LineByteCnt = (((ImageWidth * infoHeader.biBitCount) + 31) >> 5) << 2;
int ImageDataSize = LineByteCnt * ImageHeight;
int PaddingSize = 4 - ((ImageWidth * BitsPerPixel) >> 3) & 3;
BYTE *pad = new BYTE[PaddingSize];
int PixelCnt = ImageHeight * ImageWidth;
//Check BitsPerPixel
if (BitsPerPixel != 24 && BitsPerPixel != 32) {
cout << "此程序不支持非24位且非32位的BMP图片" << endl;
return 0;
}

if (BitsPerPixel == 32) {
//Read Bitmp
RGBA *img = new RGBA[PixelCnt];
for (int i = 0; i < ImageHeight; i++) {
for (int j = 0; j < ImageWidth; j++) {
int index = i * ImageWidth + j;
fread(&img[index], sizeof(RGBA), 1, pfin);
img[index] = imgOpr32(img[index]); //反色运算
}
fread(pad, 1, PaddingSize, pfin);
}

//将修改后的图片保存到文件
fwrite(&fileHeader, sizeof(fileHeader), 1, pfout);
fwrite(&infoHeader, sizeof(infoHeader), 1, pfout);
for (int i = 0; i < ImageHeight; i++) {
for (int j = 0; j < ImageWidth; j++)
fwrite(&img[i * ImageWidth + j], sizeof(RGBA), 1, pfout);
fwrite(pad, 1, PaddingSize, pfout);
}
}
else if (BitsPerPixel == 24) {
//Read Bitmp
RGB *img = new RGB[PixelCnt];
for (int i = 0; i < ImageHeight; i++) {
for (int j = 0; j < ImageWidth; j++) {
int index = i * ImageWidth + j;
fread(&img[index], sizeof(RGB), 1, pfin);
img[index] = imgOpr24(img[index]); //反色运算
}
fread(pad, 1, PaddingSize, pfin);
}

//将修改后的图片保存到文件
fwrite(&fileHeader, sizeof(fileHeader), 1, pfout);
fwrite(&infoHeader, sizeof(infoHeader), 1, pfout);
for (int i = 0; i < ImageHeight; i++) {
for (int j = 0; j < ImageWidth; j++)
fwrite(&img[i * ImageWidth + j], sizeof(RGB), 1, pfout);
fwrite(pad, 1, PaddingSize, pfout);
}
}

//End
fclose(pfin);
fclose(pfout);
return 0;
}

效果

原图(左),反色后(右)
image.png image.png

CATALOG
  1. 1. 效果