DEV Community

Ubed Sheikh
Ubed Sheikh

Posted on

Why WebP to JPG Conversion Breaks on Most Tools — And How the HTML5 Canvas API Fixes It

If you've ever downloaded an image from WhatsApp, a website, or an Android screenshot and tried to upload it to a government portal or older app — only to get a "format not supported" error — you've hit the WebP problem.

This post explains why it happens, what most tools get wrong, and how browser-based conversion using the HTML5 Canvas API actually solves it cleanly.


Why WebP Breaks on So Many Platforms

WebP was developed by Google in 2010 and is now the default format for images on Chrome, Android, and most modern websites. It produces files 25–35% smaller than JPG at the same visual quality.

The problem: a huge number of platforms still don't support it.

  • Indian government portals (Aadhaar, SSC, UPSC, Railway) — require JPG only
  • WhatsApp Web downloads — saves as .webp by default
  • Older Windows apps — don't open WebP natively
  • Email attachments — many clients can't render WebP
  • Job portals like Naukri — require JPG profile photo

So you have a perfectly good image, in a modern format, that half the world can't use.


What Most Online Converters Get Wrong

Most online image converters are server-side. You upload your file → it goes to their server → gets converted → you download the result.

Three problems with this:

1. Privacy risk. Your Aadhaar photo, passport scan, or ID document just got uploaded to a random server you know nothing about.

2. Quality loss from double compression.
Server-side tools often re-compress the image twice — once on upload, once on conversion. You lose quality you didn't need to lose.

3. They break on edge cases. Animated WebP,
WebP with transparency, or WebP files above a certain size often fail silently on server-side tools.


The Browser-Based Approach: HTML5 Canvas API

Modern browsers can handle image conversion entirely client-side using the Canvas API. No server needed.

Here's the core of how it works:

function convertImage(file, targetFormat, quality) {
  return new Promise((resolve) => {
    const img = new Image();
    const url = URL.createObjectURL(file);

    img.onload = () => {
      const canvas = document.createElement('canvas');
      canvas.width = img.naturalWidth;
      canvas.height = img.naturalHeight;

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

      // For JPG output: fill transparent areas with white
      // (JPG doesn't support transparency)
      if (targetFormat === 'image/jpeg') {
        ctx.fillStyle = '#FFFFFF';
        ctx.fillRect(0, 0, canvas.width, canvas.height);
      }

      ctx.drawImage(img, 0, 0);

      canvas.toBlob((blob) => {
        URL.revokeObjectURL(url);
        resolve(blob);
      }, targetFormat, quality);
    };

    img.src = url;
  });
}
Enter fullscreen mode Exit fullscreen mode

The key method is canvas.toBlob(). It accepts:

  • type — the target MIME type (image/jpeg, image/png, image/webp)
  • quality — a value between 0 and 1 for lossy formats like JPG and WebP

The browser handles all the encoding natively.
Your file never leaves the device.


The Gotcha: Transparency in JPG Output

One thing that catches a lot of developers: JPG doesn't support transparency.

If you're converting a PNG or WebP with a transparent background to JPG, you need to explicitly fill the canvas with white (or whatever background colour you want) before drawing the image — otherwise you get black
or corrupted areas.

That's what this line does in the snippet above:

if (targetFormat === 'image/jpeg') {
  ctx.fillStyle = '#FFFFFF';
  ctx.fillRect(0, 0, canvas.width, canvas.height);
}
Enter fullscreen mode Exit fullscreen mode

Most broken converters skip this step.


Real-World Use Case: India's Government Portals

This is the gap I ran into personally. In India, almost every government portal — Aadhaar, SSC CGL, UPSC, Railway RRB, passport applications —
requires photos in JPG format, typically under 50KB.

But WhatsApp (used by ~500 million Indians) saves all images as WebP. Android screenshots are WebP. Most modern phone cameras offer WebP.

So you have a generation of users with WebP files on their phones who can't upload them to the portals they need.

I built this conversion logic into EasyToolkit's free image converter — it handles WebP → JPG, PNG → JPG, and 6 other format combinations, entirely in the browser, with batch support for up to 20 files.

The India-specific angle (Aadhaar, SSC, UPSC portal requirements) is baked into the tool — it's genuinely the most common reason Indian
users need format conversion.


What I Learned Building This

A few things that weren't obvious before I built it:

TIFF files are complicated. The Canvas API doesn't natively decode TIFF. You need a library like UTIF.js for TIFF input support.

GIF animation doesn't survive conversion.
canvas.toBlob() captures a single frame. If someone converts an animated GIF to WebP expecting animation, they get a still image.
Worth flagging to users upfront.

Quality slider UX matters more than you'd think.
Users don't understand what "quality: 0.85" means. Showing the estimated output file size as they drag the slider is far more useful than a
percentage value.

Mobile performance is fine for single images, gets slow for batch. Converting 20 x 4MB images on a mid-range Android phone in sequence takes
longer than expected. Queuing conversions with a small delay between each one prevents the UI from freezing.


Summary

  • WebP is everywhere, but supported by almost no legacy platforms
  • Server-side conversion has real privacy and quality tradeoffs
  • canvas.toBlob() is the clean client-side fix - Fill transparent backgrounds before JPG output or you'll get black areas
  • For India specifically: WhatsApp → WebP → government portal rejection is a daily problem for millions of users

If you're building anything that touches image uploads in India, handling WebP → JPG conversion client-side is worth adding.


Built the image converter as part of EasyToolkit — a free browser-based toolkit for PDF, image,
and document utilities. All processing happens locally. Feedback welcome.

Top comments (0)