あすたぴ.dev

cloud functions上でImagemagick を使う際のこと

GCP
Firebase
cloudfunctions
Imagemagick
2019/08/31 05:07:30

cloud functions ではインスタンス内にImageMagickがデフォルトでインストールされています。
その為画像の加工等が行うことができます。

https://cloud.google.com/functions/docs/tutorials/imagemagick?hl=ja
上記は、公式のチュートリアルです。

実際に開発するときはチュートリアルのようにいきなりデプロイして試してみる。というのはTry&Errorがやりにくく現実的ではありません。
一般的に手元で cloud functions を debug する際は firebase-tools のエミュレーターを使うことが多いと思います。
しかし、firebase-tools 上でチュートリアルのような Imagemagick のコマンドを使うとうまく動きません。
エミュレーターが標準出力をフックしていることが原因だと思いますが詳細はわかりませんが、とりあえず動きません。

その為、実際の開発時はエミュレーターを使わず、node のスクリプトを生で使用して チュートリアルのようなコードを試し、うまく動作することがわかったら実際にデプロイして試してみる。というやり方がいいでしょう。

インスタンスのストレージを利用する。

cloud functions では、インスタンス上にファイルを保存したりすることができます。
且つ、同一インスタンスで実行される処理ではストレージが共有されます。
画像加工の際に一時的にファイルを出力したい。とか、フォントファイルを読み込ませたい。とかあると思います。

tmp を使う

tmp ライブラリを使うことで、処理ごとにユニークなworkディレクトリを用意することができます。

const tmp = require('tmp')
const tmpObj = tmp.dirSync();
const fileName = 'hoge.png';
const originalFilePath = `${tmpObj.name}/${fileName}`;
const thumbnailFilePath = `${tmpObj.name}/t_${fileName}`;

~~ 処理 ~~~

tmpObj.removeCallback();

上記のようなコードを書くことで一時的なディレクトリの作成と、そこへのファイルの配置。最終的に一時ディレクトリの削除まで用意に行うことができます。

フォントファイルを共有する

const fontPath = `${os.tmpdir()}/xxxxx.ttf`;
if (!fs.existsSync(fontPath)) {
  const bucket = admin.storage().bucket();
  const font = bucket.file('path_to/fonts/xxxxx.ttf');
  await font.download({ destination: fontPath });
}

処理により同一インスタンス上で実行される場合はストレージを共有されるという話しをしましたが、

os.tmpdir() 配下に共有したいファイルを置くようにし、存在しなかった場合は cloud storage 等からDLしてくる。というコードを書くことで効率的に処理を行うことが出来ます。

以上です。また何か思い出したら書きます。

Copyright © astapi