HYUDORO

勉強したことや日記など

JavaScriptで画像と動画を描画せずにプロパティの値を取得する

ブラウザ描画せずに、画像または動画のサイズなどのデータを取得したいときのTipsです。

まずは画像と動画をロードして返す関数をつくります。引数にファイルのパスを文字列として渡します。

ポイントはPromiseを使ってメディアファイルを取得する時にundefinedになってしまうのを防ぐこと。 画像の場合はImageオブジェクトを作成して、DOMを作成せずにロードします。

loadImageFromPath(src) {
  return new Promise((resolve, reject) => {
    const img = new Image()
    img.onload = () => resolve(img)
    img.onerror = (e) => reject(e)
    img.src = src
  })
}

動画の場合はこちら。 動画はvideoエレメントを作る必要があります。

loadVideoFromPath(src) {
  return new Promise((resolve, reject) => {
    const video = document.createElement('video')
    video.onloadedmetadata = () => resolve(video)
    video.onerror = (e) => reject(e)
    video.src = src
    video.load()
  })
}

上記の関数をasync/awaitで扱う例です。Promise.then()でもいいです。

画像と動画で実行する関数と参照するプロパティは異なりますが、ほぼ一緒です。

今回は幅と高さをオブジェクトとして返す関数を作ってます。こちらも引数はファイルのパス。ファイルがなかったりエラーが生じた時のためにハンドリングしてます。

async getMediaSize(src) {
  let size = { width: 0, height: 0 }
  if (!src) {
    return size
  }
  const media = await loadImageFromPath(src).catch() // 画像の場合
  const media = await loadVideoFromPath(src).catch() // 動画の場合
  if (media !== undefined) {
    size = { width: media.naturalWidth, height: media.naturalHeight } // 画像の場合
    size = { width: media.videoWidth, height: media.videoHeight } // 動画の場合
  }
  return size
}

最後に、先程のサイズを取得する関数を実行します。

async printSize() {
  const src = "パスが入ります"
  const size = await getMediaSize(src)
  console.log(size.width, size.height)
}

以上、すでに画像と動画が描画されている場合に値を取得することは容易ですが、描画されていない場合は上記のようなプロセスで取得できます。

参考リンク

qiita.com

lab.syncer.jp

lab.syncer.jp