首先呢,这是昨天到今天晚上的学习,总结下。
发现我自己的问题
1.c语言还是有问题,原因做的东西太少,理论知识不能结合实际,比如unsigned char 存储 一个字节和char存储一个字节的差别。
2.数学很重要啊。
3.学一个东西,一定要把这个东西学的屎出来了,再换。要么和没学没啥区别。
想要灰度化首先干什么呢?对了就是找图片。
这个是我在人人网注册栏找到的。
第二步呢?图片存储格式。
根据linux的哲学“一切皆文件”,所以这个图片一定可以用c语言的文件操作函数打开,我用的是c语言,当然用到文件操作这一节,复习复习。
第三部呢?
既然图片是文件,那就要读出来,文件操作就那么几个函数,都是字节或者二进制,然后读出来放在哪里呢?怎么操作这些数据呢?这个就先要查查图片编程方面的东西,百度“图片编程”会出现很多东西的,其中你会知道jpg和bmp两种格式的图片。
我发现,jpg是一种压缩后的图片(为了减轻网络传送数据的压力),bmp等等的图片太大了。大家写过哈夫曼的都知道,一个文件压缩后,它是直接显示不出来的,必须解压,解压后才是原始文件(jpg文件在网上传输的是压缩的文件,打开时候是对其解压),如果你直接对jpg操作就是大错特错(你懂得)。
下来就是要将jpg(网上的图片一般都是jpg)转换成bmp。linux下有个好东东
对于上面的东西,直接sudo就行。
现在的问题就明了了,是对bmp图片进行操作。
百度bmp。立马看到它的结构。
接着上面的问题,我们现在就知道从文件读出的数据放在哪里了。就是那几个结构体中。
现在就上代码吧。
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130 |
#include <stdio.h> #include <stdlib.h> typedef unsigned short
WORD; typedef unsigned int
DWORD; typedef unsigned int
LONG; typedef struct
tagBITMAPFILEHEADER { WORD bfType; // 位图文件的类型,必须为BM(1-2字节) DWORD bfSize; // 位图文件的大小,以字节为单位(3-6字节) WORD bfReserved1; // 位图文件保留字,必须为0(7-8字节) WORD bfReserved2; // 位图文件保留字,必须为0(9-10字节) DWORD bfOffBits; // 位图数据的起始位置,以相对于位图(11-14字节) // 文件头的偏移量表示,以字节为单位 } BITMAPFILEHEADER; typedef struct
tagBITMAPINFOHEADER{ DWORD biSize; // 本结构所占用字节数(15-18字节) LONG biWidth; // 位图的宽度,以像素为单位(19-22字节) LONG biHeight; // 位图的高度,以像素为单位(23-26字节) WORD biPlanes; // 目标设备的级别,必须为1(27-28字节) WORD biBitCount; // 每个像素所需的位数,必须是1(双色),(29-30字节) // 4(16色),8(256色)16(高彩色)或24(真彩色)之一 DWORD biCompression; // 位图压缩类型,必须是 0(不压缩),(31-34字节) // 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一 DWORD biSizeImage; // 位图的大小(其中包含了为了补齐行数是4的倍数而添加的空字节),以字节为单位(35-38字节) LONG biXPelsPerMeter; // 位图水平分辨率,每米像素数(39-42字节) LONG biYPelsPerMeter; // 位图垂直分辨率,每米像素数(43-46字节) DWORD biClrUsed; // 位图实际使用的颜色表中的颜色数(47-50字节) DWORD biClrImportant; // 位图显示过程中重要的颜色数(51-54字节) } BITMAPINFOHEADER; typedef struct { unsigned char
b; unsigned char
g; unsigned char
r; }RGB; /* typedef struct tagRGBQUAD { BYTE rgbBlue;// 蓝色的亮度(值范围为0-255) BYTE rgbGreen; // 绿色的亮度(值范围为0-255) BYTE rgbRed; // 红色的亮度(值范围为0-255) BYTE rgbReserved;// 保留,必须为0 } RGBQUAD; typedef struct tagBITMAPINFO { BITMAPINFOHEADER bmiHeader; // 位图信息头 RGBQUAD bmiColors[1]; // 颜色表 } BITMAPINFO; */ void
grey() { FILE *fp; FILE *fp1; char
a[30]; BITMAPFILEHEADER head; BITMAPINFOHEADER head1; int
trueWidth; int
i; int
j; int
k = 0; unsigned char
f = 0; printf( "please input filename:" ); scanf( "%s" , a); if ((fp = fopen(a, "rb" )) == NULL) { printf( "file start error seek\n" ); exit(1); } if ((fp1 = fopen( "11.bmp" , "wb" )) == NULL) { printf( "file start error\n" ); exit(1); } fread(&head, 14, 1, fp); fread(&head1, 40, 1, fp); printf( "width:%d\n" , head1.biWidth); printf( "biHeigth:%d\n" , head1.biHeight); printf( "biBitCount:%d\n" , head1.biBitCount); trueWidth = (head1.biWidth * head1.biBitCount/8 +3)/4*4; int
p = trueWidth - trueWidth/3 * 3; RGB rgb[head1.biHeight][head1.biWidth]; unsigned char
b[head1.biHeight][head1.biWidth]; for (j = 0; j < head1.biHeight; j++ ) { for (i = 0; i < head1.biWidth; i++) { fread(&rgb[j][i], 3, 1, fp); k++; } fseek(fp, p, SEEK_CUR); } for (i = 0; i < head1.biHeight; i++) for (j = 0; j < head1.biWidth; j++) { b[i][j] = (rgb[i][j].b + rgb[i][j].g + rgb[i][j].r)/3; } fwrite(&head, 14, 1, fp1); fwrite(&head1, 40, 1, fp1); for (i = 0; i < head1.biHeight; i++) { for (j = 0; j < head1.biWidth; j++) { fwrite(&b[i][j], 1, 3, fp1); } fwrite(&f, 1, p,fp1); } fclose(fp1); fclose(fp); } int
main() { grey(); } |
然后看看效果。
原文:http://www.cnblogs.com/xiongge/p/3599002.html