URLから画像のサイズを取得する(Node.js)

サーバーサイドアプリケーションを書いていると、「あるURLでアクセスできる画像の(縦横の)サイズを知りたい」という場面がまれにあると思います。Nodejsにおいて、そういった場合にどうしたらよいかを紹介します。

準備

image-size を利用します。また、ここでは axios を用いますが、node-fetch など他のライブラリでも同様にできると思います。標準ライブラリの https.requesthttp.request を用いることもできますが、いろいろとめんどくさいと思います(そもそもhttpかhttpsかで使うライブラリを分けなくてはいけない?)。

ちなみに執筆時点でのバージョンは axios@0.18.0, image-size@0.7.3 です。

$ npm i image-size axios

実装

以下のような関数を用意します。axios.get のオプションにおいて responseType: 'arraybuffer' と指定してあげないと、 res.data が文字列になったりしてうまくいきません(ContentTypeなどをもとにうまくやってほしいとも思ってしまいますが...)。

この関数に画像のURLを投げれば、width プロパティ(number)と height プロパティ(number)をもったオブジェクト(のプロミス)を返してくれます。大体のメジャーなフォーマットに対応してくれています。

const imageSize = require('image-size');
const axios = require('axios');

function fetchSize(imgUrl) {
  return axios.get(imgUrl, {
    responseType: 'arraybuffer',
  })
    .then(res => imageSize(res.data))
    .then(i => ({
      width: i.width,
      height: i.height,
    }));
}

TypeScriptの場合

簡単ですが、TypeScriptだと以下のようになります。

import imageSize from 'image-size';
import axios from 'axios';

function fetchSize(imgUrl: string): Promise<{ height: number; width: number; }> {
  return axios.get(imgUrl, {
    responseType: 'arraybuffer',
  })
    .then(res => imageSize(res.data))
    .then(i => ({
      width: i.width,
      height: i.height,
    }));
}