DEV Community

swift king
swift king

Posted on

Why I Stopped Using Cloud Converters and Built My Own

After a client asked me to convert 200 product photos from WebP to PNG, I uploaded the first batch to a popular online converter. It took 45 minutes, and halfway through I realized I was sending proprietary product images to a server I knew nothing about.

That was the moment I decided to build something that ran locally.

The Privacy Problem Nobody Talks About

Most free online converters upload your files to a server for processing. Their privacy policies often include broad licenses to "process and analyze" uploaded content. For client work, this is a non-starter.

I built webp2png.io as a browser-local alternative. Files stay in memory, processed via the Canvas API. Open DevTools Network tab while using it — you won't see a single upload request.

What I Learned About Canvas Performance

Processing 200 images taught me a few things:

  1. OffscreenCanvas is worth it. Moving rendering off the main thread kept the UI responsive during batch operations. The difference was dramatic — 200 images processed in under 10 seconds vs. 45+ minutes with upload-based tools.

  2. Memory management matters. Each canvas context holds a decoded image in memory. For batch processing, I had to explicitly revoke object URLs and let garbage collection do its job. Otherwise Chrome would crash around image #150.

  3. The WebP format is quirky. Chrome supports it natively, but Firefox took years to add full support. I had to add fallback handling for Safari versions that don't handle animated WebP correctly.

I later applied these same patterns to an SVG converter at svg2png.org and learned that SVG rendering brings its own set of headaches — crossOrigin issues, foreignObject limitations, and font embedding problems that Canvas simply can't solve.

The Code

The core pattern is surprisingly simple:

const img = new Image();
img.onload = () => {
  const canvas = new OffscreenCanvas(img.width, img.height);
  const ctx = canvas.getContext('2d');
  ctx.drawImage(img, 0, 0);
  canvas.convertToBlob({type: 'image/png'}).then(blob => {
    const url = URL.createObjectURL(blob);
    download(url, 'converted.png');
  });
};
img.src = URL.createObjectURL(file);
Enter fullscreen mode Exit fullscreen mode

If you work with client data or proprietary files, stop uploading them to random servers. Browser-local processing works today. It's faster, private, and puts you in control.

Top comments (1)

Collapse
 
voltagegpu profile image
VoltageGPU

It's frustrating when cloud tools fall short on performance or cost for bulk operations. I've had similar issues with image conversion pipelines—especially when dealing with high-resolution assets. Have you considered using a local GPU-accelerated tool like VoltageGPU for batch processing? It can make a big difference in speed and control.