Extraction
Extract dominant colors from images using quantization and OKLab merging. Detect and measure border regions in product photos. Node-only — requires sharp.
Material Swatch
Source image

Extracted palette
12 colors covering 99% of the visible material.
Background
Corner sampling
Histogram
720 HSL cells
Merge
OKLab d < 0.03
Pipeline
const { colors, background } = await extractColorsFromBuffer(buffer);
// 12 colors extractedimport { extractColorsFromUrl, extractColorsFromBuffer } from "colorscope/extraction";
import { detectBorderFromBuffer, detectBorderFromUrl } from "colorscope/border";Color Extraction
extractColorsFromUrl
Extract dominant colors from an image URL.
function extractColorsFromUrl(imageUrl: string): Promise<ExtractionResult>| Param | Type | Description |
|---|---|---|
imageUrl | string | Public http/https URL (blocks private IPs) |
Returns: Up to 12 colors sorted by proportion + background detection metadata.
const { colors, background } = await extractColorsFromUrl("https://example.com/leather-swatch.jpg");
// colors: [{ hue: 30, saturation: 75, lightness: 30, proportion: 0.35, hex: "#8B4513", ... }, ...]
// background: { detected: true, hex: "#e6e6e6" }extractColorsFromBuffer
Extract dominant colors from a local image buffer.
function extractColorsFromBuffer(buffer: Buffer): Promise<ExtractionResult>| Param | Type | Description |
|---|---|---|
buffer | Buffer | Raw image buffer (any format supported by sharp) |
import { readFile } from "fs/promises";
const buffer = await readFile("leather-swatch.jpg");
const { colors, background } = await extractColorsFromBuffer(buffer);
if (background.detected) {
console.log(`Studio background filtered: ${background.hex}`);
}Pipeline
The extraction pipeline processes images through four stages:
- Background detection — Samples corners to detect and exclude uniform backgrounds
- Histogram counting — Quantizes every pixel to a 720-cell HSL grid (24 hues × 6 saturations × 5 lightnesses)
- Proportion coverage — Keeps colors until 95% of foreground pixels are covered
- OKLab merging — Merges perceptually similar colors (distance < 0.03) and filters JPEG artifacts
Images are resized to 200×200px before processing for speed.
Border Detection
detectBorderFromBuffer
Detect uniform border regions in an image buffer — useful for cropping product photos with solid-color frames.
async function detectBorderFromBuffer(
buffer: Buffer,
options?: DetectBorderOptions
): Promise<BorderBounds>| Param | Type | Description |
|---|---|---|
buffer | Buffer | Image data (any format supported by sharp) |
options | DetectBorderOptions | Detection parameters |
const border = await detectBorderFromBuffer(buffer);
if (border.color) {
console.log(`Border: ${border.color}, top: ${border.top.width}px`);
console.log(`Content: ${border.contentBox.width}×${border.contentBox.height}`);
}detectBorderFromUrl
async function detectBorderFromUrl(
url: string,
options?: DetectBorderOptions
): Promise<BorderBounds>Fetch image from URL and detect borders. SSRF-protected — public http/https only.
How Border Detection Works
- Corner sampling — 5×5 pixel patches at each corner, converted to OKLab
- Edge scanning — Scans inward, measuring rows/columns matching border color
- Confidence scoring — 0-1 based on transition sharpness
- Coordinate scaling — Widths reported in original image coordinates
Types
ExtractionResult
interface ExtractionResult {
colors: QuantizedColor[];
background: {
detected: boolean;
hex: string | null;
};
}BorderBounds
interface BorderBounds {
top: EdgeBound;
right: EdgeBound;
bottom: EdgeBound;
left: EdgeBound;
color: string | null;
contentBox: { x: number; y: number; width: number; height: number };
}EdgeBound
interface EdgeBound {
width: number; // Pixels (original coordinates)
confidence: number; // 0-1 transition sharpness
}DetectBorderOptions
interface DetectBorderOptions {
colorThreshold?: number; // OKLab distance (default: 0.05)
uniformityThreshold?: number; // Row/column match fraction (default: 0.95)
maxResolution?: number; // Downscale target (default: 400)
}