Canvas API로 브라우저에서 이미지를 압축하는 방법 (업로드 없음, 서버 없음)

작성자

카테고리:

← 피드로
DEV Community · Arhan Ahmad · 2026-07-04 개발(SW)

Arhan Ahmad

How to Compress Images in the Browser with Canvas API

Every image you upload to a “free” online compressor is sent to a server — often without you knowing what happens to it afterward. For a tool that processes your private photos, that’s a terrible design.

Here’s how to build (or use) an image compressor that runs entirely in the browser using the HTML5 Canvas API. No uploads, no server costs, and unlimited file sizes.

The Core Technique: Canvas toBlob()

The key API is HTMLCanvasElement.toBlob():


js
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');

const img = new Image();
img.onload = () => {
  canvas.width = img.naturalWidth;
  canvas.height = img.naturalHeight;
  ctx.drawImage(img, 0, 0);

  canvas.toBlob((blob) => {
    const url = URL.createObjectURL(blob);
  }, 'image/jpeg', 0.8);
};
img.src = 'your-image.jpg';
The second parameter is the MIME type (image/jpeg, image/png, image/webp, image/avif). The third is quality (0–1).
Step-Down Resizing for Large Images
If you're compressing a 6000×4000 px photo, drawing it at full resolution onto a canvas can eat 70+ MB of memory. Step-down resizing halves the dimensions repeatedly:
function stepDownEncode(img, maxDim, quality) {
  let w = img.naturalWidth;
  let h = img.naturalHeight;
  let src = img;

  while (w > maxDim * 2 || h > maxDim * 2) {
    w = Math.floor(w / 2);
    h = Math.floor(h / 2);
    const temp = document.createElement('canvas');
    temp.width = w;
    temp.height = h;
    temp.getContext('2d').drawImage(src, 0, 0, w, h);
    src = temp;
  }

  const canvas = document.createElement('canvas');
  canvas.width = w;
  canvas.height = h;
  canvas.getContext('2d').drawImage(src, 0, 0, w, h);

  return new Promise((resolve) => {
    canvas.toBlob((blob) => resolve(blob), 'image/jpeg', quality);
  });
}
This prevents memory crashes and actually produces better quality (step-down preserves more detail than a single jump).
Comparing Real-World Results
Format  Avg Original    Avg Compressed  Avg Savings
JPEG → JPEG (Q80) 3.2 MB  0.8 MB  75%
PNG → WebP (Q85)  4.8 MB  0.6 MB  87%
JPEG → AVIF (Q70) 3.2 MB  0.4 MB  87%
WebP consistently beats JPEG at the same visual quality by 25–35%. AVIF beats WebP by another 20–30%.
The Production Tool
If you don't want to build your own, the ToolBox Image Compressor (https://toolboximage.com/compressor/) implements all of this with a clean UI — drag & drop, batch processing (up to 200 images), side-by-side preview, and target-size compression. It's free, processes everything locally, and supports JPEG/PNG/WebP/AVIF/GIF input.
Key Takeaways
1. canvas.toBlob() is all you need for basic compression
2. Step-down resizing prevents memory issues on large images
3. WebP offers the best quality/size tradeoff for web use today
4. Client-side compression means zero server cost and zero privacy risk
Try the tool at toolboximage.com/compressor/ (https://toolboximage.com/compressor/)

Enter fullscreen mode Exit fullscreen mode

원문에서 계속 ↗

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다