九保すこひです(フリーランスのITコンサルタント、エンジニア)
さてさて、どの分野でもAIの影響が大きくなっている昨今ですが、じゃあ知識が不要かといえば全く別で、個人的には「成果 = 知識 ✕ AIの能力」だと考えています。
そんな影響で、エンジニアであってもデザインの勉強をしているんですが、その中で1つ感じることがありました。
イラストレーターの「合成フォント」めちゃ便利!
合成フォントというのは「複数フォントを1つのフォントとして混ぜてつかえる」機能のことで、たとえば、1つのフォントなのに、
- かな:漢字:中ゴシックBBB
- 漢字:築地体五号仮名
- 半角欧文:Helvetica
- 半角数字:DIN
といった具合に文字ごとにフォントを振り分けることができるスグレモノです。

Adobe Blogより引用
しかし(オンライン講座を購入してた時は)Illustratorを使っていましたが、
なにせ、サブスクが高い😫
んです…。
もちろんプロのデザイナーなら必須ですが、プログラム主体で活動してる私からすると、ブログのアイキャッチ画像で月4,5回つかうだけなので、さすがに「うーん…」って印象でした。
結果として、IllustratorとPhotoshopは解約し、長年使い続けてきたフリーソフトGIMPをつかっています。
でも、合成フォントがほしい…。
(だって、一箇所ずつフォントを編集するのダルいから😫)
ということで、代替案を考えました!
それが今回の・・・・・・
2つのフォントを合体させて、合成フォント化する
という作戦です。
つまり、今回は以下のような人に向けて記事を書いています。
- 「Illustratorのサブスク料金が高いと感じている人」
- 「Adobe CCを解約したけど、一部機能だけ使いたい人」
- 「月数回のデザイン作業のために数千円払うのは抵抗がある人」
- 「フリーランスで経費を抑えたい人」
- 「無料ツールで何とかしたいと思っている人」
- 「エンジニアだけどデザインもやらざるを得ない人」
- 「個人ブログのアイキャッチ画像を自作している人」
- 「YouTubeのサムネイルを自分で作っている人」
- 「GIMPユーザー全般!」
ぜひ最後まで読んでくださいね!

「明日は楽しい忘年会🎉✨
大将の寿司をガッツリいきます!」
今回の作戦
2つのフォントを以下のように合成し、全く新しいフォントを作成するわけです。
たとえば、
- 英数字:Oswald(ユニクロのロゴになってるDINに似た書体)
- それ以外:RocknRoll One(ポップな印象があるフォント)
を合体させて、Os_Rocknみたいな新しいフォントをつくり、OSにインストールすれば画像編集ソフトでも使えるようになるというわけですね!
↓↓↓これが、1つのフォントを選ぶだけでできるようになります。

fonttoolsをインストールする
実はPythonにはfonttoolsというパッケージがあり、pipでインストールできます。
では、以下コマンドでfonttoolsをインストールしておきましょう。
pip3 install fonttools
これだけで準備は完了です!
フォントを合成するPythonスクリプトをつくる
fonttoolsを使って、以下の部分を合体させる作業をしています。
- 英数字:1つ目のフォント
- それ以外:2つ目のフォント
コードはこちら。
combine_fonts.py
import sys
import json
from fontTools.ttLib import TTFont
from pathlib import Path
from typing import Tuple
ALPHANUMERIC_RANGE = range(0x20, 0x7F)
FONT_NAME_IDS = {
'family': 1,
'full': 4,
'postscript': 6,
'typographic_family': 16
}
def parse_arguments() -> Tuple[Path, Path, Path, str]:
if len(sys.argv) != 4:
exit_with_error(
"Invalid number of arguments. "
"Usage: python3 merge_fonts.py <latin_font> <japanese_font> <output_file> <custom_name>"
)
latin_path = Path(sys.argv[1])
jp_path = Path(sys.argv[2])
output_path = Path(sys.argv[3])
custom_name = output_path.stem
if not latin_path.exists():
exit_with_error(f"Latin font file not found: {latin_path}")
if not jp_path.exists():
exit_with_error(f"Japanese font file not found: {jp_path}")
return latin_path, jp_path, output_path, custom_name
def load_fonts(latin_path: Path, jp_path: Path) -> Tuple[TTFont, TTFont]:
try:
latin_font = TTFont(str(latin_path))
jp_font = TTFont(str(jp_path))
return latin_font, jp_font
except Exception as e:
exit_with_error(f"Failed to load font files: {e}")
def merge_glyphs(latin_font: TTFont, jp_font: TTFont) -> int:
latin_cmap = latin_font.getBestCmap() or {}
alphanumeric_codes = set(ALPHANUMERIC_RANGE)
glyphs_copied = 0
for table in jp_font['cmap'].tables:
if not table.isUnicode():
continue
for code in list(table.cmap.keys()):
if code not in alphanumeric_codes or code not in latin_cmap:
continue
glyph_name = latin_cmap[code]
table.cmap[code] = glyph_name
if 'glyf' in latin_font and glyph_name in latin_font['glyf'].glyphs:
jp_font['glyf'][glyph_name] = latin_font['glyf'][glyph_name]
if glyph_name in latin_font['hmtx'].metrics:
jp_font['hmtx'][glyph_name] = latin_font['hmtx'][glyph_name]
glyphs_copied += 1
return glyphs_copied
def update_font_metadata(font: TTFont, custom_name: str) -> None:
for record in font['name'].names:
if record.nameID in FONT_NAME_IDS.values():
record.string = custom_name
def save_font(font: TTFont, output_path: Path, custom_name: str, glyphs_copied: int) -> None:
try:
font.save(str(output_path))
print(f"\n✓ Success!")
print(f" Output file: {output_path}")
print(f" Font name: {custom_name}")
print(f" Glyphs copied: {glyphs_copied}")
except Exception as e:
exit_with_error(f"Failed to save output file: {e}")
def main() -> None:
latin_path, jp_path, output_path, custom_name = parse_arguments()
latin_font, jp_font = load_fonts(latin_path, jp_path)
glyphs_copied = merge_glyphs(latin_font, jp_font)
update_font_metadata(jp_font, custom_name)
save_font(jp_font, output_path, custom_name, glyphs_copied)
if __name__ == "__main__":
main()
使い方はこうなります。
python3 combine_fonts.py (欧文フォント) (和文フォント) (出力先)
つまり、実際の例はこちらです。
python3 combine_fonts.py Oswald-VariableFont_wght.ttf RocknRollOne-Regular.ttf X_Os_Rockn.ttf
ちなみに:ライセンスに注意!
フォントと言ってもライセンスが様々なので、合成フォント化する前に必ずチェックをしてください。
例えば、以下のような禁止パターンがあります。
- 改変自体がダメ
- 合成フォントで画像をつくる(公開)がダメ
- 合成フォント本体の配布がダメ
ちなみにGoogleフォントで配布されているものの多くはOFLライセンスとなっていて、自由度が高く合成フォントとして使い勝手がいいです。
テストしてみる
では、実際に合成フォントをつくってみましょう!
今回使うのは、以下の構成です。
- 英数字:Oswald
- それ以外:RocknRoll One
※ちなみに、このブログでは最近のアイキャッチ画像に上記2つのフォントを使っています👍
では、以下コマンドを実行します。
python3 combine_fonts.py Oswald-VariableFont_wght.ttf RocknRollOne-Regular.ttf X_Os_Rockn.ttf
ちなみに、先頭にXをつけてるのは、合成フォントだと一発でわかるからです。
うまくいくでしょうか・・・・・・

はい!
まずは成功の表示がでました。
では、フォルダを覗いてみましょう。

はい!
新しいフォント「X_Os_Rockn」ができています。
ちゃんと合成できてるか確認します。
まずは、元フォントの2つです。
Oswald

RocknRoll One

では、合成したフォントを確認します。

はい!
- 英数字+α:Oswald
- それ以外:RocknRoll One
の文字になっていますね。
まずは成功です😊
では、OSにインストールしてGIMPで使ってみましょう。
うまくいくでしょうか・・・・・・

はい!
1つなのに2つのフォントが入り混じった状態になっています。
すべて成功です😊✨
企業様へのご提案
もしIllustratorを使うほどでもないけど、作業の効率化が課題でしたら、今回のような合成フォントを使ってみてはいかがでしょうか。
また、私は長年フリーソフトGIMPを使い続けてきたので、お力になれることもあるかと思います。
そういった方は、ぜひお問い合わせからご相談ください。
お待ちしております😊✨
おわりに
ということで、今回は2つのフォントを合体した「合成フォント」をつくってみました!
Illustratorは高機能でいいけど「さすがにコスパにあわないよ…」という方はぜひ試してみてはいかがでしょうか。
よく使う合成フォントをいくつか用意しておけば、作業が格段に楽になると思います。
※ちなみに組み合わせるときのヒントは「世界観が同じフォント」をペアにするってことです。
実際に今回のアイキャッチ画像は、合成フォントをつかっています。
なかなかいい感じでした!
ちなみに、実は当初はtauriをつかってデスクトップアプリにしようとしてたんです。
2つのフォントをドラッグ・アンド・ドロップで選択してボタンをポチーで合成完了!てめちゃくちゃ便利じゃないですか?
でも、やめたんです。
PythonをRustから実行する形にすると、バイナリ化しないといけないとか、windowsの場合はこうで・・・みたいに複雑だからです。
なので、せめて画像だけ供養のために公開させてください(笑)

AIに聞いたら「できる!」ばかり言うから騙されました…。
開発を始める前は、AIだけじゃなくちゃんとエビデンスを確認してからやるべきですね。
1つ勉強になりました。
プロンプトの最後に「忖度なし、エビデンス重視で回答して」って入れるのも結構いい感じです。
ぜひ皆さんも(エビデンスを揃えつつ)何か面白そうなことをやってみてくださいね!
ではでは〜。

「イカ2貫て、商標権とかないよね?」





