3
2

More than 3 years have passed since last update.

Google Fontが拡充されたので、Cloudinaryに全フォントファイルをアップロードする

Last updated at Posted at 2021-09-18

はじめに

最近、Google Fontsにたくさんの日本語フォントが追加になりました。1
画像加工のクラウドサービスCloudinaryで新しい日本語を使えるようにするために、全ファイルをアップロードしました。

その時に使ったスクリプトを共有します

おさらい

Cloudnaryは画像を保存して配信するサービスです。画像を配信するときに、変形や文字入れの加工ができます。

詳しくはこちらへ

Cloudinaryは文字入れ(オーバーレイ変換)をするときにフォントを指定することができるのですが、サポートされている日本語フォントがいまいちです。はっきり言ってしょぼいです。

フォントの種類が足りない場合は、フォントファイルをアップロードすることができるようになっています。2
面倒なので、Google Fontsにある日本語フォントファイルを全部アップロードしてしまいます。

使ったもの

  • PHP (5.6)
  • Google Fonts API
  • Coudinary api + node SDK
"c:\Program Files\php-5.6.39-Win32-VC11-x64\php.exe" -v
PHP 5.6.39 (cli) (built: Dec  5 2018 21:24:55)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies

CloudinaryのPHP SDKがPHP5.6を使えと言っているため。いまさら5.6で実施3

やること

  1. google font apiで日本語のフォントを探す
  2. フォントファイル(.ttf/.otf)をダウンロードする
  3. Cloudinaryにアップロードする

Google Fonts APIは無料で使えます。GoogleアカウントでAPIのトークンをとっておく必要があるので、自分でとりましょう。

フォントファイルを持ってくる部分と、Cloudinaryにアップロードする部分を2つにわけました。

準備

composer.jsonを作ってSDKをインストール

composer.json
{
    "require": {
      "cloudinary/cloudinary_php": "^2"
    },
    "config": {
        "platform": {
            "php": "5.6.39" 
        }
    }
}

Cloudinaryのマニュアルにはrequireしか書いてないけど、PHPのバージョンを指定してインストール

コマンドライン
composer install

コード1 (google font api)

Google Fonts APIからデータを持ってくる部分。
このAPIはパラメータで絞り込みができないので、全フォントデータを持ってきてからデータをフィルタする実装です。

日本語対応かどうかは、subsetsの配列の中にjapaneseが入っているかで判断しています。
1つのフォントに複数のスタイルが設定されている場合、フォントファイルも複数になるのでfilesの配列から全部持ってきます。

フォントファイルの名前は以下のルールにします。この名前がそのままCloudinaryのpublic_idになり、URLで指定するフォント名となります。
font family-font style.拡張子(ttf or otf)

ただし、スタイル名がregularのときは、付けると長くなるので省略します。

get_google_font_api.php

<?php
$google_api_token = 'Your TOKEN';
$font_api_url = 'https://www.googleapis.com/webfonts/v1/webfonts?key=' . $google_api_token ;

$font_json = file_get_contents($font_api_url);
$font_list = json_decode($font_json, true);

foreach($font_list['items'] as $n=>$font){
    echo ($n+1).'/'.count($font_list['items']) . " " . $font['family'] . PHP_EOL;

    //日本語フォントだけ
    if( in_array('japanese', $font['subsets'] )){
        echo $font['family'] . PHP_EOL;
        echo count($font['files']) . PHP_EOL;
        $file_name_font_family = $font['family'];

        foreach($font['files'] as $style=>$url){
            echo " $style : $url" . PHP_EOL;

            //スタイルがregularではない時だけ、ファイル名に付ける
            $file_name_font_style = '';
            if($style !== 'regular'){
                $file_name_font_style = '_'.$style;
            }

            //ファイル名の拡張子は最後の.以降の文字
            $splitted_url = explode('.', $url);
            $file_name_ext = end($splitted_url);

            //ファイル名完成
            $file_name = "${file_name_font_family}${file_name_font_style}.${file_name_ext}";

            //ファイルをとってきて保存
            $font_data = file_get_contents($url);
            $bytes = file_put_contents('fonts/' . $file_name, $font_data);
        }
    }
}

これを実行すると、getGoogleFont.jsの下に/fontsフォルダが作られて、フォントファイルがダウンロードします。

2021/9/18時点だと、78ファイルをダウンロードできました。

コード2 (Cloudinary)

ローカルディスクにあるフォントファイルを順番にアップロードする部分。
Google Fontsに無いフォントでも、fontsフォルダ内におけばアップロードします。

upload_fonts_cloudinary.php

<?php
require_once "vendor/autoload.php";
use Cloudinary\Cloudinary;
$cloudinary = new Cloudinary('cloudinary://apikey:secret@cloudname');

foreach( glob('fonts/*') as $file){
    $file_name = pathinfo($file)['basename'];
    echo "uploading $file_name..." . PHP_EOL;

    $api_options = ['resource_type'=>'raw','type'=>'authenticated', 'public_id'=>$file_name];
    try{
        $result = $cloudinary->uploadApi()->upload($file, $api_options);
        echo "uploaded. public_id is " . $result['public_id'] . PHP_EOL;

    }catch(Exception $ex){
        echo "error" . PHP_EOL . $ex->getMessage() . PHP_EOL;
    }
}

フォントファイルのサイズが大きすぎてエラーになるものがあります。
Cloudinaryの仕様上、1ファイルの最大が10485760バイト(10メガバイト)なのであきらめましょう。

[2021-09-18 20:23:49] cloudinary.CRITICAL: Request to Cloudinary server returned an error {"statusCode":400,"message":"File size too large. Got 33153716. Maximum is 10485760."} []
[2021-09-18 20:23:49] cloudinary.CRITICAL: Async request failed {"code":0,"message":"File size too large. Got 33153716. Maximum is 10485760."} []
[2021-09-18 20:23:49] cloudinary.CRITICAL: Single Chunk Async POST request failed {"code":0,"message":"File size too large. Got 33153716. Maximum is 10485760."} []
error
File size too large. Got 33153716. Maximum is 10485760.

しっぽり明朝系は全滅でした。残念。

アップロードしたフォントを使ってみる

9回オーバーレイをするとこんな感じです。

URL

上のURL。実際は1行で書きます。

https://res.cloudinary.com/kanaxx
/g_north_west,co_rgb:FFF,l_text:M%20PLUS%20Rounded%201c.ttf_80:%E5%B7%A6%E4%B8%8A
/g_north,co_rgb:FFF,l_text:Dela%20Gothic%20One.ttf_80:%E4%B8%8A
/g_north_east,co_rgb:FFF,l_text:Hachi%20Maru%20Pop.ttf_80:%E5%8F%B3%E4%B8%8A
/g_west,co_rgb:FFF,l_text:Hina%20Mincho.ttf_50:%E3%81%B2%E3%81%A0%E3%82%8A
/g_center,co_rgb:FFF,l_text:Kaisei%20Decol.ttf_50:%E3%81%BE%E3%82%93%E3%81%AA%E3%81%8B
/g_east,co_rgb:FFF,l_text:Kaisei%20HarunoUmi.ttf_50:%E3%81%BF%E3%81%8E
/g_south_west,co_rgb:FFF,l_text:Kiwi%20Maru-500.ttf_30:%E3%83%92%E3%83%80%E3%83%AA%E3%82%B7%E3%82%BF
/g_south,co_rgb:FFF,l_text:Kosugi%20Maru.ttf_30:%E3%82%B7%E3%82%BF
/g_south_east,co_rgb:FFF,l_text:Potta%20One.ttf_30:%E3%83%9F%E3%82%AE%E3%82%B7%E3%82%BF
/600x500.png

デコードすると

https://res.cloudinary.com/kanaxx
/g_north_west,co_rgb:FFF,l_text:M PLUS Rounded 1c.ttf_80:左上
/g_north,co_rgb:FFF,l_text:Dela Gothic One.ttf_80:上
/g_north_east,co_rgb:FFF,l_text:Hachi Maru Pop.ttf_80:右上
/g_west,co_rgb:FFF,l_text:Hina Mincho.ttf_50:ひだり
/g_center,co_rgb:FFF,l_text:Kaisei Decol.ttf_50:まんなか
/g_east,co_rgb:FFF,l_text:Kaisei HarunoUmi.ttf_50:みぎ
/g_south_west,co_rgb:FFF,l_text:Kiwi Maru-500.ttf_30:ヒダリシタ
/g_south,co_rgb:FFF,l_text:Kosugi Maru.ttf_30:シタ
/g_south_east,co_rgb:FFF,l_text:Potta One.ttf_30:ミギシタ
/600x500.png

Cloudinary SDKを使うとエラーになるとき

このエラーが出るときは、たぶんPHPのバージョンが違います。

PHP Fatal error: Declaration of Cloudinary\Log\LoggerDecorator::emergency($message, array $context = []) must be compatible with Psr\Log\LoggerInterface::emergency(Stringable|string $message, array $context = []): void in C:\work\cloudinary-font\vendor\cloudinary\cloudinary_php\src\Log\LoggerDecorator.php on line 195

PHP8にCloudnarySDKをインストールして使ったらエラーになりました。
GithubのREADMEにv5.6って書いてあります。

image.png

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2