印鑑の画像を作成しています。このタスク用に 3 つの True Type フォントがあります ( Jin_Wen_Da_Zhuan_Ti.7z、Zhong_Guo_Long_Jin_Shi_Zhuan.7z、Zhong_Yan_Yuan_Jin_Wen.7z、テスト目的のみ)。以下は、Microsoft Word での外観です。
漢字の「我」のこと。ここに私のPythonスクリプトがあります:
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')
スクリプトは./test/金文大篆体/我.gif
ファイル システムに作成されます。
ここでの問題は、最初のフォントである金文大篆体.ttf (Jin_Wen_Da_Zhuan_Ti.7z 内) では問題なく動作しますが、Microsoft Word で正しくレンダリングできる場合でも、スクリプトが他の 2 つのフォントでは動作しないことです。金石篆.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 を使用していることがわかりました。
他の2つは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')
(デフォルトのフォントで描画する) も機能しません。(後者の名前は、上記のようにフォント ビューアに表示される乱雑なコードであり、Big5 のコード ページである Mathematica コードの行によって取得されます。ToCharacterCode["中國龍金石篆", "CP950"] // FromCharacterCode
)CP950
そのため、この問題に取り組むために最善を尽くしたと思いますが、それでも解決できません。FontForge を使用してフォント名を変更したり、システム エンコーディングを Big5 に変更したりするなど、他の方法も考えましたが、Python のみを使用するため、ユーザーの追加操作が少なくて済むソリューションを希望します。どんなヒントでも大歓迎です。ありがとうございました。
stackoverflow のモデレーターへ: この問題は一見「局所的すぎる」ように見えるかもしれませんが、他の言語/他のエンコーディング/他のフォントで発生する可能性があり、解決策は他のケースに一般化できるため、閉じないでください。この理由で。ありがとうございました。
更新: 奇妙なことに、Mathematica は CP936 (GBK、私のシステム エンコーディングと考えることができます) のフォント名を認識できます。例として、中國龍金石篆.ttf (Zhong_Guo_Long_Jin_Shi_Zhuan.7z 内) を取り上げます。
ただしctx.select_font_face('ÖÐøý½ðʯ*')
、デフォルトのフォントで文字イメージを作成する設定も機能しません。