我用枕头在图片上画文字:
from PIL import Image, ImageDraw, ImageFont
im = Image.new("L", (400, 50), color="black")
draw = ImageDraw.Draw(im)
font = ImageFont.truetype("Roboto-Medium.ttf", 28)
draw.text((0, 0), "How To Get Small Caps?", font=font, fill="white")
im.save('small_caps.png')但我想不出如何用小写字母而不是普通字符来画字符串。
发布于 2020-02-13 00:00:16
最新版本的Roboto介质确实包含实际绘制到大小的小大写,但它们没有映射到Unicode代码点。这意味着在简单字符串中指定字符的常规方法将无法工作。
OpenType感知软件可以通过OpenType feature c2sc (它用大写字母替换大写字母的等价物)和smcp (做同样的操作,但只用于小写字母)访问字体。这些翻译表驻留在TrueType GSUB表中的字体中--它们是以一种特别狡猾的格式编码的。这可能就是为什么PIL程序员从来不去实现它的原因(以及其他可能有用的OpenType特性,例如每种语言的超级和订阅、克尔宁和本地化信函表单)。
Python模块freetype可以访问原始符号。但是,类似地,FreeType开发人员也曾短暂地考虑过将OpenType特性解析添加到他们的库中,但是决定不这样做,并且FreeType只关注于绘图。尽管如此,您仍然可以使用freetype获取所有字体中的任何字形并对其进行栅格化。唯一的问题是,您将对字形索引进行硬编码。
“字形索引”只不过是‘什么编码值对应于哪个图像’,从0开始,一直持续到最后一个字形。字体的可能编码位于字体数据的其他地方;它可能包含解密的Windows编码(ol的“代码页”(但更大))、完整的Unicode编码、MacRoman和少量的其他编码。您只需选择一个编码,并告诉您在该编码中的字符代码,freetype将为您查找正确的字形。
但是OpenType特性可以推翻这一点。它是一组独立的翻译,由您选择的特性(以及哪个脚本,甚至是哪种语言)驱动。一个完全了解OpenType的界面将看到您的字形,使用所需的特性增加赌注,并返回原始的字形索引。
由于单个字体文件中可能有很多原始的象形文字,所以并不是每个编码都指向字体中的每个字形。例如,想象一下可怜的旧MacRoman,只有256个可能的字符。你不可能用它来处理所有的机器人1294个符号。即使是具有成千上万个定义条目的Unicode也无法解决所有这些问题,因为可以为某些字符(如斜杠大写)创建风格替代方案,就Unicode而言,这些字符与它们的原始字符相同,以及用作连接的字符组合,其中像Zapfino这样的完整序列被绘制成一个单一的复杂字形(字体为"Zapfino";而且非常棒)。
一些字体设计器允许通过‘私有’Unicode代码点访问特殊字符(意思是“每个人都可以自由定义”),但我认为Roboto没有这种功能。
可以向FreeType请求完整的GSUB表,然后解析这个表以找到适合于小型股的翻译,如果这样做,您会很高兴地发现,您的代码随后将与任何字体一起使用真正的小大写(!),但这是一项巨大的工作。
所以我作弊了。有些软件允许对字体进行每张字形检查,我使用AdobeA..Z查找所有A..Z的小盘字形索引。
不过,这确实有缺点。它只适用于Roboto媒体的一个特定版本(可靠),因为设计人员可以为每个新版本添加、删除和移动图形。记住,这对其他软件如何处理字体没有任何影响!对编码表和OpenType表进行了调整以匹配,因此软件不需要了解每种字体的字形索引。
也不能保证中的这些相同的索引能够与Roboto家族中的其他字体一起工作。设计人员可能使用了完全相同的布局,但可能没有。实际上,正如上面所述,他们甚至不应该去关心它。
我已经下载了最新版本2.137;2017年;如果你没有这个版本,请先下载!
下面是一些示例代码,用于打印所有小盘字形的灰度值,它们的水平偏移距字形起始点(左偏移距)和垂直高度(以像素为单位),从基线测量。随意调整以匹配PIL自己的文本绘图例程;它可能需要一些细节才能得到正确的™。
(对相当基本的代码示例表示歉意。我设法破坏了Python2.7和3(某样东西)的PIL安装,因此我无法以图形方式显示一些东西;幸运的是,freetype模块仍然工作。
import freetype
import os.path
smcapGlyphs = [563,562,561,560,552,486,485,484,483,482,481,480,479,
478,477,476,475,474,473,472,471,470,469,468,467,466]
def dump_bytes(buf,wide,high):
for y in range(high):
for x in range(wide):
print ('%02x ' % buf[y*wide+x], end='')
print ()
face = freetype.Face(os.path.expanduser('~')+"/Library/Fonts/Roboto-Medium.ttf")
face.set_char_size( 48*64 )
for index,i in enumerate(smcapGlyphs):
face.load_glyph(i)
print (chr(65+index))
bitmap = face.glyph.bitmap
width = face.glyph.bitmap.width
rows = face.glyph.bitmap.rows
pitch = face.glyph.bitmap.pitch
print (face.glyph.bitmap_left)
print (face.glyph.bitmap_top)
dump_bytes (bitmap.buffer, pitch,rows)
print ()https://stackoverflow.com/questions/60195738
复制相似问题