Last active
March 15, 2022 00:42
-
-
Save mryhryki/bf4f96e237cf41bae8be0b63f9dfae9b to your computer and use it in GitHub Desktop.
Resize on Canvas
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!doctype html> | |
| <html> | |
| <head> | |
| <meta charset='UTF-8'> | |
| <meta name='viewport' content='width=device-width'> | |
| <title>Resize on Canvas</title> | |
| <style> | |
| body { | |
| margin: 0 auto; | |
| max-width: calc(100vw - 16px); | |
| padding: 16px 8px; | |
| width: 800px; | |
| } | |
| p { | |
| text-align: center; | |
| } | |
| button { | |
| background-color: dodgerblue; | |
| border-radius: 4px; | |
| border: none; | |
| color: white; | |
| font-size: 16px; | |
| padding: 12px 32px; | |
| text-align: center; | |
| } | |
| img { | |
| background-color: whitesmoke; | |
| border-radius: 4px; | |
| border: 1px solid gray; | |
| min-height: 24px; | |
| object-fit: contain; | |
| padding: 1px; | |
| } | |
| #before-image { | |
| max-width: 100%; | |
| } | |
| #after-image { | |
| max-width: 300px; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div> | |
| <p> | |
| <label for='image-file'>Image:</label> | |
| <input id='image-file' type='file'> | |
| </p> | |
| <p> | |
| <img id='before-image' alt='Before'> | |
| </p> | |
| <p> | |
| <button id='resize-button'>Resize (W:300px)</button> | |
| </p> | |
| <p> | |
| <img id='after-image' alt='After'> | |
| </p> | |
| </div> | |
| <script> | |
| const resizeImage = async (imageData, width) => { | |
| try { | |
| const context = document.createElement('canvas').getContext('2d') | |
| if (context == null) { | |
| return null | |
| } | |
| // 画像のサイズを取得 | |
| const image = await new Promise((resolve, reject) => { | |
| const image = new Image() | |
| image.addEventListener('load', () => resolve(image)) | |
| image.addEventListener('error', reject) | |
| image.src = URL.createObjectURL(imageData) | |
| }) | |
| const { naturalHeight: beforeHeight, naturalWidth: beforeWidth } = image | |
| // 変換後の高さと幅を算出 | |
| const afterWidth = width | |
| const afterHeight = Math.floor(beforeHeight * (afterWidth / beforeWidth)) | |
| // Canvas 上に描画 | |
| context.canvas.width = afterWidth | |
| context.canvas.height = afterHeight | |
| // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage | |
| context.drawImage(image, 0, 0, beforeWidth, beforeHeight, 0, 0, afterWidth, afterHeight) | |
| // JPEGデータにして返す | |
| return await new Promise((resolve) => { | |
| context.canvas.toBlob(resolve, `image/jpeg`, 0.9) | |
| }) | |
| } catch (err) { | |
| console.error(err) | |
| return null | |
| } | |
| } | |
| const el = (id) => document.getElementById(id) | |
| window.onload = () => { | |
| el('image-file').onchange = () => { | |
| const file = el('image-file').files[0] | |
| if (file != null) { | |
| el('before-image').src = URL.createObjectURL(file) | |
| } | |
| } | |
| el('resize-button').onclick = () => { | |
| const file = el('image-file').files[0] | |
| if (file == null) { | |
| alert("No image file selected") | |
| return | |
| } | |
| resizeImage(file, 300).then((image) => { | |
| el('after-image').src = URL.createObjectURL(image) | |
| }) | |
| } | |
| } | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment