(原創) 如何使用Standard Library作影像處理? (C/C++) (Image Processing)
在昨天的Blog,我們使用了Standard Library讀寫bmp圖檔,其中的unsigned char *,雖然是一個一維陣列,但骨子是一個二維陣列,該如何實際的做影像處理呢?
先示範一個最簡單的影像處理,產生一個紅色的圖形。
1
/*
2
(C) OOMusou 2007 http://oomusou.cnblogs.com
3![](/Images/OutliningIndicators/InBlock.gif)
4
Filename : BmpPixelByPixel.cpp
5
Compiler : Visual C++ 8.0 / ANSI C / ISO C++
6
Description : Demo the how to process image pixel by pixel
7
Release : 02/19/2007 1.0
8
*/
9![](/Images/OutliningIndicators/None.gif)
10
#include "stdio.h"
11
#include "stdlib.h"
12![](/Images/OutliningIndicators/None.gif)
13
int bmp_read(unsigned char *image, int, int, char *);
14
int bmp_write(unsigned char *image, int, int, char *);
15![](/Images/OutliningIndicators/None.gif)
16
int main() {
17
unsigned char *image;
18
int xsize = 512;
19
int ysize = 512;
20![](/Images/OutliningIndicators/InBlock.gif)
21
image = (unsigned char *)malloc((size_t)xsize * ysize * 3);
22
if (image == NULL)
23
return -1;
24
25
for(int y = 0; y != ysize; ++y) {
26
for(int x = 0; x != xsize; ++x) {
27
// set (R,G,B) = (255,0,0)
28
// R
29
*(image + 3 * (y * xsize + x) + 2) = 255;
30
// G
31
*(image + 3 * (y * xsize + x) + 1) = 0;
32
// B
33
*(image + 3 * (y * xsize + x) + 0) = 0;
34
}
35
}
36
37
bmp_write(image, xsize, ysize, "onlyRed");
38
39
free(image);
40
}
41![](/Images/OutliningIndicators/None.gif)
42
int bmp_read(unsigned char *image, int xsize, int ysize, char *filename) {
43
char fname_bmp[128];
44
sprintf(fname_bmp, "%s.bmp", filename);
45
46
FILE *fp;
47
if (!(fp = fopen(fname_bmp, "rb")))
48
return -1;
49
50
unsigned char header[54];
51
fread(header, sizeof(unsigned char), 54, fp);
52
fread(image, sizeof(unsigned char), (size_t)(long)xsize * ysize * 3, fp);
53
54
fclose(fp);
55
return 0;
56
}
57![](/Images/OutliningIndicators/None.gif)
58
int bmp_write(unsigned char *image, int xsize, int ysize, char *filename) {
59
unsigned char header[54] = {
60
0x42, 0x4d, 0, 0, 0, 0, 0, 0, 0, 0,
61
54, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 24, 0,
62
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
63
0, 0, 0, 0
64
};
65
66
long file_size = (long)xsize * (long)ysize * 3 + 54;
67
header[2] = (unsigned char)(file_size &0x000000ff);
68
header[3] = (file_size >> 8) & 0x000000ff;
69
header[4] = (file_size >> 16) & 0x000000ff;
70
header[5] = (file_size >> 24) & 0x000000ff;
71
72
long width = xsize;
73
header[18] = width & 0x000000ff;
74
header[19] = (width >> 8) &0x000000ff;
75
header[20] = (width >> 16) &0x000000ff;
76
header[21] = (width >> 24) &0x000000ff;
77
78
long height = ysize;
79
header[22] = height &0x000000ff;
80
header[23] = (height >> 8) &0x000000ff;
81
header[24] = (height >> 16) &0x000000ff;
82
header[25] = (height >> 24) &0x000000ff;
83![](/Images/OutliningIndicators/InBlock.gif)
84
char fname_bmp[128];
85
sprintf(fname_bmp, "%s.bmp", filename);
86
87
FILE *fp;
88
if (!(fp = fopen(fname_bmp, "wb")))
89
return -1;
90
91
fwrite(header, sizeof(unsigned char), 54, fp);
92
fwrite(image, sizeof(unsigned char), (size_t)(long)xsize * ysize * 3, fp);
93
94
fclose(fp);
95
return 0;
96
}
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
2
![](/Images/OutliningIndicators/InBlock.gif)
3
![](/Images/OutliningIndicators/InBlock.gif)
4
![](/Images/OutliningIndicators/InBlock.gif)
5
![](/Images/OutliningIndicators/InBlock.gif)
6
![](/Images/OutliningIndicators/InBlock.gif)
7
![](/Images/OutliningIndicators/InBlock.gif)
8
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
9
![](/Images/OutliningIndicators/None.gif)
10
![](/Images/OutliningIndicators/None.gif)
11
![](/Images/OutliningIndicators/None.gif)
12
![](/Images/OutliningIndicators/None.gif)
13
![](/Images/OutliningIndicators/None.gif)
14
![](/Images/OutliningIndicators/None.gif)
15
![](/Images/OutliningIndicators/None.gif)
16
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
17
![](/Images/OutliningIndicators/InBlock.gif)
18
![](/Images/OutliningIndicators/InBlock.gif)
19
![](/Images/OutliningIndicators/InBlock.gif)
20
![](/Images/OutliningIndicators/InBlock.gif)
21
![](/Images/OutliningIndicators/InBlock.gif)
22
![](/Images/OutliningIndicators/InBlock.gif)
23
![](/Images/OutliningIndicators/InBlock.gif)
24
![](/Images/OutliningIndicators/InBlock.gif)
25
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
26
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
27
![](/Images/OutliningIndicators/InBlock.gif)
28
![](/Images/OutliningIndicators/InBlock.gif)
29
![](/Images/OutliningIndicators/InBlock.gif)
30
![](/Images/OutliningIndicators/InBlock.gif)
31
![](/Images/OutliningIndicators/InBlock.gif)
32
![](/Images/OutliningIndicators/InBlock.gif)
33
![](/Images/OutliningIndicators/InBlock.gif)
34
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
35
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
36
![](/Images/OutliningIndicators/InBlock.gif)
37
![](/Images/OutliningIndicators/InBlock.gif)
38
![](/Images/OutliningIndicators/InBlock.gif)
39
![](/Images/OutliningIndicators/InBlock.gif)
40
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
41
![](/Images/OutliningIndicators/None.gif)
42
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
43
![](/Images/OutliningIndicators/InBlock.gif)
44
![](/Images/OutliningIndicators/InBlock.gif)
45
![](/Images/OutliningIndicators/InBlock.gif)
46
![](/Images/OutliningIndicators/InBlock.gif)
47
![](/Images/OutliningIndicators/InBlock.gif)
48
![](/Images/OutliningIndicators/InBlock.gif)
49
![](/Images/OutliningIndicators/InBlock.gif)
50
![](/Images/OutliningIndicators/InBlock.gif)
51
![](/Images/OutliningIndicators/InBlock.gif)
52
![](/Images/OutliningIndicators/InBlock.gif)
53
![](/Images/OutliningIndicators/InBlock.gif)
54
![](/Images/OutliningIndicators/InBlock.gif)
55
![](/Images/OutliningIndicators/InBlock.gif)
56
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
57
![](/Images/OutliningIndicators/None.gif)
58
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
59
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
60
![](/Images/OutliningIndicators/InBlock.gif)
61
![](/Images/OutliningIndicators/InBlock.gif)
62
![](/Images/OutliningIndicators/InBlock.gif)
63
![](/Images/OutliningIndicators/InBlock.gif)
64
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
65
![](/Images/OutliningIndicators/InBlock.gif)
66
![](/Images/OutliningIndicators/InBlock.gif)
67
![](/Images/OutliningIndicators/InBlock.gif)
68
![](/Images/OutliningIndicators/InBlock.gif)
69
![](/Images/OutliningIndicators/InBlock.gif)
70
![](/Images/OutliningIndicators/InBlock.gif)
71
![](/Images/OutliningIndicators/InBlock.gif)
72
![](/Images/OutliningIndicators/InBlock.gif)
73
![](/Images/OutliningIndicators/InBlock.gif)
74
![](/Images/OutliningIndicators/InBlock.gif)
75
![](/Images/OutliningIndicators/InBlock.gif)
76
![](/Images/OutliningIndicators/InBlock.gif)
77
![](/Images/OutliningIndicators/InBlock.gif)
78
![](/Images/OutliningIndicators/InBlock.gif)
79
![](/Images/OutliningIndicators/InBlock.gif)
80
![](/Images/OutliningIndicators/InBlock.gif)
81
![](/Images/OutliningIndicators/InBlock.gif)
82
![](/Images/OutliningIndicators/InBlock.gif)
83
![](/Images/OutliningIndicators/InBlock.gif)
84
![](/Images/OutliningIndicators/InBlock.gif)
85
![](/Images/OutliningIndicators/InBlock.gif)
86
![](/Images/OutliningIndicators/InBlock.gif)
87
![](/Images/OutliningIndicators/InBlock.gif)
88
![](/Images/OutliningIndicators/InBlock.gif)
89
![](/Images/OutliningIndicators/InBlock.gif)
90
![](/Images/OutliningIndicators/InBlock.gif)
91
![](/Images/OutliningIndicators/InBlock.gif)
92
![](/Images/OutliningIndicators/InBlock.gif)
93
![](/Images/OutliningIndicators/InBlock.gif)
94
![](/Images/OutliningIndicators/InBlock.gif)
95
![](/Images/OutliningIndicators/InBlock.gif)
96
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
本範例試著用此一維陣列作一個最簡單的影像處理,將圖片由右向左作mirror。
1
/*
2
(C) OOMusou 2007 http://oomusou.cnblogs.com
3![](/Images/OutliningIndicators/InBlock.gif)
4
Filename : BmpRightSideLeft.cpp
5
Compiler : Visual C++ 8.0 / ANSI C / ISO C++
6
Description : Demo the how to right side to left by standard library
7
Release : 02/04/2007 1.0
8
*/
9![](/Images/OutliningIndicators/None.gif)
10
#include "stdio.h"
11
#include "stdlib.h"
12![](/Images/OutliningIndicators/None.gif)
13
int bmp_read(unsigned char *, int , int , char *);
14
int bmp_write(unsigned char *, int , int , char *);
15
int bmp_rightsideleft(unsigned char *, unsigned char *, int , int);
16![](/Images/OutliningIndicators/None.gif)
17
int main() {
18
unsigned char *ori, *tar;
19
int xsize = 512;
20
int ysize = 512;
21![](/Images/OutliningIndicators/InBlock.gif)
22
ori = (unsigned char *)malloc((size_t)xsize * ysize * 3);
23
tar = (unsigned char *)malloc((size_t)xsize * ysize * 3);
24
25
bmp_read(ori, xsize, ysize, "clena");
26
bmp_rightsideleft(ori, tar, xsize, ysize);
27
bmp_write(tar, xsize, ysize, "clena_rightsideleft");
28
}
29![](/Images/OutliningIndicators/None.gif)
30![](/Images/OutliningIndicators/None.gif)
31
int bmp_read(unsigned char *image, int xsize, int ysize, char *filename) {
32
char fname_bmp[128];
33
sprintf(fname_bmp, "%s.bmp", filename);
34
35
FILE *fp;
36
if (!(fp = fopen(fname_bmp, "rb")))
37
return -1;
38
39
unsigned char header[54];
40
fread(header, sizeof(unsigned char), 54, fp);
41
fread(image, sizeof(unsigned char), (size_t)(long)xsize * ysize * 3, fp);
42
43
fclose(fp);
44
return 0;
45
}
46![](/Images/OutliningIndicators/None.gif)
47
int bmp_write(unsigned char *image, int xsize, int ysize, char *filename) {
48
unsigned char header[54] = {
49
0x42, 0x4d, 0, 0, 0, 0, 0, 0, 0, 0,
50
54, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 24, 0,
51
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
52
0, 0, 0, 0
53
};
54
55
long file_size = (long)xsize * (long)ysize * 3 + 54;
56
header[2] = (unsigned char)(file_size &0x000000ff);
57
header[3] = (file_size >> 8) & 0x000000ff;
58
header[4] = (file_size >> 16) & 0x000000ff;
59
header[5] = (file_size >> 24) & 0x000000ff;
60
61
long width = xsize;
62
header[18] = width & 0x000000ff;
63
header[19] = (width >> 8) &0x000000ff;
64
header[20] = (width >> 16) &0x000000ff;
65
header[21] = (width >> 24) &0x000000ff;
66
67
long height = ysize;
68
header[22] = height &0x000000ff;
69
header[23] = (height >> 8) &0x000000ff;
70
header[24] = (height >> 16) &0x000000ff;
71
header[25] = (height >> 24) &0x000000ff;
72![](/Images/OutliningIndicators/InBlock.gif)
73
char fname_bmp[128];
74
sprintf(fname_bmp, "%s.bmp", filename);
75
76
FILE *fp;
77
if (!(fp = fopen(fname_bmp, "wb")))
78
return -1;
79
80
fwrite(header, sizeof(unsigned char), 54, fp);
81
fwrite(image, sizeof(unsigned char), (size_t)(long)xsize * ysize * 3, fp);
82
83
fclose(fp);
84
return 0;
85
}
86![](/Images/OutliningIndicators/None.gif)
87
int bmp_rightsideleft(unsigned char *ori, unsigned char *tar, int xsize, int ysize) {
88
// x-------
89
// y
90
// |
91
// |
92
// |
93
94
int avgX = (0 + xsize) / 2;
95
for(int y = 0; y != ysize; ++y) {
96
for(int x = 0; x != xsize; ++x) {
97
int tarX = 2 * avgX - x;
98
// R
99
*(tar + 3 * (y * xsize + tarX) + 2) = *(ori + 3 * (y * xsize + x) + 2);
100
// G
101
*(tar + 3 * (y * xsize + tarX) + 1) = *(ori + 3 * (y * xsize + x) + 1);
102
// B
103
*(tar + 3 * (y * xsize + tarX) + 0) = *(ori + 3 * (y * xsize + x) + 0);
104
}
105
}
106
107
return 0;
108
}
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
2
![](/Images/OutliningIndicators/InBlock.gif)
3
![](/Images/OutliningIndicators/InBlock.gif)
4
![](/Images/OutliningIndicators/InBlock.gif)
5
![](/Images/OutliningIndicators/InBlock.gif)
6
![](/Images/OutliningIndicators/InBlock.gif)
7
![](/Images/OutliningIndicators/InBlock.gif)
8
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
9
![](/Images/OutliningIndicators/None.gif)
10
![](/Images/OutliningIndicators/None.gif)
11
![](/Images/OutliningIndicators/None.gif)
12
![](/Images/OutliningIndicators/None.gif)
13
![](/Images/OutliningIndicators/None.gif)
14
![](/Images/OutliningIndicators/None.gif)
15
![](/Images/OutliningIndicators/None.gif)
16
![](/Images/OutliningIndicators/None.gif)
17
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
18
![](/Images/OutliningIndicators/InBlock.gif)
19
![](/Images/OutliningIndicators/InBlock.gif)
20
![](/Images/OutliningIndicators/InBlock.gif)
21
![](/Images/OutliningIndicators/InBlock.gif)
22
![](/Images/OutliningIndicators/InBlock.gif)
23
![](/Images/OutliningIndicators/InBlock.gif)
24
![](/Images/OutliningIndicators/InBlock.gif)
25
![](/Images/OutliningIndicators/InBlock.gif)
26
![](/Images/OutliningIndicators/InBlock.gif)
27
![](/Images/OutliningIndicators/InBlock.gif)
28
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
29
![](/Images/OutliningIndicators/None.gif)
30
![](/Images/OutliningIndicators/None.gif)
31
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
32
![](/Images/OutliningIndicators/InBlock.gif)
33
![](/Images/OutliningIndicators/InBlock.gif)
34
![](/Images/OutliningIndicators/InBlock.gif)
35
![](/Images/OutliningIndicators/InBlock.gif)
36
![](/Images/OutliningIndicators/InBlock.gif)
37
![](/Images/OutliningIndicators/InBlock.gif)
38
![](/Images/OutliningIndicators/InBlock.gif)
39
![](/Images/OutliningIndicators/InBlock.gif)
40
![](/Images/OutliningIndicators/InBlock.gif)
41
![](/Images/OutliningIndicators/InBlock.gif)
42
![](/Images/OutliningIndicators/InBlock.gif)
43
![](/Images/OutliningIndicators/InBlock.gif)
44
![](/Images/OutliningIndicators/InBlock.gif)
45
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
46
![](/Images/OutliningIndicators/None.gif)
47
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
48
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
49
![](/Images/OutliningIndicators/InBlock.gif)
50
![](/Images/OutliningIndicators/InBlock.gif)
51
![](/Images/OutliningIndicators/InBlock.gif)
52
![](/Images/OutliningIndicators/InBlock.gif)
53
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
54
![](/Images/OutliningIndicators/InBlock.gif)
55
![](/Images/OutliningIndicators/InBlock.gif)
56
![](/Images/OutliningIndicators/InBlock.gif)
57
![](/Images/OutliningIndicators/InBlock.gif)
58
![](/Images/OutliningIndicators/InBlock.gif)
59
![](/Images/OutliningIndicators/InBlock.gif)
60
![](/Images/OutliningIndicators/InBlock.gif)
61
![](/Images/OutliningIndicators/InBlock.gif)
62
![](/Images/OutliningIndicators/InBlock.gif)
63
![](/Images/OutliningIndicators/InBlock.gif)
64
![](/Images/OutliningIndicators/InBlock.gif)
65
![](/Images/OutliningIndicators/InBlock.gif)
66
![](/Images/OutliningIndicators/InBlock.gif)
67
![](/Images/OutliningIndicators/InBlock.gif)
68
![](/Images/OutliningIndicators/InBlock.gif)
69
![](/Images/OutliningIndicators/InBlock.gif)
70
![](/Images/OutliningIndicators/InBlock.gif)
71
![](/Images/OutliningIndicators/InBlock.gif)
72
![](/Images/OutliningIndicators/InBlock.gif)
73
![](/Images/OutliningIndicators/InBlock.gif)
74
![](/Images/OutliningIndicators/InBlock.gif)
75
![](/Images/OutliningIndicators/InBlock.gif)
76
![](/Images/OutliningIndicators/InBlock.gif)
77
![](/Images/OutliningIndicators/InBlock.gif)
78
![](/Images/OutliningIndicators/InBlock.gif)
79
![](/Images/OutliningIndicators/InBlock.gif)
80
![](/Images/OutliningIndicators/InBlock.gif)
81
![](/Images/OutliningIndicators/InBlock.gif)
82
![](/Images/OutliningIndicators/InBlock.gif)
83
![](/Images/OutliningIndicators/InBlock.gif)
84
![](/Images/OutliningIndicators/InBlock.gif)
85
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
86
![](/Images/OutliningIndicators/None.gif)
87
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
88
![](/Images/OutliningIndicators/InBlock.gif)
89
![](/Images/OutliningIndicators/InBlock.gif)
90
![](/Images/OutliningIndicators/InBlock.gif)
91
![](/Images/OutliningIndicators/InBlock.gif)
92
![](/Images/OutliningIndicators/InBlock.gif)
93
![](/Images/OutliningIndicators/InBlock.gif)
94
![](/Images/OutliningIndicators/InBlock.gif)
95
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
96
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
97
![](/Images/OutliningIndicators/InBlock.gif)
98
![](/Images/OutliningIndicators/InBlock.gif)
99
![](/Images/OutliningIndicators/InBlock.gif)
100
![](/Images/OutliningIndicators/InBlock.gif)
101
![](/Images/OutliningIndicators/InBlock.gif)
102
![](/Images/OutliningIndicators/InBlock.gif)
103
![](/Images/OutliningIndicators/InBlock.gif)
104
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
105
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
106
![](/Images/OutliningIndicators/InBlock.gif)
107
![](/Images/OutliningIndicators/InBlock.gif)
108
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
125行到135行為實際的一個pixel一個pixel作影像處理。
原圖
![](/images/cnblogs_com/oomusou/clena.jpg)
執行結果
![](/images/cnblogs_com/oomusou/clena_rightsideleft.jpg)
Remark
在撰寫處理陣列的迴圈時,應該先從z,再y,最後才是x,為什麼呢?因為當宣告陣列時,是int ia[sizey][sizex],所以是先y,然後才x。
See Also
(原創) 如何使用ANSI C/ISO C++讀寫bmp圖檔? (C/C++)