Frontend Development 19 min read

How to Auto-Extract Theme Colors from Images with JavaScript: Median‑Cut & Octree Explained

This article explains how to automatically extract a picture’s dominant theme colors in the browser using JavaScript, covering the problem background, analysis of common methods, advantages of client‑side processing, and step‑by‑step implementation of median‑cut and octree algorithms with code examples.

Weimob Technology Center
Weimob Technology Center
Weimob Technology Center
How to Auto-Extract Theme Colors from Images with JavaScript: Median‑Cut & Octree Explained

1. Introduction

Theme color is the primary color used in UI design to set the overall atmosphere and style. Proper selection improves visibility, usability and user experience.

2. Background

WeChat mini‑program CRM membership module supports level and rights cards. Merchants can customize card appearance (medal, background, images, text color) but must manually set background/theme colors, which is costly and limited to a few preset palettes.

Extracting theme colors is often associated with OpenCV, yet JavaScript can also accomplish it with real‑time, browser‑native capabilities.

3. Requirement Analysis

To automate theme‑color extraction we consider three common approaches:

Average‑color method – simple but may miss dominant hues.

Color histogram – selects histogram peaks; works for multi‑color images but overall quality is limited.

OpenCV – powerful but requires server‑side processing.

JavaScript offers client‑side control, responsiveness for small images, and interactive adjustments.

4. Technical Solution

The solution consists of three steps:

Load image data using Canvas and getImageData (optionally in a Web Worker).

Pre‑process the pixel data: denoise (Gaussian filter) and peel off near‑white/black borders.

Generate theme colors using either median‑cut or octree algorithms.

4.1 Load Image Data

Create a Canvas element, draw the image with

drawImage

, then obtain an ImageData object via

getImageData

. Web Workers are used for off‑screen rendering to avoid blocking the main thread.

Canvas loading illustration
Canvas loading illustration

4.2 Data Pre‑processing

4.2.1 Denoising

Apply Gaussian filter (convolution) to remove noise. Convolution is explained with examples such as image blurring, sharpening, edge detection, and even magic‑wand selection.

Gaussian filter illustration
Gaussian filter illustration

4.2.2 Peeling

Remove pixels whose RGB values are close to pure white or black (e.g.,

if (!(Math.min(r,g,b) >= max || Math.max(r,g,b) <= min)) { … }

).

<code>function convertToPixelsArray(imgData) {
  const data = imgData.data;
  const pixels = [];
  const [min, max] = [5, 250]; // filter range can be adjusted
  for (let i = 0; i < data.length; i += 4) {
    const r = data[i];
    const g = data[i + 1];
    const b = data[i + 2];
    if (!(Math.min(r, g, b) >= max || Math.max(r, g, b) <= min)) {
      // optional: filter alpha channel
      pixels.push([data[i], data[i + 1], data[i + 2]]);
    }
  }
  return pixels;
}
</code>

4.3 Generate Theme Colors

Two algorithms are used:

Median‑cut

Pixels are treated as points in a 3‑D RGB cube. The algorithm repeatedly splits the box with the longest side at its median until a desired number of boxes is reached, then averages the colors.

<code>function medianCut(pixels) {
  const colorRange = getColorRange(pixels); // RGB range of the box
  const colorBox = new ColorBox(colorRange, pixels.length, pixels);
  const divisions = 8; // maximum cuts, can be customized
  let [box1, box2] = cutBox(colorBox); // first split
  return queueCut([box1, box2], divisions);
}
function queueCut(queue, num) {
  let isSmallBox = false;
  while (queue.length < num && !isSmallBox) {
    const denselyBox = queue.shift();
    const resultBox = cutBox(denselyBox);
    if (resultBox.length === 1) {
      isSmallBox = true;
      queue.unshift(resultBox);
      return;
    }
    queue = insertValueInSortedArray(queue, resultBox); // insertion sort by density
  }
  return queue;
}
function cutBox(colorBox) {
  const { colorRange, total, rgbArr } = colorBox;
  const cutSide = colorBox.getCutSide(colorRange);
  if (cutSide === -1) return colorBox; // stop when box is too small
  const colorInCutSide = rgbArr.map(item => item[cutSide]);
  let medianColor = getMedianColor(colorInCutSide, total);
  if (medianColor === colorRange[cutSide][0]) {
    medianColor++;
  }
  const newRange = getCutRange(colorRange, cutSide, medianColor);
  const dividedPixels = dividePixel(rgbArr, cutSide, medianColor);
  return [boxOne, boxTwo];
}
</code>

Octree

The octree recursively divides the RGB space into eight sub‑cubes. Pixels are inserted; when a leaf node exceeds a threshold

N

, its parent is merged to limit memory usage. After all pixels are processed, the

N

leaves with the most pixels provide the dominant colors.

Octree division illustration
Octree division illustration

5. Results

Using Canvas and the described algorithms, theme colors can be extracted in real time on the front end, applied to membership cards for automatic color matching, and used for gradient placeholders during image loading. The following screenshots show the before/after effects on rights and level cards.

Rights card result
Rights card result
Level card result
Level card result

When loading large images, the extracted theme color can be used for a blurred gradient placeholder, improving perceived performance.

Blurred gradient loading effect
Blurred gradient loading effect

6. References

Median‑cut – https://www.jianshu.com/p/a2cc58eba182

Octree – https://sunjiadai.xyz/blog/2019/06/25/OcTree%E5%85%AB%E5%8F%89%E6%A0%91/

Wei‑dong, C., & Wei, D. (2008). An improved median‑cut algorithm of color image quantization. IEEE.

Yamaguchi, K., Kunii, T., Fujimura, K., & Toriya, H. (1984). Octree‑related data structures and algorithms. IEEE Computer Graphics & Applications, 4(1), 53‑59.

Frontendjavascriptimage-processingoctreeColor Extractionmedian cut
Weimob Technology Center
Written by

Weimob Technology Center

Official platform of the Weimob Technology Center

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.