Claude Skills Guide

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:

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

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:

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.


Built by theluckystrike — More at zovo.one