Chrome Extension Image Format Converter: Build Your Own
Browser-based image conversion is becoming essential for web developers, designers, and content creators who need quick format transformations without uploading files to external services. Building a Chrome extension for image format conversion gives you a private, fast, and customizable tool that runs entirely locally.
Why Build a Local Image Converter?
External image conversion websites often raise privacy concerns—you’re uploading your images to servers you don’t control. A custom Chrome extension processes everything locally using the browser’s Canvas API, meaning your images never leave your machine.
Key benefits of a browser-based converter:
- No server uploads—complete privacy
- Instant conversions without network latency
- Works offline after installation
- Customizable output quality settings
- Batch conversion support
Core Architecture
The extension uses three main components: a content script for capturing images from web pages, a popup interface for user controls, and a background worker for processing. The Canvas API handles the actual format conversion through toDataURL() and toBlob() methods.
Manifest Configuration
Your manifest.json needs permissions for active tab access and storage:
{
"manifest_version": 3,
"name": "Image Format Converter",
"version": "1.0",
"permissions": ["activeTab", "storage"],
"action": {
"default_popup": "popup.html"
}
}
Image Conversion Logic
The core conversion function uses Canvas to transform between formats:
async function convertImage(imageData, targetFormat, quality = 0.92) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => {
const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
const mimeType = `image/${targetFormat}`;
canvas.toBlob((blob) => {
if (blob) resolve(blob);
else reject(new Error('Conversion failed'));
}, mimeType, quality);
};
img.onerror = reject;
img.src = imageData;
});
}
Supported Format Details
| Format | Use Case | Quality Range |
|---|---|---|
| PNG | Screenshots, graphics with transparency | Lossless |
| JPEG | Photos, large images | 0.1-1.0 |
| WebP | Modern web content | 0.1-1.0 |
| AVIF | High compression needs | 0.1-1.0 |
Popup Interface Implementation
The popup provides the user interface for selecting conversion options:
<select id="format">
<option value="png">PNG</option>
<option value="jpeg">JPEG</option>
<option value="webp">WebP</option>
</select>
<input type="range" id="quality" min="0.1" max="1.0" value="0.92">
<button id="convert">Convert</button>
<div id="result"></div>
Connect the interface to your conversion logic:
document.getElementById('convert').addEventListener('click', async () => {
const [tab] = await chrome.tabs.query({active: true, currentWindow: true});
chrome.tabs.sendMessage(tab.id, {action: 'getImages'}, async (images) => {
const format = document.getElementById('format').value;
const quality = parseFloat(document.getElementById('quality').value);
for (const img of images) {
const converted = await convertImage(img.src, format, quality);
// Handle download or display
}
});
});
Capturing Images from Pages
The content script runs on web pages to identify and collect convertible images:
// content.js
const images = Array.from(document.images)
.filter(img => img.complete && img.naturalWidth > 0)
.map(img => ({
src: img.src,
width: img.naturalWidth,
height: img.naturalHeight
}));
chrome.runtime.sendMessage({action: 'imagesFound', images});
Handling Large Images and Memory
Large images can consume significant memory. Implement chunked processing for batches:
async function processBatch(images, format, quality, onProgress) {
const results = [];
const batchSize = 5;
for (let i = 0; i < images.length; i += batchSize) {
const batch = images.slice(i, i + batchSize);
const batchResults = await Promise.all(
batch.map(img => convertImage(img.src, format, quality))
);
results.push(...batchResults);
onProgress(Math.min(i + batchSize, images.length) / images.length);
// Allow UI to update between batches
await new Promise(r => setTimeout(r, 50));
}
return results;
}
Download Management
After conversion, users need a way to save their images. Use the Chrome Downloads API:
function downloadConverted(blob, filename) {
const url = URL.createObjectURL(blob);
chrome.downloads.download({
url: url,
filename: filename,
saveAs: true
});
}
Add the download permission to your manifest:
{
"permissions": ["activeTab", "storage", "downloads"]
}
Extension Storage for Preferences
Persist user preferences using Chrome’s storage API:
// Save preferences
chrome.storage.local.set({
defaultFormat: 'webp',
defaultQuality: 0.85,
preserveMetadata: true
});
// Load on startup
chrome.storage.local.get(['defaultFormat', 'defaultQuality'], (prefs) => {
document.getElementById('format').value = prefs.defaultFormat || 'webp';
document.getElementById('quality').value = prefs.defaultQuality || 0.85;
});
Production Considerations
When releasing your extension, consider these factors:
- Browser compatibility: Test Canvas output across Chrome, Firefox, and Edge
- HEIC support: iPhone photos come in HEIC—add a library like
heic2anyfor conversion - Metadata handling: Use
exif-jsto preserve orientation data after conversion - Context menu integration: Add right-click options for quick conversions
Conclusion
Building a Chrome extension for image format conversion uses the browser’s native capabilities to create a fast, private alternative to online converters. The Canvas API provides reliable format transformation, while Chrome’s extension APIs enable seamless integration with web browsing workflows.
Start with basic PNG-to-JPEG conversion, then expand to WebP and AVIF as you refine the user experience. The extension model makes it easy to iterate quickly and deploy updates to users instantly.
Related Reading
- Claude Code for Beginners: Complete Getting Started Guide
- Best Claude Skills for Developers in 2026
- Claude Skills Guides Hub
Built by theluckystrike — More at zovo.one