Resize image client side

This script resize a given image to wanted size before uploading. Therefore is saves computer power for your company! Go green!

by davidohlund

HTML

<form id="file-drop-zone">
  <fieldset>
    <legend>Resize image to:</legend>
    <label for="image-width">Width</label>
    <input id="image-width" type="number" value="600" />
    <label for="image-height">Height</label>
    <input id="image-height" type="number" value="480" />
  </fieldset>

  <fieldset>
    <legend>Input:</legend>
    <input
      id="file-text-input"
      type="text"
      name="text"
      placeholder="Drag and drop or copy paste image"
    />
    <input id="file-chooser" type="file" name="image" />
    <input id="input-info" type="text">
  </fieldset>
  <fieldset>
    <legend>Output:</legend>
    <input id="output-info" type="text">
    <img id="image-output">
  </fieldset>
</form>

CSS

#canvas-buffer {
  width: 100%;
}

form,
fieldset {
  display: flex;
  gap: 10px;
  flex-direction: column;
}

legend {
  border:8px solid blue;
}

input {
  padding:8px
}

input[type="text"], input[type="number"]{
  background-color:rgba(0, 0, 200);
}

* {
  background-color: blue;
  font:
    1.3rem Inconsolata,
    monospace;
  color: white;
}

JavaScript

const filePicker = document.getElementById("file-chooser")
const fileDropZone = document.getElementById("file-drop-zone")
const fileTextInput = document.getElementById("file-text-input")
filePicker.addEventListener("change", handleFileChange)
fileDropZone.addEventListener("drop", handleFileDrop)
fileDropZone.addEventListener("dragover", (e) => e.preventDefault())
fileTextInput.addEventListener("paste", handlePaste)

function handleFileCallback(file) {
    console.log("Original size", calculateSize(file.size));
    const info = document.getElementById("input-info");
    info.value = calculateSize(file.size);
}

function handleOutputCallback(output) {
    const info = document.getElementById("output-info");
    info.value = output.size;
}

/**
 * Handles the file input change event.
 * Reads the selected file and processes it.
 * @param {Event} e - The change event.
 */
function handleFileChange(e) {
    readFile(e.target, handleFileCallback, handleOutputCallback)
}

/**
 * Handles the file input change event.
 * Reads the selected file and processes it.
 * @param {Event} e - The change event.
 */
function handleFileDrop(e) {
    e.preventDefault()
    e.stopPropagation()
    readFile({
        files: e.dataTransfer.files,
    }, handleFileCallback, handleOutputCallback)
}

/**
 * Handles the paste event.
 * Reads the file from the clipboard and processes it.
 * @param {ClipboardEvent} e - The paste event.
 */
function handlePaste(e) {
    const item = e.clipboardData.items[0]
    readFile({
        files: [item.getAsFile()],
    }, handleFileCallback, handleOutputCallback)
}

/**
 * Reads the file input and processes it.
 * If the file is an image, it reads it as a Data URL.
 * @param {Object} input - The file input object.
 */
function readFile(input, callback, outputCallback) {
    if (input.files && input.files[0]) {
        if (callback) {
            callback(input.files[0]);
        }
        const reader = new FileReader()
        reader.onload =...