Before / After Image Viewer
Compare an original image with a transformed result — a two-panel grid with checkerboard transparency or a segmented Original / Enhanced toggle.
Before / After Image Viewer
The Before / After Image Viewer compares an original image with a transformed result. It supports two modes: a two-panel grid (both images side-by-side, the result panel ring-highlighted and rendered on a checkerboard transparency background so alpha shows through), and a segmented Original / Enhanced toggle that swaps a single displayed image source.
It is presentational — both originalSrc and processedSrc are image source strings (data URL or object URL). Produce the result image with useImageToImage (upscaling / super-resolution), whose UpscaleImageResult.image is an ImageData | Blob you convert to an object URL (URL.createObjectURL) before passing it as processedSrc. It owns only the toggle's local UI state.
When to use it: background removers, photo enhancers / upscalers, segmentation viewers — any "here's your input, here's the result" comparison.
Preview
Installation
pnpm dlx shadcn@latest add @localmode/ui/media-vision/before-after-image-viewernpx shadcn@latest add @localmode/ui/media-vision/before-after-image-vieweryarn dlx shadcn@latest add @localmode/ui/media-vision/before-after-image-viewerbunx --bun shadcn@latest add @localmode/ui/media-vision/before-after-image-viewerDependencies
-
Data source: renders the
originalSrc/processedSrcimage strings you pass — works with any backend that produces a transformed image. Recommended LocalMode producer:useImageToImage(upscale / super-resolution) from@localmode/react— convert itsimage(ImageData | Blob) to an object URL forprocessedSrc. For background removal, compositeuseSegmentImage'smasksonto the source into a transparent PNG first (optional). -
clsx+tailwind-merge— via the sharedcn()util (installed automatically as a registry dependency)
Files installed
before-after-image-viewer.tsx— the component (checkerboard CSS shipped inline)lib/utils.ts— thecn()helper (if not already present)
Props
BeforeAfterImageViewer
Prop
Type
Backing hooks
Produce processedSrc with useImageToImage (upscale / super-resolution) from @localmode/react: its UpscaleImageResult.image is an ImageData | Blob, so wrap it in an object URL (URL.createObjectURL) before passing it. For background removal, useSegmentImage returns masks (not a ready image) — composite a mask onto the source to build a transparent PNG, then pass that URL.
Examples
Grid (default)
import { BeforeAfterImageViewer } from '@/components/before-after-image-viewer';
import { useImageToImage } from '@localmode/react';
const { data } = useImageToImage({ model });
// data.image is ImageData | Blob — turn the Blob result into a displayable URL
const processedSrc = data?.image instanceof Blob ? URL.createObjectURL(data.image) : undefined;
<BeforeAfterImageViewer originalSrc={inputDataUrl} processedSrc={processedSrc} />Toggle mode
<BeforeAfterImageViewer
originalSrc={inputDataUrl}
processedSrc={processedSrc} // object URL from the upscale result Blob
mode="toggle"
processedLabel="Upscaled"
/>Background-removal result on checkerboard
const { data } = useSegmentImage({ model });
// useSegmentImage returns `masks` (SegmentMask[]), not a ready image —
// composite a mask onto the source to produce a transparent-background PNG URL.
const cutoutUrl = data ? compositeMaskToTransparentPng(inputDataUrl, data.masks) : undefined;
<BeforeAfterImageViewer
originalSrc={inputDataUrl}
processedSrc={cutoutUrl}
checkerboard // default — reveals the transparent background
/>Accessibility
The two images get distinct alt text so assistive tech never announces the same description for both. Pass a single alt and the viewer derives "{originalLabel}: {alt}" for the original and "{processedLabel}: {alt}" for the result; or set originalAlt / resultAlt explicitly for full control. An empty alt (the default) keeps both images decorative.
<BeforeAfterImageViewer
originalSrc={inputDataUrl}
processedSrc={cutoutUrl}
originalAlt="Original team photo"
resultAlt="Team photo with the background removed"
/>Customization
The checkerboard is a self-contained inline CSS-gradient background, so the component works standalone after shadcn add with no global CSS. Adjust the checker size/color in the copied before-after-image-viewer.tsx, or set checkerboard={false} for opaque results. Panels use shadcn/ui tokens (border-border, bg-card, ring-primary).
Bounding Box Overlay
Color-coded detection boxes positioned over an image as percentage offsets from natural dimensions, with a companion label legend. Serves object / face / hand / pose output.
Image Processing Overlay
A full-bleed overlay shown over a dimmed source image while vision inference runs — spinner ring, status, optional cancel, and an animated scan variant. Renders nothing when idle.