图片叠加文字

项目上有个小需求,在处理过和图片上叠加文字.本以为很简单.结果找字模都找了半天,找到了中英文又不通用.

后来,又被图片的上下次序,字节正序倒序,按行,还是按列等搞的晕头转向......

还好从网上下了个批量生成字模的软件"PCtoLCD2002.exe"

自己写程序生成个GB2312编码表.

主要是生成源码表.代码很简单,效率格式一律不考虑:

1 int get_hzk_index(const char* str)
2 {
3 char ch;
4 int n;
5
6 ch = *str;
7
8 if (ch < 0)
9 {
10 n = ch - 0xA1;
11
12 if (n > 14 && n < 87)
13 {
14 return ((n - 4) * 94 + str[1] - 0xA1) * 72;
15 }
16 else if (n < 9)
17 {
18 return (n * 94 + str[1] - 0xA1) * 72;
19 }
20 else
21 {
22 return -1;
23 }
24 }
25
26 return (9 * 94 + ch) * 72;;
27 }
28
29
30  int generate_src()
31 {
32 FILE *fp;
33 int i, j;
34 unsigned char buff[2];
35
36 fp = fopen("src.txt", "wb");
37
38 for (i = 0; i < 9; i ++)
39 {
40 for (j = 0; j < 94; j ++)
41 {
42 buff[0] = i + 0xA1;
43 buff[1] = j + 0xA1;
44 fwrite(buff, 2, 1, fp);
45 }
46 }
47
48
49 for (i = 0; i < 128; i ++)
50 {
51 if (isprint(i))
52 {
53 buff[0] = i;
54 }
55 else
56 {
57 buff[0] = ' ';
58 }
59 buff[1] = ' ';
60 fwrite(buff, 2, 1, fp);
61 }
62
63 for (i = 0; i < 60; i ++)
64 {
65 buff[0] = ' ';
66 buff[1] = ' ';
67 fwrite(buff, 2, 1, fp);
68 }
69
70 for (i = 15; i < 87; i ++)
71 {
72 for (j = 0; j < 94; j ++)
73 {
74 buff[0] = i + 0xA1;
75 buff[1] = j + 0xA1;
76 fwrite(buff, 2, 1, fp);
77 }
78 }
79
80 fclose(fp);
81
82 return 0;
83 }

09 10区本来是空的..我把英文的前128个写了进去..为了方便处理每个英文字符后面跟一个空格.

这样的话就和汉字对齐了.

后面的汉字区,按空间往前移.详细的看get_hzk_index函数.

然后通过上述软件把src.txt变为字模文件 (阴码,按列,逆向)  按列主要是处理英文..要不很麻烦.

生成des.txt....然后用EDITPLUS,调格式.去{}等....最后生成一个数组

写入文件 hzk24.h

再用FREEIMAGE把JPG解码,,自己写函数叠加

1 extern unsigned char g_hzk24[561744];
2
3
4  /**
5 * @brief 载入任何可能的图像文件
6 * @param fname {const char *} [in] 所要载入文件名
7 * @return {FIBITMAP *} 成功返回句柄 不成功NULL
8 */
9 FIBITMAP* ImageLoad(const char* fname)
10 {
11 FREE_IMAGE_FORMAT fif;
12 FIBITMAP *dib;
13
14 /* 文件名称非法,直接返回 */
15 if (fname == NULL || strlen(fname) < 2)
16 {
17 fprintf(stderr, "非法文件名\n");
18 return NULL;
19 }
20
21 /* 从文件结构判断类型 */
22 if ((fif = FreeImage_GetFileType(fname, 0)) == FIF_UNKNOWN)
23 {
24 fprintf(stderr, "无法从结构本身判断文件类型\n");
25
26 /* 如果从结构判断不成功,改为从扩展名判断 */
27 if ((fif = FreeImage_GetFIFFromFilename(fname)) == FIF_UNKNOWN)
28 {
29 fprintf(stderr, "无法从扩展名判断类型\n");
30 /* 依然不成功 */
31 return NULL;
32 }
33 }
34
35 if (!FreeImage_FIFSupportsReading(fif))
36 {
37 /* 不支持该类型 */
38 fprintf(stderr, "不支持该类型\n");
39 return NULL;
40 }
41
42 /* 载入文件 */
43 if ((dib = FreeImage_Load(fif, fname, 0)) == NULL)
44 {
45 fprintf(stderr, "无法载入文件\n");
46 return NULL;
47 }
48
49 return dib;
50 }
51
52  /**
53 * @brief 释放图像
54 * @param dib {FIBITMAP *} [in] 输入句柄
55 * @return {void} 无返回值
56 */
57  void ImageUnload(FIBITMAP *dib)
58 {
59 if (dib != NULL)
60 {
61 /* 释放内存 */
62 FreeImage_Unload(dib);
63 }
64 }
65
66
67  /**
68 * @brief 获得字符在字模表中的地址
69 * @param str {const char *} [in] 输入字符
70 * @return {int} 成功返回地址 不成功-1
71 */
72  int get_hzk_index(const char* str)
73 {
74 char ch;
75 int n;
76
77 /* 字符非法 */
78 if (str == NULL || str[0] == 0)
79 {
80 return -1;
81 }
82
83 ch = *str;
84
85 /* 中文 */
86 if (ch < 0)
87 {
88 n = (unsigned char)ch - 0xA1;
89
90 /* 汉字 */
91 if (n > 14 && n < 87)
92 {
93 return ((n - 4) * 94 + (unsigned char)str[1] - 0xA1) * 72;
94 }
95 /* 中文符号 */
96 else if (n < 9)
97 {
98 return (n * 94 + (unsigned char)str[1] - 0xA1) * 72;
99 }
100 else
101 {
102 return -1;
103 }
104 }
105
106 /* 英文 */
107 return (9 * 94 + ch) * 72;;
108 }
109
110  /**
111 * @brief 在图片文件上叠加文字
112 * @param src {const char *} [in] 输入文件
113 * @param des {const char *} [in] 输出文件
114 * @param sx {int} [in] 起始X像素(以1开始,下同)
115 * @param sy {int} [in] 起始Y像素
116 * @param str {const char *} [in] 所要叠加的字符串
117 * @return {int} 成功 0 否则 -1
118 */
119  int img_draw_text(const char *src, const char *des, int sx, int sy, const char *str)
120 {
121 int loc;
122 FIBITMAP *dib;
123 int width, height, pitch, bpp;
124 int i, j, k, m, n, x, y;
125 int len;
126 unsigned char *img, *ptr1, *ptr2;
127 unsigned char pix[4];
128
129
130 /* 参数非法 */
131 if (src == NULL || strlen(src) < 2 || \
132 des == NULL || strlen(des) < 2 || \
133 str == NULL || strlen(str) < 2 || \
134 sx < 1)
135 {
136 return -1;
137 }
138
139 /* 无法载入图片 */
140 if ((dib = ImageLoad(src)) == NULL)
141 {
142 return -1;
143 }
144
145 width = FreeImage_GetWidth(dib);
146 height = FreeImage_GetHeight(dib);
147 pitch = FreeImage_GetPitch(dib);
148 bpp = FreeImage_GetBPP(dib) >> 3;
149
150 /* 计算起始X,Y(像素位置) */
151 x = (sx - 1);
152
153 if (sy < 0)
154 {
155 y = -1 - sy;
156 }
157 else
158 {
159 y = height - sy;
160 }
161
162 if (x >= width || y < 23 || y > height - 1)
163 {
164 ImageUnload(dib);
165 return -1;
166 }
167
168 /* 得出一点 */
169 memset(pix, 255, sizeof(pix));
170
171 /* 求出内存中图像矩阵位置 */
172 img = (unsigned char *)FreeImage_GetBits(dib);
173
174 /* 遍历字符串 */
175 len = strlen(str);
176
177 for (i = 0; i < len; i ++)
178 {
179 /* 求出字模位置 */
180 loc = get_hzk_index(str + i);
181 ptr1 = g_hzk24 + loc;
182
183 /* 中文 */
184 if (str[i] < 0)
185 {
186 if (x + 24 > width)
187 {
188 ptr2 = img + y * pitch + x * bpp;
189
190 for (n = 0; n < 24; n ++)
191 {
192 memset(ptr2 - n * pitch, 0, (width - x) * bpp);
193 }
194
195 x = 0;
196 y -= 24;
197 }
198
199 if (y < 23)
200 {
201 break;
202 }
203
204 // 在XY处画
205   ptr2 = img + y * pitch + x * bpp;
206
207 for (m = 0; m < 24; m ++)
208 {
209 for (j = 0; j < 3; j ++)
210 {
211 for(k = 0; k < 8; k ++)
212 {
213 if (ptr1[m * 3 + j] & (0x01 << k))
214 {
215 memcpy(ptr2 + (-j * 8 - k) * pitch + m * bpp, pix, bpp);
216 }
217 else
218 {
219 memset(ptr2 + (-j * 8 - k) * pitch + m * bpp, 0, bpp);
220 }
221 }
222 }
223 }
224
225 x += 24;
226
227 i ++;
228 }
229 /* 英文 */
230 else
231 {
232 if (x + 12 > width)
233 {
234 ptr2 = img + y * pitch + x * bpp;
235
236 for (n = 0; n < 24; n ++)
237 {
238 memset(ptr2 - n * pitch, 0, (width - x) * bpp);
239 }
240
241 x = 0;
242 y -= 24;
243 }
244
245 if (y < 23)
246 {
247 break;
248 }
249
250 ptr2 = img + y * pitch + x * bpp;
251
252 for (m = 0; m < 12; m ++)
253 {
254 for (j = 0; j < 3; j ++)
255 {
256 for(k = 0; k < 8; k ++)
257 {
258 if (ptr1[m * 3 + j] & (0x01 << k))
259 {
260 memcpy(ptr2 + (-j * 8 - k) * pitch + m * bpp, pix, bpp);
261 }
262 else
263 {
264 memset(ptr2 + (-j * 8 - k) * pitch + m * bpp, 0, bpp);
265 }
266 }
267 }
268 }
269
270 x += 12;
271 }
272 }
273
274 if (x < width && y >= 23)
275 {
276 ptr2 = img + y * pitch + x * bpp;
277 width -= x;
278 width *= bpp;
279
280 for (i = 0; i < 24; i ++)
281 {
282 memset(ptr2 - i * pitch, 0, width);
283 }
284 }
285
286 FreeImage_Save(FIF_JPEG, dib, des, 0);
287 FreeImage_Unload(dib);
288 return 0;
289 }

至此大功告成..呵呵...

原文地址:https://www.cnblogs.com/javado/p/1892007.html