Я создаю изображения китайского печать script. У меня есть три истинных шрифта для этой задачи (Jin_Wen_Da_Zhuan_Ti.7z, Zhong_Guo_Long_Jin_Shi_Zhuan.7z, Zhong_Yan_Yuan_Jin_Wen.7z, только для целей тестирования). Ниже перечислены возможности Microsoft Word
китайского иероглифа "我" (I/me). Вот мой Python script:
import numpy as np
from PIL import Image, ImageFont, ImageDraw, ImageChops
import itertools
import os
def grey2binary(grey, white_value=1):
grey[np.where(grey <= 127)] = 0
grey[np.where(grey > 127)] = white_value
return grey
def create_testing_images(characters,
font_path,
save_to_folder,
sub_folder=None,
image_size=64):
font_size = image_size * 2
if sub_folder is None:
sub_folder = os.path.split(font_path)[-1]
sub_folder = os.path.splitext(sub_folder)[0]
sub_folder_full = os.path.join(save_to_folder, sub_folder)
if not os.path.exists(sub_folder_full):
os.mkdir(sub_folder_full)
font = ImageFont.truetype(font_path,font_size)
bg = Image.new('L',(font_size,font_size),'white')
for char in characters:
img = Image.new('L',(font_size,font_size),'white')
draw = ImageDraw.Draw(img)
draw.text((0,0), text=char, font=font)
diff = ImageChops.difference(img, bg)
bbox = diff.getbbox()
if bbox:
img = img.crop(bbox)
img = img.resize((image_size, image_size), resample=Image.BILINEAR)
img_array = np.array(img)
img_array = grey2binary(img_array, white_value=255)
edge_top = img_array[0, range(image_size)]
edge_left = img_array[range(image_size), 0]
edge_bottom = img_array[image_size - 1, range(image_size)]
edge_right = img_array[range(image_size), image_size - 1]
criterion = sum(itertools.chain(edge_top, edge_left,
edge_bottom, edge_right))
if criteria > 255 * image_size * 2:
img = Image.fromarray(np.uint8(img_array))
img.save(os.path.join(sub_folder_full, char) + '.gif')
где основной фрагмент
font = ImageFont.truetype(font_path,font_size)
img = Image.new('L',(font_size,font_size),'white')
draw = ImageDraw.Draw(img)
draw.text((0,0), text=char, font=font)
Например, если вы помещаете эти шрифты в папку ./fonts
и вызываете его с помощью
create_testing_images(['我'], 'fonts/金文大篆体.ttf', save_to_folder='test')
script создаст ./test/金文大篆体/我.gif
в вашей файловой системе.
Теперь проблема в том, что она хорошо работает с первым шрифтом 金文 大 篆体.ttf(в Jin_Wen_Da_Zhuan_Ti.7z), script не работает с двумя другими шрифтами, даже если они могут быть правильно отображены в Microsoft Word: для 中國 龍 金石 篆.ttf(в Zhong_Guo_Long_Jin_Shi_Zhuan.7z) он ничего не рисует, поэтому bbox
будет None
; для 中研院 金文.ttf(в Zhong_Yan_Yuan_Jin_Wen.7z) он нарисует черный кадр без символа на картинке.
и, таким образом, не проходит тест criterion
, целью которого является тестирование полноцветного вывода. Я использовал FontForge, чтобы проверить свойства шрифтов и обнаружил, что первый шрифт 金文 大 篆体.ttf(в Jin_Wen_Da_Zhuan_Ti.7z) использует UnicodeBmp
в то время как другие два используют Big5hkscs
который не является схемой кодирования моей системы. Это может быть причиной того, что имена шрифтов неузнаваемы в моей системе:
Собственно, я также пытаюсь решить эту проблему, пытаясь получить шрифт с грязным именем шрифта. Я попробовал pycairo
после установки этих шрифтов:
import cairo
# adapted from
# http://heuristically.wordpress.com/2011/01/31/pycairo-hello-world/
# setup a place to draw
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 100, 100)
ctx = cairo.Context (surface)
# paint background
ctx.set_source_rgb(1, 1, 1)
ctx.rectangle(0, 0, 100, 100)
ctx.fill()
# draw text
ctx.select_font_face('金文大篆体')
ctx.set_font_size(80)
ctx.move_to(12,80)
ctx.set_source_rgb(0, 0, 0)
ctx.show_text('我')
# finish up
ctx.stroke() # commit to surface
surface.write_to_png('我.gif')
Это снова хорошо работает с 金文 大 篆体.ttf(в Jin_Wen_Da_Zhuan_Ti.7z):
но все же не с другими. Например: ни ctx.select_font_face('中國龍金石篆')
(который сообщает _cairo_win32_scaled_font_ucs4_to_index:GetGlyphIndicesW
), ни ctx.select_font_face('¤¤°êÀsª÷¥Û½f')
(который рисует шрифтом по умолчанию) работает. (Последнее имя - это беспорядочный код, отображаемый в средстве просмотра шрифтов, как показано выше, полученном линией кода Mathematica ToCharacterCode["中國龍金石篆", "CP950"] // FromCharacterCode
, где CP950
является кодовой страницей Big5.)
Поэтому я думаю, что я изо всех сил пытался решить эту проблему, но все равно не могу ее решить. Я также придумал другие способы, как переименование имени шрифта с помощью FontForge или изменение системного кодирования на Big5, но я бы предпочел решение, которое включает только Python и, следовательно, для пользователя требуется меньше дополнительных действий. Любые подсказки будут высоко оценены. Спасибо.
Модераторам stackoverflow: эта проблема может показаться "слишком локализованной" с первого взгляда, но это может произойти в других языках/других кодировках/других шрифтах, и решение может быть обобщено на в других случаях, поэтому, пожалуйста, не закрывайте его по этой причине. Спасибо.
ОБНОВЛЕНИЕ: странно Mathematica может распознавать имя шрифта в CP936 (GBK, которое можно рассматривать как мое системное кодирование). Возьмите 中國 龍 金石 篆.ttf(в Zhong_Guo_Long_Jin_Shi_Zhuan.7z) для примера:
Но установка ctx.select_font_face('ÖÐøý½ðʯ*')
тоже не работает, что создаст образ символа со шрифтом по умолчанию.