在 Python 中测试一个字形是否是同一字体中另一个字形的反映
Testing in Python whether one glyph is a reflection of another in the same font
受到 List of all unicode's open/close brackets? 的启发,我试图找到给定字体中所有 unicode 字形的列表,这些字形相互映射。首先,我只需要能够测试一个字形是否是另一个字形的反映。下面我有两种不同的尝试(我的 render_char
函数的两种不同实现)但是我无法使用任何一种将“(”和“)”识别为镜像。我该怎么做?
from PIL import Image,ImageDraw,ImageFont
import freetype
import numpy as np
def render_char0(c):
# Based on https://github.com/rougier/freetype-py/blob/master/examples/hello-world.py
# Needs numpy (blech) and the image comes out the inverse of the way I expect
face = freetype.Face("/Library/Fonts/Verdana.ttf")
face.set_char_size( 48*64 )
face.load_char(c)
bitmap = face.glyph.bitmap
w,h = bitmap.width, bitmap.rows
Z = np.array(bitmap.buffer, dtype=np.ubyte).reshape(h,w)
return Image.fromarray(Z, mode='L').convert('1')
def render_char1(c):
# Based on
verdana_font = ImageFont.truetype("/Library/Fonts/Verdana.ttf", 20, encoding="unic")
text_width, text_height = verdana_font.getsize(c)
canvas = Image.new('RGB', (text_width+10, text_height+10), (255, 255, 255))
draw = ImageDraw.Draw(canvas)
draw.text((5,5), c, font = verdana_font, fill = "#000000")
return canvas
for render_char in [render_char0, render_char1]:
lparen = render_char('(')
rparen = render_char(')')
mirror = lparen.transpose(Image.FLIP_LEFT_RIGHT)
mirror.show()
rparen.show()
print mirror.tobytes() == rparen.tobytes() # False
在 Unicode 纯文本数据库中有一个名为 BidiMirroring.txt
的文本文件,其中包含所有镜像字符的列表。该文件很容易被程序解析。
当前 url 是 http://www.unicode.org/Public/UNIDATA/BidiMirroring.txt
我不认为使用呈现的字形可以可靠地工作。例如,有很多原因。 (
和 )
不是精确的镜像,例如字符周围的间距、提示和抗锯齿,可能字体略微倾斜,或者字体设计者只是让两个括号有点不同etc. 其他字符是旋转的,而不是镜像的,例如某些字体中的 “
和 ”
,以及中文引号 「
和 」
.
我认为渲染是错误的方法。这取决于字体以及字体是否知道如何呈现它。我听说 unicode 字符有这种对称性的规范。也许它是用他们的名字编码的。 "LEFT" 和 "RIGHT" "SUBSCRIPT"。看看 http://xahlee.info/comp/unicode_matching_brackets.html
受到 List of all unicode's open/close brackets? 的启发,我试图找到给定字体中所有 unicode 字形的列表,这些字形相互映射。首先,我只需要能够测试一个字形是否是另一个字形的反映。下面我有两种不同的尝试(我的 render_char
函数的两种不同实现)但是我无法使用任何一种将“(”和“)”识别为镜像。我该怎么做?
from PIL import Image,ImageDraw,ImageFont
import freetype
import numpy as np
def render_char0(c):
# Based on https://github.com/rougier/freetype-py/blob/master/examples/hello-world.py
# Needs numpy (blech) and the image comes out the inverse of the way I expect
face = freetype.Face("/Library/Fonts/Verdana.ttf")
face.set_char_size( 48*64 )
face.load_char(c)
bitmap = face.glyph.bitmap
w,h = bitmap.width, bitmap.rows
Z = np.array(bitmap.buffer, dtype=np.ubyte).reshape(h,w)
return Image.fromarray(Z, mode='L').convert('1')
def render_char1(c):
# Based on
verdana_font = ImageFont.truetype("/Library/Fonts/Verdana.ttf", 20, encoding="unic")
text_width, text_height = verdana_font.getsize(c)
canvas = Image.new('RGB', (text_width+10, text_height+10), (255, 255, 255))
draw = ImageDraw.Draw(canvas)
draw.text((5,5), c, font = verdana_font, fill = "#000000")
return canvas
for render_char in [render_char0, render_char1]:
lparen = render_char('(')
rparen = render_char(')')
mirror = lparen.transpose(Image.FLIP_LEFT_RIGHT)
mirror.show()
rparen.show()
print mirror.tobytes() == rparen.tobytes() # False
在 Unicode 纯文本数据库中有一个名为 BidiMirroring.txt
的文本文件,其中包含所有镜像字符的列表。该文件很容易被程序解析。
当前 url 是 http://www.unicode.org/Public/UNIDATA/BidiMirroring.txt
我不认为使用呈现的字形可以可靠地工作。例如,有很多原因。 (
和 )
不是精确的镜像,例如字符周围的间距、提示和抗锯齿,可能字体略微倾斜,或者字体设计者只是让两个括号有点不同etc. 其他字符是旋转的,而不是镜像的,例如某些字体中的 “
和 ”
,以及中文引号 「
和 」
.
我认为渲染是错误的方法。这取决于字体以及字体是否知道如何呈现它。我听说 unicode 字符有这种对称性的规范。也许它是用他们的名字编码的。 "LEFT" 和 "RIGHT" "SUBSCRIPT"。看看 http://xahlee.info/comp/unicode_matching_brackets.html