Fetching latest headlines…
Building a Browser-Based Passport Photo Maker with Country Presets
NORTH AMERICA
🇺🇸 United StatesJuly 4, 2026

Building a Browser-Based Passport Photo Maker with Country Presets

0 views0 likes0 comments
Originally published byDev.to

Building a Browser-Based Passport Photo Maker

Passport photos have strict government specifications — exact dimensions, specific background colors, and precise head positioning. Here's how to build a tool that handles all of this entirely in the browser.

The Challenge

Each country has different requirements:

Country Size (mm) Size (px at 300 DPI) Background
US 51×51 600×600 White
UK/EU 35×45 413×531 Light gray
India 35×45 413×531 White
Canada 50×70 591×827 White
China 33×48 390×567 White
Japan 35×45 413×531 White
Australia 35×45 413×531 White
France 35×45 413×531 Light gray
Germany 35×45 413×531 Light gray
UAE 43×55 508×650 White

Loading and Displaying the Image

First, load the user's image and display it with an interactive crop overlay:


js
function loadImage(file) {
  return new Promise((resolve) => {
    const img = new Image();
    img.onload = () => resolve(img);
    img.src = URL.createObjectURL(file);
  });
}
Interactive Crop Window
The crop window is an absolutely positioned div overlaid on the image. Users can drag it to reposition and resize using corner handles:
class CropWindow {
  constructor(container, image, preset) {
    this.container = container;
    this.image = image;
    this.preset = preset;
    this.x = 0;
    this.y = 0;
    this.w = 200;
    this.h = 260;
    this.initHandles();
    this.initKeyboard();
  }

  initHandles() {
    // 4 corner handles for resize
    const handles = ['nw', 'ne', 'sw', 'se'];
    handles.forEach(pos => {
      const handle = document.createElement('div');
      handle.className = `crop-handle ${pos}`;
      handle.addEventListener('pointerdown', (e) => this.startResize(e, pos));
      this.container.appendChild(handle);
    });
  }

  initKeyboard() {
    document.addEventListener('keydown', (e) => {
      const step = e.shiftKey ? 10 : 2;
      switch(e.key) {
        case 'ArrowUp': this.y = Math.max(0, this.y - step); break;
        case 'ArrowDown': this.y = Math.min(this.maxY, this.y + step); break;
        case 'ArrowLeft': this.x = Math.max(0, this.x - step); break;
        case 'ArrowRight': this.x = Math.min(this.maxX, this.x + step); break;
      }
      this.render();
    });
  }
}
Background Replacement
To change the background color, we scan edge pixels and replace similar colors:
function replaceBackground(canvas, targetColor, tolerance = 30) {
  const ctx = canvas.getContext('2d');
  const data = ctx.getImageData(0, 0, canvas.width, canvas.height);
  const pixels = data.data;

  // Sample background color from corners
  const bg = sampleCornerPixels(pixels, canvas.width, canvas.height);

  for (let i = 0; i < pixels.length; i += 4) {
    const diff = colorDistance(pixels, bg, i);
    if (diff < tolerance) {
      pixels[i] = targetColor.r;     // R
      pixels[i + 1] = targetColor.g; // G
      pixels[i + 2] = targetColor.b; // B
    }
  }

  ctx.putImageData(data, 0, 0);
}
Print Layout Generation
For users who want to print at a photo lab, we need to arrange multiple copies on a 4×6 inch (1024×1536 px at 300 DPI) print sheet:
function generatePrintLayout(singlePhoto, preset, sheetWidth = 1500, sheetHeight = 1000) {
  const canvas = document.createElement('canvas');
  canvas.width = sheetWidth;
  canvas.height = sheetHeight;
  const ctx = canvas.getContext('2d');

  // Fill with white background
  ctx.fillStyle = 'white';
  ctx.fillRect(0, 0, sheetWidth, sheetHeight);

  // Calculate how many photos fit
  const cols = Math.floor(sheetWidth / (preset.outW + 20));
  const rows = Math.floor(sheetHeight / (preset.outH + 20));

  for (let row = 0; row < rows; row++) {
    for (let col = 0; col < cols; col++) {
      const x = col * (preset.outW + 20) + 10;
      const y = row * (preset.outH + 20) + 10;
      ctx.drawImage(singlePhoto, x, y, preset.outW, preset.outH);
    }
  }

  return canvas;
}
Full Tool
The ToolBox Image Passport Photo Maker (https://toolboximage.com/tools/passport/) implements all of this with 10 country presets, 4 background colors, arrow key fine positioning, and both single photo + print layout downloads. All client-side, zero uploads.
Try it at toolboximage.com/tools/passport/ (https://toolboximage.com/tools/passport/)

Comments (0)

Sign in to join the discussion

Be the first to comment!