When you need to convert WebP images as part of an automated workflow — a web scraper, a content management system, a batch processing pipeline, or a web application — you need a programmatic approach rather than a manual one-click tool.
This guide covers the major server-side, client-side, and API-based options for automating WebP-to-JPG conversion.
One-Off Conversions? No Code Needed
Right-click any WebP image and save as JPG. Free, instant, browser-based.
Add to Chrome — FreeBrowser-Side: Canvas API
The Canvas API lets you convert WebP to JPG entirely in the user's browser — no server required, no upload, privacy-preserving. This is how the Chrome extension works.
WebP to JPG conversion in JavaScript (browser)
// Convert a WebP image URL to a JPG data URL
function convertWebpToJpg(imageUrl, quality = 0.9) {
return new Promise((resolve, reject) => {
const img = new Image();
img.crossOrigin = "anonymous";
img.onload = () => {
const canvas = document.createElement("canvas");
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
const ctx = canvas.getContext("2d");
// White background for areas that may have transparency
ctx.fillStyle = "#ffffff";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0);
// Convert to JPG data URL
const jpgDataUrl = canvas.toDataURL("image/jpeg", quality);
resolve(jpgDataUrl);
};
img.onerror = reject;
img.src = imageUrl;
});
}
// Usage
convertWebpToJpg("https://example.com/image.webp", 0.92)
.then(jpgDataUrl => {
// Trigger download
const a = document.createElement("a");
a.href = jpgDataUrl;
a.download = "converted.jpg";
a.click();
});
Convert WebP File object (from file input) to JPG
function convertWebpFileToJpg(file, quality = 0.9) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = (e) => {
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.fillStyle = "#ffffff";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0);
canvas.toBlob(blob => resolve(blob), "image/jpeg", quality);
};
img.onerror = reject;
img.src = e.target.result;
};
reader.readAsDataURL(file);
});
}
Node.js: Sharp Library
Sharp is the standard Node.js image processing library. It is fast (uses libvips, a C library), memory-efficient, and has excellent WebP support.
Single file conversion with Sharp
// Install: npm install sharp
const sharp = require("sharp");
// File to file
async function convertWebpToJpg(inputPath, outputPath, quality = 90) {
await sharp(inputPath)
.jpeg({ quality, mozjpeg: true })
.toFile(outputPath);
console.log(`Converted: ${inputPath} → ${outputPath}`);
}
convertWebpToJpg("input.webp", "output.jpg", 92);
Batch conversion with Sharp
const sharp = require("sharp");
const fs = require("fs");
const path = require("path");
async function batchConvertWebpToJpg(inputDir, outputDir, quality = 90) {
fs.mkdirSync(outputDir, { recursive: true });
const webpFiles = fs.readdirSync(inputDir)
.filter(f => f.toLowerCase().endsWith(".webp"));
for (const file of webpFiles) {
const inputPath = path.join(inputDir, file);
const outputName = file.replace(/\.webp$/i, ".jpg");
const outputPath = path.join(outputDir, outputName);
await sharp(inputPath)
.jpeg({ quality, mozjpeg: true })
.toFile(outputPath);
console.log(`Converted: ${file}`);
}
console.log(`Done. ${webpFiles.length} files converted.`);
}
batchConvertWebpToJpg("./images/webp", "./images/jpg", 90);
In-memory conversion (for web server responses)
// Convert WebP buffer to JPG buffer (no file I/O)
const sharp = require("sharp");
async function webpBufferToJpgBuffer(webpBuffer, quality = 90) {
return await sharp(webpBuffer)
.jpeg({ quality })
.toBuffer();
}
// Example: Express.js endpoint that accepts WebP and returns JPG
app.post("/convert", async (req, res) => {
try {
const jpgBuffer = await webpBufferToJpgBuffer(req.body, 90);
res.set("Content-Type", "image/jpeg");
res.send(jpgBuffer);
} catch (err) {
res.status(400).json({ error: "Conversion failed" });
}
});
Python: Pillow
from PIL import Image
import io
# Single file conversion
def convert_webp_to_jpg(input_path, output_path, quality=90):
img = Image.open(input_path)
# Handle RGBA (transparency) — JPG doesn't support it
if img.mode == "RGBA":
background = Image.new("RGB", img.size, (255, 255, 255))
background.paste(img, mask=img.split()[3])
img = background
elif img.mode != "RGB":
img = img.convert("RGB")
img.save(output_path, "JPEG", quality=quality, subsampling=0)
# In-memory conversion (for web frameworks)
def webp_bytes_to_jpg_bytes(webp_bytes, quality=90):
img = Image.open(io.BytesIO(webp_bytes))
if img.mode in ("RGBA", "LA"):
background = Image.new("RGB", img.size, (255, 255, 255))
background.paste(img, mask=img.split()[-1])
img = background
else:
img = img.convert("RGB")
output = io.BytesIO()
img.save(output, "JPEG", quality=quality, subsampling=0)
return output.getvalue()
PHP: GD and Imagick
PHP with GD library
<?php
function convertWebpToJpg(string $inputPath, string $outputPath, int $quality = 90): bool {
$img = imagecreatefromwebp($inputPath);
if (!$img) return false;
$result = imagejpeg($img, $outputPath, $quality);
imagedestroy($img);
return $result;
}
convertWebpToJpg('input.webp', 'output.jpg', 90);
PHP with Imagick
<?php
function convertWebpToJpgImagick(string $inputPath, string $outputPath, int $quality = 90): void {
$img = new Imagick($inputPath);
$img->setImageFormat('jpeg');
$img->setImageCompressionQuality($quality);
$img->writeImage($outputPath);
$img->destroy();
}
convertWebpToJpgImagick('input.webp', 'output.jpg', 90);
Third-Party APIs
| API | Free Tier | Best For | Privacy |
|---|---|---|---|
| Cloudinary | 25 credits/month | Full image pipeline (resize, improve, CDN) | Images stored on Cloudinary servers |
| Imgix | Trial only | Real-time transformation for large scale | Images served from your origin |
| TinyPNG API | 500 compressions/month | Compression + basic format conversion | Images uploaded temporarily |
| Convertio API | Limited | Format conversion (many formats) | Files uploaded to Convertio servers |
No-Code, Privacy-First WebP Conversion
The Chrome extension converts entirely in your browser — no upload, no server.
Install WebP to JPG Converter — FreeRelated Guides
Frequently Asked Questions
How do I convert WebP to JPG programmatically?
Python with Pillow: Image.open('input.webp').convert('RGB').save('output.jpg', quality=90). Node.js with Sharp: sharp('input.webp').jpeg({quality: 90}).toFile('output.jpg'). PHP with GD: imagejpeg(imagecreatefromwebp('input.webp'), 'output.jpg', 90).
What is the best Node.js library for WebP to JPG conversion?
Sharp is the standard choice: fast (libvips-based), memory-efficient, and well-maintained. Install with npm install sharp. It handles WebP, PNG, JPG, AVIF, and more with a clean async API.
Can I convert WebP to JPG in a browser using JavaScript?
Yes, via the Canvas API: draw the WebP onto a canvas element and call canvas.toDataURL('image/jpeg', 0.9). This is entirely client-side with no server upload — the same approach used by the Chrome extension.
How do I convert WebP to JPG in PHP?
With GD: imagejpeg(imagecreatefromwebp('input.webp'), 'output.jpg', 90). With Imagick: create an Imagick object, set format to JPEG, set quality, and write. GD requires WebP support compiled in (standard in PHP 7.0+).
Should I use a third-party API or handle WebP conversion server-side?
For privacy-sensitive images, use self-hosted conversion (Sharp, Pillow) — images never leave your infrastructure. For high-volume production pipelines where CDN delivery and optimization are also needed, Cloudinary or Imgix are practical. Third-party APIs always receive your image data on their servers.