Converting images in the browser with Canvas
In the browser you can convert images with the Canvas API — there's no library to install and no server to upload to. The browser already knows how to decode a PNG and re-encode it as a different format, so converting a PNG to JPG or WebP is just three steps: load the PNG into an Image, draw it onto a <canvas>, then call canvas.toBlob() with the target MIME type. This is exactly how PNGifier works.
Load the PNG and draw to a canvas
Start by loading the file into an Image. Once it fires its onload event you know its dimensions, so you can size a canvas to match and draw the image onto it with drawImage:
const img = new Image();
img.onload = () => {
const canvas = document.createElement("canvas");
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
const ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
// ...export below
};
img.src = URL.createObjectURL(file);Using URL.createObjectURL(file) points the image straight at the file the user picked, with no network request.
Export with canvas.toBlob
Once the image is on the canvas, canvas.toBlob() re-encodes it into whatever format you ask for. Pass the target MIME type as the second argument and, for lossy formats, a quality value between 0 and 1 as the third:
canvas.toBlob(
(blob) => {
const url = URL.createObjectURL(blob);
// download or use the url
},
"image/jpeg",
0.9,
);Swap "image/jpeg" for "image/webp" and the same code exports a WebP instead — every modern browser supports it. The resulting blob can be turned into a download link or previewed directly.
Handling transparency for JPG
JPG has no transparency, so any transparent PNG pixels turn black unless you fill a background first. Paint the canvas with a color before you draw the image:
const img = new Image();
img.onload = () => {
const canvas = document.createElement("canvas");
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
const ctx = canvas.getContext("2d");
// JPG has no transparency, so fill a background first:
ctx.fillStyle = "#fff";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0);
canvas.toBlob((blob) => {
const url = URL.createObjectURL(blob);
// download or use the url
}, "image/jpeg", 0.9);
};
img.src = URL.createObjectURL(file);WebP keeps transparency like PNG, so the background fill is only needed for image/jpeg. If you'd rather not write any code, the PNGifier tools do all of this for you.
Why this is private (runs client-side)
Because the Canvas API runs in the browser, every step — decoding the PNG, drawing it, and re-encoding it — happens on the user's own device. Nothing is uploaded to a server, so the image stays private. New to the format itself? Read what is a PNG.
Frequently asked questions
- Do I need a library to convert a PNG in JavaScript?
- No. The built-in Canvas API can decode a PNG and re-encode it as JPG or WebP. You only need an Image, a canvas element, and canvas.toBlob — no npm package or server.
- Which formats can canvas.toBlob export?
- Every browser supports image/png and image/jpeg, and all modern browsers also support image/webp. Pass the MIME type as the second argument to toBlob.
- Why does my JPG have a black background?
- JPG has no transparency, so transparent PNG pixels become black by default. Fill the canvas with a color before drawing the image to control the background.
- Does this upload my image anywhere?
- No. The Canvas API runs entirely in the browser, so your file is decoded and re-encoded on your own device and never leaves it.