LoginSignup
2
2

More than 5 years have passed since last update.

Javascriptで画像リサイズ(縮小)

Last updated at Posted at 2019-01-26

画像アップロード機能を実装するときによく使うのでメモします。

/**
 * @param {HTMLImageElement} imgEL 
 * @param {Number} maxSize 
 * @return {Promise<Blob>}
 */
const resizeImage = (imgEL, maxSize, type = 'image/png') => 
  new Promise((resolve) => {
    const ratio = imgEL.naturalWidth / imgEL.naturalHeight
    const canvas = document.createElement('canvas')
    canvas.width = ratio >= 1 ? maxSize : maxSize / ratio
    canvas.height = ratio < 1 ? maxSize : maxSize / ratio
    canvas.getContext('2d').drawImage(imgEL, 0, 0, canvas.width, canvas.height)
    canvas.toBlob(resolve, type)
  })

戻り値のBlobが縮小されたやつでそのままサーバにアップロードすればいい感じですね。

使用例

<body>
  <input type="file">
  <div id="preview"></div>
  <button>アップロード</button>
  <script>
    const resizeImage = (imgEL, maxSize, type = 'image/png') =>
      new Promise(resolve => {
        const ratio = imgEL.naturalWidth / imgEL.naturalHeight
        const canvas = document.createElement('canvas')
        canvas.width = ratio >= 1 ? maxSize : maxSize / ratio
        canvas.height = ratio < 1 ? maxSize : maxSize / ratio
        canvas.getContext('2d').drawImage(imgEL, 0, 0, canvas.width, canvas.height)
        canvas.toBlob(resolve, type)
      })

    const pFileReader = blob =>
      new Promise(resolve => {
        const fr = new FileReader()
        fr.readAsDataURL(blob)
        fr.onload = e => resolve(e.target.result)
      })

    const pImage = src =>
      new Promise(resolve => {
        const img = new Image()
        img.src = src
        img.onload = e => resolve(img)
      })

    document.querySelector('input').onchange = async e => {
      const file = e.target.files[0]
      const preview = document.querySelector('#preview')
      const src = await pFileReader(file)
      const img = await pImage(src)
      // 本当に縮小されることを確認したい場合は以下をコメントアウト
      // const blob = await resizeImage(img, 100, file.type)
      // img.src = await pFileReader(blob)
      preview.appendChild(img)
    }

    document.querySelector('button').onclick = async () => {
      const file = document.querySelector('input').files[0]
      const src = await pFileReader(file)
      const img = await pImage(src)
      const blob = await resizeImage(img, 100, file.type)
      // blobをアップロード ~
    }
  </script>
</body>

以上!

FileReader使ってますけど, URL.createObjURLで代用できますよ。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2