k-centroid-scaler 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +259 -73
- package/k_centroid_scaler.js +187 -5
- package/k_centroid_scaler_bg.wasm +0 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,22 +1,47 @@
|
|
|
1
|
-
# K-Centroid Image Scaler - WebAssembly Module
|
|
1
|
+
# K-Centroid Image Scaler & Color Quantizer - WebAssembly Module
|
|
2
2
|
|
|
3
|
-
A Rust/WebAssembly implementation of the K-Centroid image downscaling algorithm, converted from the original Lua/Aseprite script.
|
|
3
|
+
A Rust/WebAssembly implementation of the K-Centroid image downscaling algorithm and advanced color quantization tools, converted from the original Lua/Aseprite script.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
### 1. K-Centroid Image Scaling
|
|
8
|
+
Intelligent downscaling using K-means clustering on image tiles to preserve important colors.
|
|
9
|
+
|
|
10
|
+
### 2. Color Quantization
|
|
11
|
+
Two high-quality algorithms for reducing color palettes:
|
|
12
|
+
- **Median Cut**: Best quality, ideal for photographs and complex images
|
|
13
|
+
- **K-Means**: Faster processing, great for graphics and illustrations
|
|
6
14
|
|
|
7
|
-
|
|
15
|
+
### 3. Color Analysis with Spatial Sorting
|
|
16
|
+
Advanced color analysis with multiple sorting algorithms:
|
|
17
|
+
- **Z-Order (Morton)**: Groups similar colors using space-filling curves
|
|
18
|
+
- **Hilbert Curve**: Superior locality preservation for color relationships
|
|
19
|
+
- **Hue-based**: Sort by color wheel position
|
|
20
|
+
- **Luminance**: Sort by brightness
|
|
21
|
+
- **Frequency**: Sort by usage percentage
|
|
8
22
|
|
|
23
|
+
### 4. Dominant Color Extraction
|
|
24
|
+
Automatically identifies and quantizes dominant colors with configurable minimum coverage thresholds.
|
|
25
|
+
|
|
26
|
+
### 5. Palette Extraction
|
|
27
|
+
Extract dominant colors from any image for analysis or design purposes.
|
|
28
|
+
|
|
29
|
+
## Algorithm Overview
|
|
30
|
+
|
|
31
|
+
### K-Centroid Scaling
|
|
9
32
|
1. **Tile Division**: The image is divided into tiles based on the target dimensions
|
|
10
33
|
2. **K-Means Clustering**: Each tile undergoes K-means clustering to identify dominant colors
|
|
11
34
|
3. **Color Selection**: The most dominant color (centroid with most pixels) represents each tile
|
|
12
35
|
4. **Downscaling**: Each pixel in the output image uses the dominant color from its corresponding tile
|
|
13
36
|
|
|
14
|
-
|
|
37
|
+
### Color Quantization
|
|
38
|
+
- **Median Cut**: Recursively divides the color space to find optimal palette
|
|
39
|
+
- **K-Means**: Clusters similar colors together for palette reduction
|
|
40
|
+
- **Floyd-Steinberg Dithering**: Optional error diffusion for smoother gradients
|
|
15
41
|
|
|
16
42
|
## Module Interface
|
|
17
43
|
|
|
18
|
-
###
|
|
19
|
-
|
|
44
|
+
### K-Centroid Resize
|
|
20
45
|
```rust
|
|
21
46
|
k_centroid_resize(
|
|
22
47
|
image_data: &[u8], // RGBA image buffer
|
|
@@ -29,110 +54,271 @@ k_centroid_resize(
|
|
|
29
54
|
) -> ImageResult
|
|
30
55
|
```
|
|
31
56
|
|
|
32
|
-
###
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
57
|
+
### Color Quantization (Median Cut)
|
|
58
|
+
```rust
|
|
59
|
+
quantize_colors_median_cut(
|
|
60
|
+
image_data: &[u8], // RGBA image buffer
|
|
61
|
+
width: u32, // Image width
|
|
62
|
+
height: u32, // Image height
|
|
63
|
+
num_colors: u32, // Target color count (2-256)
|
|
64
|
+
dithering: bool, // Apply Floyd-Steinberg dithering
|
|
65
|
+
) -> ImageResult
|
|
40
66
|
```
|
|
41
67
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
68
|
+
### Color Quantization (K-Means)
|
|
69
|
+
```rust
|
|
70
|
+
quantize_colors_kmeans(
|
|
71
|
+
image_data: &[u8], // RGBA image buffer
|
|
72
|
+
width: u32, // Image width
|
|
73
|
+
height: u32, // Image height
|
|
74
|
+
num_colors: u32, // Target color count (2-256)
|
|
75
|
+
iterations: u32, // K-means iterations
|
|
76
|
+
dithering: bool, // Apply Floyd-Steinberg dithering
|
|
77
|
+
) -> ImageResult
|
|
78
|
+
```
|
|
45
79
|
|
|
46
|
-
|
|
47
|
-
|
|
80
|
+
### Palette Extraction
|
|
81
|
+
```rust
|
|
82
|
+
extract_palette(
|
|
83
|
+
image_data: &[u8], // RGBA image buffer
|
|
84
|
+
max_colors: u32, // Maximum colors to extract
|
|
85
|
+
) -> ColorPalette
|
|
86
|
+
```
|
|
48
87
|
|
|
49
|
-
###
|
|
88
|
+
### Color Analysis with Sorting
|
|
89
|
+
```rust
|
|
90
|
+
analyze_colors(
|
|
91
|
+
image_data: &[u8], // RGBA image buffer
|
|
92
|
+
max_colors: u32, // Maximum colors to return (capped at 256)
|
|
93
|
+
sort_method: &str, // Sorting algorithm
|
|
94
|
+
) -> ColorAnalysis
|
|
95
|
+
```
|
|
50
96
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
97
|
+
**Sort Methods:**
|
|
98
|
+
- `"z-order"` or `"morton"`: Space-filling curve for color grouping
|
|
99
|
+
- `"hilbert"`: Hilbert curve for better locality preservation
|
|
100
|
+
- `"hue"`: Sort by hue value (color wheel position)
|
|
101
|
+
- `"luminance"` or `"brightness"`: Sort by perceived brightness
|
|
102
|
+
- `"frequency"`: Sort by usage percentage (most to least common)
|
|
54
103
|
|
|
55
|
-
|
|
56
|
-
|
|
104
|
+
**Return Structure:**
|
|
105
|
+
```javascript
|
|
106
|
+
{
|
|
107
|
+
colors: [{
|
|
108
|
+
hex: string, // "#RRGGBB" format
|
|
109
|
+
percentage: number, // % of image (0-100)
|
|
110
|
+
count: number, // Pixel count
|
|
111
|
+
r: number, // Red (0-255)
|
|
112
|
+
g: number, // Green (0-255)
|
|
113
|
+
b: number // Blue (0-255)
|
|
114
|
+
}],
|
|
115
|
+
totalColors: number, // Unique colors found
|
|
116
|
+
totalPixels: number // Pixels analyzed
|
|
117
|
+
}
|
|
118
|
+
```
|
|
57
119
|
|
|
58
|
-
|
|
59
|
-
|
|
120
|
+
### Dominant Colors with Auto-Quantization
|
|
121
|
+
```rust
|
|
122
|
+
get_dominant_colors(
|
|
123
|
+
image_data: &[u8], // RGBA image buffer
|
|
124
|
+
num_colors: u32, // Target dominant colors
|
|
125
|
+
min_coverage: f32, // Minimum % coverage threshold
|
|
126
|
+
) -> ColorAnalysis
|
|
60
127
|
```
|
|
61
128
|
|
|
62
|
-
## Usage
|
|
129
|
+
## Usage Examples
|
|
63
130
|
|
|
131
|
+
### Basic Color Quantization
|
|
64
132
|
```javascript
|
|
65
|
-
import init, {
|
|
133
|
+
import init, { quantize_colors_median_cut } from './pkg/k_centroid_scaler.js';
|
|
66
134
|
|
|
67
|
-
async function
|
|
68
|
-
// Initialize the WASM module
|
|
135
|
+
async function reduceColors() {
|
|
69
136
|
await init();
|
|
70
137
|
|
|
71
|
-
// Get
|
|
72
|
-
const canvas = document.getElementById('
|
|
138
|
+
// Get image data
|
|
139
|
+
const canvas = document.getElementById('canvas');
|
|
73
140
|
const ctx = canvas.getContext('2d');
|
|
74
141
|
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
75
142
|
|
|
76
|
-
//
|
|
77
|
-
const result =
|
|
143
|
+
// Reduce to 16 colors with dithering
|
|
144
|
+
const result = quantize_colors_median_cut(
|
|
78
145
|
imageData.data,
|
|
79
146
|
canvas.width,
|
|
80
147
|
canvas.height,
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
4, // 4 centroids per tile
|
|
84
|
-
5 // 5 iterations
|
|
148
|
+
16, // 16 colors
|
|
149
|
+
true // Enable dithering
|
|
85
150
|
);
|
|
86
151
|
|
|
87
|
-
//
|
|
152
|
+
// Display result
|
|
88
153
|
const outputImageData = new ImageData(
|
|
89
154
|
new Uint8ClampedArray(result.data),
|
|
90
155
|
result.width,
|
|
91
156
|
result.height
|
|
92
157
|
);
|
|
158
|
+
ctx.putImageData(outputImageData, 0, 0);
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Complete Processing Pipeline
|
|
163
|
+
```javascript
|
|
164
|
+
async function processImage(imageData, width, height) {
|
|
165
|
+
// Step 1: Downscale
|
|
166
|
+
const scaled = await downscaleImage(
|
|
167
|
+
imageData, width, height,
|
|
168
|
+
width / 2, height / 2,
|
|
169
|
+
{ centroids: 4, iterations: 5 }
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
// Step 2: Quantize colors
|
|
173
|
+
const quantized = await quantizeColorsMedianCut(
|
|
174
|
+
scaled.data,
|
|
175
|
+
scaled.width,
|
|
176
|
+
scaled.height,
|
|
177
|
+
{ numColors: 8, dithering: true }
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
return quantized;
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Extract Color Palette
|
|
185
|
+
```javascript
|
|
186
|
+
async function getPalette(imageData) {
|
|
187
|
+
const palette = await extractColorPalette(imageData, 16);
|
|
188
|
+
console.log(`Found ${palette.count} colors:`, palette.colors);
|
|
189
|
+
// Returns array of {r, g, b} objects
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Analyze Colors with Z-Order Sorting
|
|
194
|
+
```javascript
|
|
195
|
+
async function analyzeColors(imageData) {
|
|
196
|
+
const { analyze_colors } = await init();
|
|
197
|
+
|
|
198
|
+
// Get up to 256 colors sorted by Z-order (groups similar colors)
|
|
199
|
+
const analysis = analyze_colors(imageData, 256, 'z-order');
|
|
200
|
+
|
|
201
|
+
// Access color information
|
|
202
|
+
analysis.colors.forEach(color => {
|
|
203
|
+
console.log(`${color.hex}: ${color.percentage.toFixed(2)}% (${color.count} pixels)`);
|
|
204
|
+
});
|
|
93
205
|
|
|
94
|
-
//
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
outputCtx.putImageData(outputImageData, 0, 0);
|
|
206
|
+
// Generate CSS variables
|
|
207
|
+
const cssVars = analysis.colors
|
|
208
|
+
.slice(0, 10) // Top 10 colors
|
|
209
|
+
.map((c, i) => `--color-${i+1}: ${c.hex};`)
|
|
210
|
+
.join('\n');
|
|
100
211
|
}
|
|
101
212
|
```
|
|
102
213
|
|
|
103
|
-
|
|
214
|
+
### Get Dominant Colors
|
|
215
|
+
```javascript
|
|
216
|
+
async function getDominantPalette(imageData) {
|
|
217
|
+
const { get_dominant_colors } = await init();
|
|
218
|
+
|
|
219
|
+
// Get 16 dominant colors, ignoring colors below 0.1% coverage
|
|
220
|
+
const dominant = get_dominant_colors(imageData, 16, 0.1);
|
|
221
|
+
|
|
222
|
+
// Create HTML palette display
|
|
223
|
+
const paletteHTML = dominant.colors
|
|
224
|
+
.map(c => `
|
|
225
|
+
<div style="display: inline-block;">
|
|
226
|
+
<div style="width: 50px; height: 50px; background: ${c.hex};"></div>
|
|
227
|
+
<small>${c.percentage.toFixed(1)}%</small>
|
|
228
|
+
</div>
|
|
229
|
+
`)
|
|
230
|
+
.join('');
|
|
231
|
+
}
|
|
232
|
+
```
|
|
104
233
|
|
|
105
|
-
###
|
|
106
|
-
|
|
107
|
-
|
|
234
|
+
### Export Color Analysis Results
|
|
235
|
+
```javascript
|
|
236
|
+
// Export as JSON
|
|
237
|
+
const colorData = {
|
|
238
|
+
palette: analysis.colors.map(c => ({
|
|
239
|
+
hex: c.hex,
|
|
240
|
+
rgb: [c.r, c.g, c.b],
|
|
241
|
+
usage: c.percentage
|
|
242
|
+
}))
|
|
243
|
+
};
|
|
108
244
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
245
|
+
// Export as CSS custom properties
|
|
246
|
+
const css = `:root {
|
|
247
|
+
${analysis.colors.slice(0, 20).map((c, i) =>
|
|
248
|
+
` --palette-${i}: ${c.hex}; /* ${c.percentage.toFixed(1)}% */`
|
|
249
|
+
).join('\n')}
|
|
250
|
+
}`;
|
|
112
251
|
|
|
113
|
-
|
|
252
|
+
// Export as SCSS/Sass variables
|
|
253
|
+
const scss = analysis.colors.slice(0, 20)
|
|
254
|
+
.map((c, i) => `$color-${i}: ${c.hex};`)
|
|
255
|
+
.join('\n');
|
|
256
|
+
```
|
|
114
257
|
|
|
115
|
-
|
|
116
|
-
2. **Dominant Color Selection**: Always selects the centroid with the most assigned pixels
|
|
117
|
-
3. **Tile Processing**: Each tile is processed independently, maintaining local color characteristics
|
|
118
|
-
4. **Edge Handling**: Properly handles edge tiles that may be smaller than the standard tile size
|
|
258
|
+
## Parameter Guidelines
|
|
119
259
|
|
|
120
|
-
|
|
260
|
+
### Quantization Method Selection
|
|
261
|
+
- **Median Cut**: Use for photographs, natural images, gradients
|
|
262
|
+
- **K-Means**: Use for graphics, logos, illustrations with flat colors
|
|
121
263
|
|
|
122
|
-
|
|
123
|
-
- **
|
|
124
|
-
- **
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
- Optional wasm-opt post-processing
|
|
264
|
+
### `num_colors` (2-256)
|
|
265
|
+
- **2-4**: Extreme stylization, poster effect
|
|
266
|
+
- **8-16**: Retro gaming aesthetic
|
|
267
|
+
- **32-64**: Good balance of quality and compression
|
|
268
|
+
- **128-256**: Near-original quality with reduced file size
|
|
128
269
|
|
|
129
|
-
|
|
270
|
+
### `dithering` (true/false)
|
|
271
|
+
- **Enable**: For smooth gradients and photographs
|
|
272
|
+
- **Disable**: For pixel art or when crisp edges are needed
|
|
130
273
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
274
|
+
### `iterations` (K-Means only, 1-50)
|
|
275
|
+
- **5-10**: Fast processing, good results
|
|
276
|
+
- **20-30**: Better color accuracy
|
|
277
|
+
- **40-50**: Maximum quality, slower processing
|
|
135
278
|
|
|
136
|
-
##
|
|
279
|
+
## Performance Optimizations
|
|
137
280
|
|
|
138
|
-
|
|
281
|
+
### Algorithm Complexity
|
|
282
|
+
- **Median Cut**: O(n log n) where n = unique colors
|
|
283
|
+
- **K-Means**: O(n × k × i) where n = pixels, k = colors, i = iterations
|
|
284
|
+
- **Dithering**: O(w × h) single pass through image
|
|
285
|
+
|
|
286
|
+
### WebAssembly Optimizations
|
|
287
|
+
- K-means++ initialization for better convergence
|
|
288
|
+
- Weighted color averaging based on pixel frequency
|
|
289
|
+
- Efficient color distance calculations
|
|
290
|
+
- Floyd-Steinberg dithering with minimal memory overhead
|
|
291
|
+
|
|
292
|
+
## Build Instructions
|
|
293
|
+
|
|
294
|
+
### Prerequisites
|
|
295
|
+
- Rust toolchain (`curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh`)
|
|
296
|
+
- wasm-pack (`curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh`)
|
|
297
|
+
|
|
298
|
+
### Building
|
|
299
|
+
```bash
|
|
300
|
+
chmod +x build.sh
|
|
301
|
+
./build.sh
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
## Comparison: Quantization Methods
|
|
305
|
+
|
|
306
|
+
| Method | Best For | Speed | Quality | Dithering Support |
|
|
307
|
+
|--------|----------|-------|---------|-------------------|
|
|
308
|
+
| Median Cut | Photos, gradients | Medium | Excellent | Yes |
|
|
309
|
+
| K-Means | Graphics, logos | Fast | Very Good | Yes |
|
|
310
|
+
| K-Centroid Resize | Downscaling | Fast | Good | No |
|
|
311
|
+
|
|
312
|
+
## Advanced Features
|
|
313
|
+
|
|
314
|
+
### Custom Initialization
|
|
315
|
+
The K-means algorithm uses K-means++ initialization for optimal starting centroids, ensuring better convergence and more consistent results.
|
|
316
|
+
|
|
317
|
+
### Weighted Clustering
|
|
318
|
+
Colors are weighted by their frequency in the image, ensuring common colors are better represented in the final palette.
|
|
319
|
+
|
|
320
|
+
### Error Diffusion
|
|
321
|
+
Floyd-Steinberg dithering distributes quantization errors to neighboring pixels, creating smoother gradients with limited colors.
|
|
322
|
+
|
|
323
|
+
## License
|
|
324
|
+
Converted to Rust/WebAssembly for web usage. Original K-Centroid algorithm from Aseprite Lua script.
|
package/k_centroid_scaler.js
CHANGED
|
@@ -200,6 +200,16 @@ function takeObject(idx) {
|
|
|
200
200
|
return ret;
|
|
201
201
|
}
|
|
202
202
|
|
|
203
|
+
function getArrayJsValueFromWasm0(ptr, len) {
|
|
204
|
+
ptr = ptr >>> 0;
|
|
205
|
+
const mem = getDataViewMemory0();
|
|
206
|
+
const result = [];
|
|
207
|
+
for (let i = ptr; i < ptr + 4 * len; i += 4) {
|
|
208
|
+
result.push(takeObject(mem.getUint32(i, true)));
|
|
209
|
+
}
|
|
210
|
+
return result;
|
|
211
|
+
}
|
|
212
|
+
|
|
203
213
|
function passArray8ToWasm0(arg, malloc) {
|
|
204
214
|
const ptr = malloc(arg.length * 1, 1) >>> 0;
|
|
205
215
|
getUint8ArrayMemory0().set(arg, ptr / 1);
|
|
@@ -266,6 +276,34 @@ export function extract_palette(image_data, max_colors) {
|
|
|
266
276
|
return ColorPalette.__wrap(ret);
|
|
267
277
|
}
|
|
268
278
|
|
|
279
|
+
/**
|
|
280
|
+
* @param {Uint8Array} image_data
|
|
281
|
+
* @param {number} max_colors
|
|
282
|
+
* @param {string} sort_method
|
|
283
|
+
* @returns {ColorAnalysis}
|
|
284
|
+
*/
|
|
285
|
+
export function analyze_colors(image_data, max_colors, sort_method) {
|
|
286
|
+
const ptr0 = passArray8ToWasm0(image_data, wasm.__wbindgen_export_1);
|
|
287
|
+
const len0 = WASM_VECTOR_LEN;
|
|
288
|
+
const ptr1 = passStringToWasm0(sort_method, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
|
|
289
|
+
const len1 = WASM_VECTOR_LEN;
|
|
290
|
+
const ret = wasm.analyze_colors(ptr0, len0, max_colors, ptr1, len1);
|
|
291
|
+
return ColorAnalysis.__wrap(ret);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* @param {Uint8Array} image_data
|
|
296
|
+
* @param {number} num_colors
|
|
297
|
+
* @param {number} min_coverage
|
|
298
|
+
* @returns {ColorAnalysis}
|
|
299
|
+
*/
|
|
300
|
+
export function get_dominant_colors(image_data, num_colors, min_coverage) {
|
|
301
|
+
const ptr0 = passArray8ToWasm0(image_data, wasm.__wbindgen_export_1);
|
|
302
|
+
const len0 = WASM_VECTOR_LEN;
|
|
303
|
+
const ret = wasm.get_dominant_colors(ptr0, len0, num_colors, min_coverage);
|
|
304
|
+
return ColorAnalysis.__wrap(ret);
|
|
305
|
+
}
|
|
306
|
+
|
|
269
307
|
/**
|
|
270
308
|
* @param {Uint8Array} data
|
|
271
309
|
* @param {number} width
|
|
@@ -283,6 +321,150 @@ export function process_image(data, width, height, target_width, target_height,
|
|
|
283
321
|
return takeObject(ret);
|
|
284
322
|
}
|
|
285
323
|
|
|
324
|
+
const ColorAnalysisFinalization = (typeof FinalizationRegistry === 'undefined')
|
|
325
|
+
? { register: () => {}, unregister: () => {} }
|
|
326
|
+
: new FinalizationRegistry(ptr => wasm.__wbg_coloranalysis_free(ptr >>> 0, 1));
|
|
327
|
+
|
|
328
|
+
export class ColorAnalysis {
|
|
329
|
+
|
|
330
|
+
static __wrap(ptr) {
|
|
331
|
+
ptr = ptr >>> 0;
|
|
332
|
+
const obj = Object.create(ColorAnalysis.prototype);
|
|
333
|
+
obj.__wbg_ptr = ptr;
|
|
334
|
+
ColorAnalysisFinalization.register(obj, obj.__wbg_ptr, obj);
|
|
335
|
+
return obj;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
__destroy_into_raw() {
|
|
339
|
+
const ptr = this.__wbg_ptr;
|
|
340
|
+
this.__wbg_ptr = 0;
|
|
341
|
+
ColorAnalysisFinalization.unregister(this);
|
|
342
|
+
return ptr;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
free() {
|
|
346
|
+
const ptr = this.__destroy_into_raw();
|
|
347
|
+
wasm.__wbg_coloranalysis_free(ptr, 0);
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* @returns {number}
|
|
351
|
+
*/
|
|
352
|
+
get total_colors() {
|
|
353
|
+
const ret = wasm.__wbg_get_coloranalysis_total_colors(this.__wbg_ptr);
|
|
354
|
+
return ret >>> 0;
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* @param {number} arg0
|
|
358
|
+
*/
|
|
359
|
+
set total_colors(arg0) {
|
|
360
|
+
wasm.__wbg_set_coloranalysis_total_colors(this.__wbg_ptr, arg0);
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* @returns {number}
|
|
364
|
+
*/
|
|
365
|
+
get total_pixels() {
|
|
366
|
+
const ret = wasm.__wbg_get_coloranalysis_total_pixels(this.__wbg_ptr);
|
|
367
|
+
return ret >>> 0;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* @param {number} arg0
|
|
371
|
+
*/
|
|
372
|
+
set total_pixels(arg0) {
|
|
373
|
+
wasm.__wbg_set_coloranalysis_total_pixels(this.__wbg_ptr, arg0);
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* @returns {any[]}
|
|
377
|
+
*/
|
|
378
|
+
get colors() {
|
|
379
|
+
try {
|
|
380
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
381
|
+
wasm.coloranalysis_colors(retptr, this.__wbg_ptr);
|
|
382
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
383
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
384
|
+
var v1 = getArrayJsValueFromWasm0(r0, r1).slice();
|
|
385
|
+
wasm.__wbindgen_export_3(r0, r1 * 4, 4);
|
|
386
|
+
return v1;
|
|
387
|
+
} finally {
|
|
388
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
if (Symbol.dispose) ColorAnalysis.prototype[Symbol.dispose] = ColorAnalysis.prototype.free;
|
|
393
|
+
|
|
394
|
+
const ColorInfoFinalization = (typeof FinalizationRegistry === 'undefined')
|
|
395
|
+
? { register: () => {}, unregister: () => {} }
|
|
396
|
+
: new FinalizationRegistry(ptr => wasm.__wbg_colorinfo_free(ptr >>> 0, 1));
|
|
397
|
+
|
|
398
|
+
export class ColorInfo {
|
|
399
|
+
|
|
400
|
+
__destroy_into_raw() {
|
|
401
|
+
const ptr = this.__wbg_ptr;
|
|
402
|
+
this.__wbg_ptr = 0;
|
|
403
|
+
ColorInfoFinalization.unregister(this);
|
|
404
|
+
return ptr;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
free() {
|
|
408
|
+
const ptr = this.__destroy_into_raw();
|
|
409
|
+
wasm.__wbg_colorinfo_free(ptr, 0);
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* @returns {string}
|
|
413
|
+
*/
|
|
414
|
+
get hex() {
|
|
415
|
+
let deferred1_0;
|
|
416
|
+
let deferred1_1;
|
|
417
|
+
try {
|
|
418
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
419
|
+
wasm.colorinfo_hex(retptr, this.__wbg_ptr);
|
|
420
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
421
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
422
|
+
deferred1_0 = r0;
|
|
423
|
+
deferred1_1 = r1;
|
|
424
|
+
return getStringFromWasm0(r0, r1);
|
|
425
|
+
} finally {
|
|
426
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
427
|
+
wasm.__wbindgen_export_3(deferred1_0, deferred1_1, 1);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* @returns {number}
|
|
432
|
+
*/
|
|
433
|
+
get percentage() {
|
|
434
|
+
const ret = wasm.colorinfo_percentage(this.__wbg_ptr);
|
|
435
|
+
return ret;
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* @returns {number}
|
|
439
|
+
*/
|
|
440
|
+
get count() {
|
|
441
|
+
const ret = wasm.colorinfo_count(this.__wbg_ptr);
|
|
442
|
+
return ret >>> 0;
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* @returns {number}
|
|
446
|
+
*/
|
|
447
|
+
get r() {
|
|
448
|
+
const ret = wasm.colorinfo_r(this.__wbg_ptr);
|
|
449
|
+
return ret;
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* @returns {number}
|
|
453
|
+
*/
|
|
454
|
+
get g() {
|
|
455
|
+
const ret = wasm.colorinfo_g(this.__wbg_ptr);
|
|
456
|
+
return ret;
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* @returns {number}
|
|
460
|
+
*/
|
|
461
|
+
get b() {
|
|
462
|
+
const ret = wasm.colorinfo_b(this.__wbg_ptr);
|
|
463
|
+
return ret;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
if (Symbol.dispose) ColorInfo.prototype[Symbol.dispose] = ColorInfo.prototype.free;
|
|
467
|
+
|
|
286
468
|
const ColorPaletteFinalization = (typeof FinalizationRegistry === 'undefined')
|
|
287
469
|
? { register: () => {}, unregister: () => {} }
|
|
288
470
|
: new FinalizationRegistry(ptr => wasm.__wbg_colorpalette_free(ptr >>> 0, 1));
|
|
@@ -312,7 +494,7 @@ export class ColorPalette {
|
|
|
312
494
|
* @returns {number}
|
|
313
495
|
*/
|
|
314
496
|
get count() {
|
|
315
|
-
const ret = wasm.
|
|
497
|
+
const ret = wasm.__wbg_get_coloranalysis_total_colors(this.__wbg_ptr);
|
|
316
498
|
return ret >>> 0;
|
|
317
499
|
}
|
|
318
500
|
/**
|
|
@@ -369,27 +551,27 @@ export class ImageResult {
|
|
|
369
551
|
* @returns {number}
|
|
370
552
|
*/
|
|
371
553
|
get width() {
|
|
372
|
-
const ret = wasm.
|
|
554
|
+
const ret = wasm.__wbg_get_coloranalysis_total_colors(this.__wbg_ptr);
|
|
373
555
|
return ret >>> 0;
|
|
374
556
|
}
|
|
375
557
|
/**
|
|
376
558
|
* @param {number} arg0
|
|
377
559
|
*/
|
|
378
560
|
set width(arg0) {
|
|
379
|
-
wasm.
|
|
561
|
+
wasm.__wbg_set_coloranalysis_total_colors(this.__wbg_ptr, arg0);
|
|
380
562
|
}
|
|
381
563
|
/**
|
|
382
564
|
* @returns {number}
|
|
383
565
|
*/
|
|
384
566
|
get height() {
|
|
385
|
-
const ret = wasm.
|
|
567
|
+
const ret = wasm.__wbg_get_coloranalysis_total_pixels(this.__wbg_ptr);
|
|
386
568
|
return ret >>> 0;
|
|
387
569
|
}
|
|
388
570
|
/**
|
|
389
571
|
* @param {number} arg0
|
|
390
572
|
*/
|
|
391
573
|
set height(arg0) {
|
|
392
|
-
wasm.
|
|
574
|
+
wasm.__wbg_set_coloranalysis_total_pixels(this.__wbg_ptr, arg0);
|
|
393
575
|
}
|
|
394
576
|
/**
|
|
395
577
|
* @returns {Uint8Array}
|
|
Binary file
|