效果预览
环境准备
FontForge
https://github.com/fontforge/fontforge
FontCreater
http://www.mydown.com/soft/359/509448859.shtml
格式转换
使用在线转换工具将pdf等格式转化成矢量图svg(缩放后不会失真)
https://onlineconvertfree.com/zh/convert-format/pdf-to-svg/
图像切割
将svg格式的矢量图按照方格切割,并另存为对应文字的unicode编码,如将“丢”另存为 20002.svg (“丢”转换成unicode用10进制表示为20002)
思路
- 使用Adobe Illustrator的切片工具进行切割,但是切片只能批量保存为png等位图格式,不能保存为svg..
- 研究svg的编码格式,从svg文件中直接提取出需要的文字
SVG
- SVG 指可伸缩矢量图形 (Scalable Vector Graphics)
- SVG 用来定义用于网络的基于矢量的图形
- SVG 使用 XML 格式定义图形
- SVG 图像在放大或改变尺寸的情况下其图形质量不会有所损失
- SVG 是万维网联盟的标准
- SVG 与诸如 DOM和 XSL 之类的W3C标准是一个整体
SVG的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<svgxmlns="http://www.w3.org/2000/svg"> <pathd="M50,50 A30,30 0 0,1 35,20 L100,100 M110,110 L100,0" style="stroke:#660000; fill:none;"/> </svg> |
上面代码的返回结果如下: 可以看到SVG图像中包含一条曲线和俩条直线,并且第二条直线是立刻第一条直线一段距离的。 所有的这些绘制工作都是在
我们发现在SVG文件格式中,除了相同的文件头和文件尾外,总是先用M指令移动到某一点,然后再根据偏移画直线和曲线,于是想到用以下方法来实现切割:
python脚本如下
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 |
#encoding=utf-8 import urllib def handle(line, ddx, ddy): if 'C' in line: f1 = line.find('C') f2 = line.find(',', f1 + 1) f3 = line.find(',', f2 + 1) f4 = line.find(',', f3 + 1) f5 = line.find(',', f4 + 1) f6 = line.find(',', f5 + 1) f7 = line.find('L', f6 + 1) if f7 == -1: f7 = line.find('z', f6 + 1) x1 = float(line[f1 + 1:f2]) - ddx y1 = float(line[f2 + 1:f3]) - ddy x2 = float(line[f3 + 1:f4]) - ddx y2 = float(line[f4 + 1:f5]) - ddy x = float(line[f5 + 1:f6]) - ddx y = float(line[f6 + 1:f7]) - ddy line = line[:f1+1] + str(x1) + ',' + str(y1) + ',' + str(x2) + ',' + str(y2) + ',' + str(x) + ',' + str(y) + line[f7:] if 'S' in line: print line f1 = line.find('S') f2 = line.find(',', f1 + 1) f3 = line.find(',', f2 + 1) f4 = line.find(',', f3 + 1) f5 = line.find('L', f4 + 1) if f5 == -1: f5 = line.find('z', f5 + 1) x1 = float(line[f1 + 1:f2]) - ddx y1 = float(line[f2 + 1:f3]) - ddy x2 = float(line[f3 + 1:f4]) - ddx y2 = float(line[f4 + 1:f5]) - ddy line = line[:f1+1] + str(x1) + ',' + str(y1) + ',' + str(x2) + ',' + str(y2) + line[f5:] if 'L' in line: f1 = line.find('L') f2 = line.find(',', f1 + 1) f3 = line.find('z', f2 + 1) x = float(line[f1 + 1:f2]) - ddx y = float(line[f2 + 1:f3]) - ddy line = line[:f1+1] + str(x) + ',' + str(y) + line[f3:] return line dict_d = "搭达答瘩打大呆歹傣戴带殆代贷袋待逮怠耽担丹单郸掸胆旦氮但惮淡诞弹" + \ "蛋当挡党荡档刀捣蹈倒岛祷导到稻悼道盗德得的蹬灯登等瞪凳邓堤低滴迪" + \ "敌笛狄涤翟嫡抵底地蒂第帝弟递缔颠掂滇碘点典靛垫电佃甸店惦奠淀殿碉" + \ "叼雕凋刁掉吊钓调跌爹碟蝶迭谍叠丁盯叮钉顶鼎锭定订丢东冬董懂动" + \ "栋侗恫冻洞兜抖斗陡豆逗痘都督毒犊独读堵睹赌杜镀肚度渡妒端短锻段断" + \ "缎堆兑队对墩吨蹲敦顿囤钝盾遁掇哆多夺垛躲朵跺舵剁惰堕" letter = 'd' dict = dict.decode('utf-8').encode('utf-16') offleft = 18.18 offtop = 11.51 dwidth = 40.0 # 每个格子宽度 dheight = 40.0 #每个格子高度 out = [] for i in range(14*14): # 公用文件头 out.append('''<?xml version="1.0" encoding="utf-8"?> <!-- Generator: Adobe Illustrator 17.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="595px" height="841px" viewBox="0 0 40 40" enable-background="new 0 0 40 40" xml:space="preserve"> <g> <title>Layer 1</title> ''') #for i in range(first, first+len(dict)): wt = False with open(letter + '.svg', 'r') as f: #print(f.read()) list1 = f.readlines() index = 0 ddx = 0 ddy = 0 for i in list1: s = i.rstrip('\n') if '<path' in s: wt = True m = s.find('M') comma = s.find(',') c = s.find('c') x = float(s[m+1:comma]) y = float(s[comma+1:c]) dx = int((x - offleft) / dwidth) dy = int((y - offtop) / dheight) ddx = offleft + dx * dwidth ddy = offtop + dy * dheight x = x - ddx y = y - ddy s = s[:m+1] + str(x) + ',' + str(y) + s[c:] #s[comma + 1:c] = str (y - offtop) index = dy * 14 + dx print s if '</g>' in s or '</svg>' in s: wt = False if wt: s = handle(s,ddx,ddy) out[index] = out[index] + s + '\n' for i in range(len(dict)/2 -1): # 公用文件尾 out[i] = out[i] + ''' </g> </svg> ''' with open( letter + '/%d.svg' % (ord(dict[i * 2 + 3])*256+ ord(dict[i * 2 + 2])), 'w') as f2: f2.write(out[i]) |
图像切割后保存的结果
批量导入字形
字形示例
在FontForge的帮助文档中可以找到脚本的用法
新建script.pe,输入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Open($1); Print("...Start batch."); Reencode("unicode"); i = 19969 while(i<40718) if (FileAccess("d/" + ToString(i) + ".svg")==0) Print("handle" + ToString(i) +"...") ; Select(i); Clear(); Import("d/" + ToString(i) + ".svg"); endif i++ endloop Save("u.sfd"); Close(); Quit() |
保存,然后在命令提示符输入
1 2 |
fontforge -script script.pe ht.sfd # sfd是工程文件 |
即可将字形批量导入生成一个u.sfd的工程,用fontforge打开该工程,点击生成ttf即可生成自己的字体
参考
https://blog.csdn.net/huanhuanq1209/article/details/71425032