Resize an Image Before Upload with JavaScript

Browser-side resizing can reduce upload time for large camera images. Decode the selected File, calculate bounded dimensions, draw to a canvas, and export a Blob. Keep the original when it is already within limits, and validate the result again on the server.

Last updated: September 26, 2026.

async function resizeImage(file, maxWidth = 1600, maxHeight = 1600) {
  const source = await createImageBitmap(file);
  const scale = Math.min(1, maxWidth / source.width, maxHeight / source.height);
  const width = Math.round(source.width * scale);
  const height = Math.round(source.height * scale);

  const canvas = document.createElement('canvas');
  canvas.width = width;
  canvas.height = height;
  canvas.getContext('2d').drawImage(source, 0, 0, width, height);
  source.close();

  return await new Promise((resolve, reject) => {
    canvas.toBlob(blob => blob ? resolve(blob) : reject(new Error('Resize failed')),
      'image/webp', 0.82);
  });
}

The scale never exceeds 1, so smaller files are not enlarged. Both constraints are applied while preserving aspect ratio.

Upload the Blob with a useful filename

Create a File from the Blob when the server expects a filename: new File([blob], "photo.webp", {type: blob.type}). Append it to FormData and send it with fetch. Do not manually set the multipart Content-Type; the browser adds the boundary.

Choose output quality deliberately

JPEG and WebP quality values trade detail for size. Test photographs, screenshots, transparent images, and text-heavy graphics. PNG is lossless and may be larger. canvas.toBlob() falls back to PNG when a requested type is unsupported; verify blob.type before choosing the extension.

MDN documents toBlob(), including format support and the possible null result. Canvas output commonly discards metadata, so retain required attribution or orientation data separately.

Enforce server limits too

A client can skip this function or upload a crafted file. The server must decode the image, enforce byte and pixel limits, generate trusted derivatives, and store it outside executable paths. Use dimension validation for immediate feedback and the preview pattern to show the result before submission.

Related Web Cheat Sheet guides

Sergey Kornilov

Sergey Kornilov