· 技術 · NOTE_07

スタメンの画像を、スマホの中で描くマイイレブンとペタスタの画像づくり

マイイレブンとペタスタで「画像を保存」を押すと、縦長のスタメンの画像が端末に保存されます。この画像は、どこかのサーバーで作って送り返しているのではありません。いま手に持っているスマホのブラウザが、その場で1枚ずつ描いています。このノートでは、その手順と、そこで工夫したことを紹介します。

なぜサーバーで作らないのか

画像をサーバーで作る方法もあります。選んだ内容をサーバーに送り、サーバーが画像を作って返す形です。どの端末でも同じ仕上がりになりやすいという良さがあります。

それでもブラウザの中で描くことにしたのは、理由が2つあるからです。

ただし、ブラウザの中で描くには、サーバーなら気にしなくてよい問題をいくつも解く必要がありました。順に見ていきます。

描く場所は「canvas」

ブラウザには、プログラムから絵を描ける画用紙のような機能があります。canvas(キャンバス)と呼ばれるものです。線や四角、文字、決まった形を、位置と色を指定して1つずつ置いていくと、最後にそれを1枚の画像として取り出せます。

マイイレブンとペタスタでは、この画用紙の大きさを、横 1080・縦 1350 ピクセルに決めています。縦と横の比が 4:5 の縦長で、X や Instagram に載せたときに、切れずに大きく表示されやすい形です。画面に見えている見本は、この大きな画用紙を縮めて表示したものなので、保存した画像は画面で見るよりきめ細かく仕上がります。

描くものは、おおまかに次のとおりです。

  1. 背景と見出し選んだクラブの色をもとに背景を塗り、見出し・対戦相手・日付などを入れます。
  2. ピッチと選手の位置ピッチの線を引き、フォーメーションの形に合わせて選手の位置を決めます。
  3. シャツと背番号全クラブ共通のシャツの形を、クラブの色に近い「メインの色」と「差し色」で塗り分け、背番号を入れます。
  4. 名前の札シャツの下に、選手の名前の札を重ねます。
  5. 下の帯「本サービスは非公式サービスです」の表記と、どのサービスで作ったかを入れます。

シャツは、実際のユニフォームの柄を写したものではありません。十数個の点を結んだ同じ形を、色だけ替えて塗っています。エンブレムやロゴ、写真は使っていません。絵の素材を1枚も持たず、形と色の指定だけで描けることも、この作りの良いところです。

日本語の書体を、使う分だけ読む

いちばん手間がかかったのが書体(フォント)です。canvas に文字を描くとき、その書体がまだ端末に届いていないと、ブラウザは手元にある別の書体で描いてしまいます。そうなると、見本では丸い文字だったのに、保存した画像はかたい文字になる、といったことが起こります。

しかも日本語の書体は大きなファイルです。漢字・ひらがな・カタカナを合わせると数千字あり、まるごと読むと時間がかかります。そこで、書体は文字の範囲ごとに小さなファイルに分けてサービスの中に置き、必要な分だけを読むようにしています。外の書体の配信サービスからは読み込みません。画像を作るたびに外へ通信が起きないようにするためです。

では、「必要な分」はどう知るのでしょうか。ここでは「下描き」という手を使っています。

  1. 見えない画用紙に一度描く画面に出さない別の画用紙に、本番と同じ手順で画像を描きます。このとき、どの書体で、どの文字を使ったかを書き留めます。
  2. 使った文字の入ったファイルだけ読む書き留めた文字を含む書体のファイルだけを読み込み、すべて届くのを待ちます。
  3. 本番の画用紙に描く書体がそろってから、もう一度、本番の画用紙に描きます。

同じ絵を2回描くので遠回りに見えますが、図形を描くのは一瞬です。時間がかかるのは書体を読む部分なので、そこを最小にするほうが効きます。読み込んだ書体は端末に残るので、2回目からはほとんど待ちません。いちばん初めに開いたときだけ、書体の読み込みに少し時間がかかります。

名簿にない選手を名前で打って入れる機能があるので、どんな名前が来ても欠けないよう、日本語の文字がそろった書体を選んでいます。マイイレブンはすっきりしたゴシック体、ペタスタは丸みのある書体です。どちらも自由に使える許可(オープンなライセンス)で配られているもので、その全文もサービスの中に置いています。

長い名前を、札に収める

サッカーの選手の名前は、短いものから、カタカナで十数文字になるものまでさまざまです。名前の札の大きさを固定すると、短い名前はすかすかに、長い名前ははみ出してしまいます。そこで札は、名前に合わせて次の順に調整します。

ペタスタでは、2行にすると下の列の選手にかかりやすいので、2行にする前に札の左右の余白を詰める段階をはさんでいます。同じ考え方でも、見た目に合わせて順番を変えています。

描く順番も大事です。シャツを先にすべて描き、名前の札はそのあとにまとめて重ねます。選手ごとに「シャツ→名前」と描くと、後から描いた選手のシャツが、前の選手の名前に重なって隠れることがあるためです。

盤面と画像で、同じ形に並べる

フォーメーションは38種類から選べ、それぞれの形は選手の位置の座標(左右と前後の数字)で持っています。この座標を、画面で選手を選ぶ盤面と、保存する画像の両方で使います。

画像では、縦長の画用紙を広く使うために、選手の並びを縦に少し伸ばしています。ゴールキーパー以外の選手を、いちばん後ろの選手を基準に、いちばん前の選手がピッチの上の端に来るまで同じ割合で伸ばします。全員を同じ割合で伸ばすので、形そのものは崩れません。

以前は、縦に近い2人の間だけを広げる作りにしていました。すると選手が別の列に動いたように見え、盤面と画像で形が違ってしまいました。いまは並べ方を1か所にまとめ、盤面と画像がかならず同じ計算で並ぶようにしています。38種類すべての形で、元の形と同じ割合のままかを自動のテストで確かめています。

非公式の表記は、描き忘れても入る

マイイレブンとペタスタは、サッカーを楽しむ人のための非公式のサービスです。保存した画像がSNSで広がっても、どこかの団体が出したものと間違われないよう、すべての画像の下に「本サービスは非公式サービスです」と、作ったサービスの住所を入れています。この表記は、使う人が消せない形で描いています。

見た目は画像の種類ごとに違いますが、描く道具の側で「表記を入れたか」を覚えています。もし、ある画像の描き方でうっかり表記を入れ忘れても、最後に道具の側が気づいて、左下に白い帯つきで自動で書き足します。新しい画像の種類を足すときの、描き忘れの防止です。

「保存」ボタンの裏側

描き終えた画用紙は、PNG という形式の画像ファイルにして端末に渡します。ここにもスマホならではの事情があります。

共有リンクを開いた人の画面でも、その場で描く

「リンクをコピー」で作る共有リンクには、画像そのものではなく、どのクラブ・どの形・どの選手を選んだかという中身を、短い文字にして入れています。リンクを開くとその住所はサーバーに届きますが、中身を集計したり保存したりはしません。受け取った人のスマホが中身を読み取り、ここまでと同じ手順で、その場で画像を描き直します。

画像をサーバーに置かないので、リンクを送ったあとに画像が消える心配も、運営側が画像をためこむこともありません。受け取った人は、そのまま内容を直して自分の案として送り返すこともできます。

この作りの弱点と、外側にあるもの

端末の中で描く作りには、弱点もあります。描く速さや書体の届く速さは端末と通信の状態に左右され、古いスマホや電波の弱い場所では、初回に少し待つことがあります。また、ブラウザの種類によって文字の幅がわずかに違い、名前の札の大きさが端末ごとに少し変わることがあります。どの端末でもはみ出さないよう、札には余裕を持たせています。

なお、画像を描く仕組みの外側には、ページを表示するためのファイルの取得と、Cookie を使わないアクセス解析の通信があります。サービスに広告を入れるときも、画像とは別の通信になります。これらに作った画像が含まれることはありませんが、「通信がまったくない」わけではないことは正直に書いておきます。くわしくは各サービスのプライバシーポリシーをご覧ください。

マイイレブンとペタスタは、同じ名簿と同じ描く道具を使い、見た目だけを別にしています。それぞれの使い方は「マイイレブン」「ペタスタ」の紹介ページにまとめています。