📷

CIで画像素材を検証する

2022/12/05に公開

この記事はLuup Advent Calendarの5日目の記事です。

LUUPサーバーチームのt-kurimuraです。
この記事ではLUUPのサーバーのレポジトリのひとつで実装されている画像に対するバリデーションをご紹介します。

背景

LUUPではキャンペーンなどユーザーへお知らせする際にバナーなどで画像素材を利用します。 これら画像はサーバー上にアップロードされアプリ側へURLを渡す形で表示されます。

この画像の容量が大きいと表示に時間がかかったり、縦横比が指定どおりでないと表示崩れを起こしたりして、デザイン時の意図した表示なりません。ただそれらのルールがデザイナーとエンジニアの間でマニュアル化されていても新規参画者が気づかないこともあったり、そもそも”注意する”ことはなるべく減らしたいものです。

入稿する際アプリケーションで検証されるに越したことはありませんが、画像素材は当該バナーのコードと一緒にGit配下で管理していたためCIで検証することにしました。

要件

以下の2つをディレクトリー毎に定義した値で入稿されているか検証します。

  • 画像の縦と横のPixel数が定義した値である
  • 画像の容量が一定以下である

ImageMagick

ImageMagickは、画像の作成・編集・変換などを行えるApache 2.0ライセンスで配布されているフリーソフトウェアです。

Linux, Windows, macOS, iOS, Android OSで動作します。

画像の合成やフォーマット変更など多様な機能がコマンドラインから実行できます。

サーバーチームのレポジトリのCIはGitHub Actionsで実装されているため、ImageMagickをGitHub Actions用に実装しているImageMagick-actionを利用しました。

実装

name: image size cheker
on:
  pull_request:
    paths:
      - 'public/images/hoge/**'
    types:
      - opened
      - reopened
      - synchronize

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: jruipinto/ImageMagick-action@v1
        with:
          command: sh ./.github/scripts/validate_image.sh

GitHub ActionsのWorkflowは極めてシンプルでImageMagick-actionをインストールした上でshellスクリプトを呼び出します。
画像が配置されたディレクトリー以外の変更では検証する必要がないので、on句で実行ディレクトリーの条件を加えます。

image_stats_validator () {
  dir_name=$1
  aspect_ratio=$2 # eg. "100x200" <= width is 100px, height is 200px
  size_limit_kb=$3 #eg 100 <- 100KB

  ls "./public/images/hoge/${dir_name}"
  for file in `find "./public/images/hoge/${dir_name}" -type f`; do
      if [[ $file =~ /\.gitkeep$ ]]; then
        continue
      fi

      # Aspect ratioのばらつきによる表示ブレを防ぐ
      format_limit_PNG="size=${aspect_ratio},format=PNG"
      format_limit_JPEG="size=${aspect_ratio},format=JPEG"
      format="$(magick identify -format 'size=%wx%h,format=%m' $file)"
      if [[ $format != "${format_limit_PNG}" && $format != "${format_limit_JPEG}" ]]; then
        echo -e "${dir_name} should be [$format_limit]\n💔 ${file} is [$format]"
        exit 1
      fi

      # アプリ上に表示する際に遅くなることを防ぐため
      size="$(magick identify -format "%[fx:int(extent/(1024))]" $file)"
      if [[ $size -gt ${size_limit_kb} ]]; then
        echo -e "${dir_name} should be smaller than [${size_limit_kb}KB]\n💔 $file is [${size}KB]"
        exit 1
      fi
  done

  echo "${dir_name} all ok"
}

set -e
image_stats_validator winter_campaign_small_banner 900x350 150

image_stats_validatorの関数で特定のディレクトリー内の画像の大きさと容量検証しています。
この例では以下のルールで画像が設定されていないとCIが失敗します。

  • winter_campaign_small_bannerは、
    • 900px x 350pxの画像
    • 各画像が150KB以下

ディレクトリー毎にまとめることによって、複数のルールを管理しやすくなります。

終わりに

この実装ではバナー画像特有の角丸の検証することなど、より詳細な検証を想定していたためImageMagickで実装していますが、サンプルのように容量とサイズの検証だけであればlsとidentifyコマンドだけでこと足りるはずです。 また、ImageMagickには脆弱性の問題も報告されてきているため注視が必要と考えています。 画像やり取りのルールの徹底のためのアイデアとしてCIで検証することを参考にしていただければ幸いです。

Luup Developers Blog

Discussion