npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ts-color-quantize

v0.0.4

Published

A js module for color quantization, based on Leptonica.

Downloads

282

Readme

color-quantize

Node.js module for color quantization, based on Leptonica. This library references quantize and uses typescript implementation.

原理

近似色算法

  1. 根据所有像素点 rgb 信息获取 redMax, redMin, greenMax, greenMin, blueMax, blueMin 色彩空间信息
  2. 色彩空间信息可以被划分为 n 份
  3. n 份色彩空间可以获取该空间的平均色(n 个近似色)

实际上一张图片的颜色我们可以看作一张三维坐标系,其三轴从常规的 x, y, z 变为 r, g, b 。 由此,令: length = redMax - redMin width = greenMax - greenMin height = blueMax - blueMin 那么色彩空间体(vbox)是一个 length * width * height 的长方体,该色彩空间的平均颜色即是:色彩空间内所有像素 r,g,b 分别之和除以像素数量[redSum / pixelCount, greenSum / pixelCount, blueSum / pixelCount]。同时,若需要对该空间进行垂直切割可以将height 分为height1height2,那么: vbox = length * width * height = length * width * height1 + length * width * height2 = vbox1 + vbox2

若需要 n 个近似色只需要

  1. 按照一定的策略分割 [vbox] 为 [vbox1, vbox2]
  2. 选出其中最大的 vboxn 继续分割为 [vbox1, vbox2 ..., vboxn] 直到数组长度为 n
  3. 单独计算每一个 vbox 中的平均色即可

一维化像素压缩算法

一个图像标准的像素信息往往是这样的 pixels = [...[r, g, b]],第一维数组顺序记录了像素点的位置信息,第二维数组记录了 r, g, b 三色的信息。那么在获取颜色的压缩中完全可以:

  1. 去除掉位置信息
  2. Array 表示的[r, g, b]降格以 Number 表示

由此,将 pixels = [...[r, g, b]]二维表示的像素数组压缩为一维 histo = [...num],其中 num 表示该颜色像素的数量。

rgb 每个颜色都是由 8 位表示(2 的 8 次方即 256),若需要完整的用一维数组表示所有 rgb 的值,就需要 256 * 256 * 256 长度的 histo 数组,实际上这里是求取色彩空间,histo 就不需要完整的用每个下标表示单个 rgb 颜色,而是表示一定范围内的色彩,这里我们就让 histo 表达32 * 32 * 32长度的色彩范围,计算量可谓真正意义上的几何倍率的降低。

即 rgb 精确表示一个具体的颜色色值: [00000000, 00000000, 00000000](rgb 各 8 位) 而 色彩范围 表示一部分相似的颜色色值: [00000, 00000, 00000](rgb 各 5 位)

由此,histo 是一个 1 << (3 * 5) 长度的数组,每个下标代表一部分范围的色彩空间,该处下标的值记录符合该范围色值的像素点个数,例如:

yellowgreen: [154, 205, 50]

应该属于色彩范围

colorbox: [19, 25, 6]

转换方式:让每个色值除以 8(即右移 3 位),比如这里的 yellowgreen,实际上 red 色值 152 ~ 159 都属于 red 色彩空间 19。

显而易见,histo 的下标二进制表达为00000 00000 00000,前 5 位表示红色空间,中间 5 位绿色空间,最后 5 位蓝色空间,具体实现:

  1. r, g, b 三色分别右移 3 位,匹配压缩后的色彩范围值
const rval = r >> 3;
const gval = g >> 3;
const bval = b >> 3;
  1. 遍历像素的 rgb,获取对应色彩范围后,根据色彩范围更新色彩范围数组
// const histo = new Array(1 << 3 * 5)
const index = (rval << (2 * 5)) + (gval << 5) + bval;
histo[index]++;

实际上 色彩空间位数大小(5) 和 色彩空间精细度(3) 就是原像素信息色彩位数(8)的和,满足这个条件也可以根据需求设置64 * 64 * 64等不同大小的色彩空间

实现

有了 近似色算法 和 一维化像素压缩算法 后可以稍加思索推论出 quantize 的实现:

  1. 根据所有像素点 rgb 压缩为色彩范围,并生成 histo 和 原 vbox

    概括的来说 histo 用于表示色彩空间内的具体的色彩的像素数量 vbox 用于表示色彩空间的范围

  2. 根据目标近似色数量进行分割 vbox ,分割时找到 vbox 最长边,基于 histo 计算空间像素密度找到该边的分割位置,将 vbox “拦腰切断”
  3. 重复切割完所有 vbox 并获取其平均色后,逆压缩算法得出该 vbox 真实的 rgb 平均色

Install

npm install color-quantize

Quick Overview

Usage

import { quantize } from "./quantize";

const arrayOfPixels = [
  [190, 197, 190],
  [202, 204, 200],
  [207, 214, 210],
  [211, 214, 211],
  [205, 207, 207],
];
const maximumColorCount = 10;

const colorMap = quantize(arrayOfPixels, maximumColorCount);
  • arrayOfPixels - An array of pixels (represented as [R,G,B arrays]) to quantize
  • maxiumColorCount - The maximum number of colours allowed in the reduced palette
Reduced Palette

The .palette() method returns an array that contains the reduced color palette.

// Returns the reduced palette
colorMap.palette();
// [[204, 204, 204], [208,212,212], [188,196,188], [212,204,196]]
Reduced pixel

The .map(pixel) method maps an individual pixel to the reduced color palette.

// Returns the reduced pixel
colorMap.map(arrayOfPixels[0]);
// [188,196,188]