なつねこメモ

主にプログラミング関連のメモ帳 ♪(✿╹ヮ╹)ノ 書いてあるコードは自己責任でご自由にどうぞ。記事本文の無断転載は禁止です。

続:Cloudflare Workers でも画像のメタデータを取得したい:PNG の iTXt 編

前回の記事では、Cloudflare Workers で EXIF/XMP データを取得する方法について解説しました。

tech.natsuneko.blog

今回は PNG ファイルに焦点を当て、iTXt チャンクに埋め込まれたメタデータを取得する方法を紹介します。

まず、 PNG ファイルには任意のテキストデータを埋め込むための仕様として、iTXt チャンクが用意されています。 iTXt チャンクは UTF-8 文字列を記録できるため、写真のメタデータを埋め込むのに非常に便利です。 PNG ファイルのチャンク構造について詳しく知りたい方は、こちらの記事が参考になります:

qiita.com

ということで早速やっていきましょう。 まず、画像を解析するパッケージとして今回は png-chunks-extract パッケージを使います。 最終更新が10年前と迫力がある感じになっていますが、まぁ仕様に対する実装ということで大きな変化がある分野でもないので、大丈夫でしょう。

ということで早速インストールします。

$ pnpm install png-chunks-extract
$ pnpm install @types/png-chunks-extract --save-dev

実装は非常にシンプルです:

import extract from "png-chunks-extract";

const buffer = /* 画像データ */;
const chunks = extract(buffer);

// iTXt をフィルタリング
const textChunks = chunks.filter(chunk => chunk.name === "iTXt");

// 必要なデータがあるかどうかを舐める
for (const chunk of textChunks) {
  console.log(chunk.data); // Uint8Array
}

簡単ですね。実際のコードとしては、次のように利用しています。 データが Uint8Array で降ってくるため、 TextDecoder を使う必要があるのがポイントですね。

const extractPngMetadata= async (url: string) => {
  const blob = await fetch(url).then(w => w.blob());

  if (blob) {
    const buffer= Buffer.from(await blob.arrayBuffer());
    const chunks = extract(buffer);
    const itxtChunk = chunks.find((chunk) => chunk.name === "iTXt");

    if (itxtChunk) {
      const metadata = new TextDecoder().decode(itxtChunk.data);
      // パース処理
    }
  }
};

ということで Cloudflare Workers で PNG ファイルの iTXt チャンクからメタデータを取得する方法を紹介しました。png-chunks-extract パッケージを使用することで、簡単に実装できることがわかりました。 Cloudflare Workers での開発において最も重要なのは、エッジ環境でも動作するパッケージを見つけることです。今回紹介した png-chunks-extract パッケージは軽量で、エッジ環境でも問題なく動作することを確認しています。