smart-downscaler 0.3.0 → 0.3.2
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/LICENSE +21 -0
- package/README.md +91 -12
- package/package.json +1 -1
- package/smart_downscaler.d.ts +202 -109
- package/smart_downscaler.js +5 -1
- package/smart_downscaler_bg.js +570 -272
- package/smart_downscaler_bg.wasm +0 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Pixagram
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -4,6 +4,33 @@ A sophisticated Rust library for intelligent image downscaling with focus on pix
|
|
|
4
4
|
|
|
5
5
|
**Available as both a native Rust library and a WebAssembly module for browser/Node.js usage.**
|
|
6
6
|
|
|
7
|
+
## What's New in v0.3
|
|
8
|
+
|
|
9
|
+
### ⚡ Performance Optimizations
|
|
10
|
+
|
|
11
|
+
Version 0.3 introduces **preprocessing optimizations** for large images, providing 2-10x speedup while maintaining 80%+ visual quality:
|
|
12
|
+
|
|
13
|
+
| Feature | Default | Description |
|
|
14
|
+
|---------|---------|-------------|
|
|
15
|
+
| `max_resolution_mp` | 1.5 | Cap input at 1.5 megapixels (0 = disabled) |
|
|
16
|
+
| `max_color_preprocess` | 16384 | Pre-quantize to 16K unique colors max (0 = disabled) |
|
|
17
|
+
|
|
18
|
+
```javascript
|
|
19
|
+
const config = new WasmDownscaleConfig();
|
|
20
|
+
config.max_resolution_mp = 1.5; // Cap at 1.5 megapixels (0 = disabled)
|
|
21
|
+
config.max_color_preprocess = 16384; // Pre-quantize to 16K colors (0 = disabled)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Optimization Strategies
|
|
25
|
+
|
|
26
|
+
1. **Resolution Capping**: Images larger than `max_resolution_mp` are downscaled using fast nearest-neighbor interpolation before processing. Images are only downsized, never upscaled.
|
|
27
|
+
|
|
28
|
+
2. **Color Pre-Quantization**: Images with more than `max_color_preprocess` unique colors are pre-quantized using fast bit-truncation (RGB555/RGB444) with weighted averaging.
|
|
29
|
+
|
|
30
|
+
3. **Integer Edge Detection**: Uses integer arithmetic for edge detection on preprocessed images for ~2x faster edge computation.
|
|
31
|
+
|
|
32
|
+
4. **Optimized Tile Processing**: Reduced allocations and stack-allocated arrays for small palettes (≤64 colors).
|
|
33
|
+
|
|
7
34
|
## What's New in v0.2
|
|
8
35
|
|
|
9
36
|
### 🎨 Oklab Color Space
|
|
@@ -45,6 +72,7 @@ config.palette_strategy = 'saturation'; // For vibrant pixel art
|
|
|
45
72
|
- **Neighbor-Coherent Assignment**: Spatial coherence through neighbor and region voting
|
|
46
73
|
- **Two-Pass Refinement**: Iterative optimization for smooth results
|
|
47
74
|
- **WebAssembly Support**: Run in browsers with full performance
|
|
75
|
+
- **Performance Preprocessing**: Resolution capping and color pre-quantization
|
|
48
76
|
|
|
49
77
|
## Installation
|
|
50
78
|
|
|
@@ -54,7 +82,7 @@ Add to your `Cargo.toml`:
|
|
|
54
82
|
|
|
55
83
|
```toml
|
|
56
84
|
[dependencies]
|
|
57
|
-
smart-downscaler = "0.
|
|
85
|
+
smart-downscaler = "0.3"
|
|
58
86
|
```
|
|
59
87
|
|
|
60
88
|
### WebAssembly (npm)
|
|
@@ -87,10 +115,12 @@ fn main() {
|
|
|
87
115
|
let result = downscale(&img, 64, 64, 16);
|
|
88
116
|
result.save("output.png").unwrap();
|
|
89
117
|
|
|
90
|
-
// Advanced: preserve vibrant colors
|
|
118
|
+
// Advanced: preserve vibrant colors with preprocessing
|
|
91
119
|
let config = DownscaleConfig {
|
|
92
120
|
palette_size: 24,
|
|
93
121
|
palette_strategy: PaletteStrategy::SaturationWeighted,
|
|
122
|
+
max_resolution_mp: 1.5, // Performance: cap at 1.5MP
|
|
123
|
+
max_color_preprocess: 16384, // Performance: pre-quantize colors
|
|
94
124
|
..Default::default()
|
|
95
125
|
};
|
|
96
126
|
|
|
@@ -113,11 +143,17 @@ const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
|
113
143
|
const config = WasmDownscaleConfig.vibrant();
|
|
114
144
|
config.palette_size = 16;
|
|
115
145
|
|
|
146
|
+
// Performance settings (already set in presets)
|
|
147
|
+
config.max_resolution_mp = 1.5;
|
|
148
|
+
config.max_color_preprocess = 16384;
|
|
149
|
+
|
|
116
150
|
// Or configure manually
|
|
117
151
|
const config2 = new WasmDownscaleConfig();
|
|
118
152
|
config2.palette_size = 16;
|
|
119
153
|
config2.palette_strategy = 'saturation';
|
|
120
154
|
config2.neighbor_weight = 0.3;
|
|
155
|
+
config2.max_resolution_mp = 1.5;
|
|
156
|
+
config2.max_color_preprocess = 16384;
|
|
121
157
|
|
|
122
158
|
const result = downscale_rgba(
|
|
123
159
|
imageData.data,
|
|
@@ -134,13 +170,13 @@ outputCtx.putImageData(outputData, 0, 0);
|
|
|
134
170
|
### Configuration Presets
|
|
135
171
|
|
|
136
172
|
```javascript
|
|
137
|
-
// Speed optimized
|
|
173
|
+
// Speed optimized (max_resolution_mp: 1.0, max_color_preprocess: 8192)
|
|
138
174
|
const fast = WasmDownscaleConfig.fast();
|
|
139
175
|
|
|
140
|
-
// Best quality
|
|
176
|
+
// Best quality (max_resolution_mp: 2.0, max_color_preprocess: 32768)
|
|
141
177
|
const quality = WasmDownscaleConfig.quality();
|
|
142
178
|
|
|
143
|
-
// Preserve vibrant colors
|
|
179
|
+
// Preserve vibrant colors (max_resolution_mp: 1.5, max_color_preprocess: 16384)
|
|
144
180
|
const vibrant = WasmDownscaleConfig.vibrant();
|
|
145
181
|
|
|
146
182
|
// Use only exact source colors
|
|
@@ -169,7 +205,7 @@ Oklab is a **perceptually uniform** color space where:
|
|
|
169
205
|
|
|
170
206
|
```
|
|
171
207
|
Red (Oklab) + Cyan (Oklab)
|
|
172
|
-
Oklab Average → Preserves colorfulness
|
|
208
|
+
Oklab Average → Preserves colorfulness ✔
|
|
173
209
|
```
|
|
174
210
|
|
|
175
211
|
### Visual Comparison
|
|
@@ -206,6 +242,10 @@ config.edge_weight = 0.5;
|
|
|
206
242
|
|
|
207
243
|
// Segmentation
|
|
208
244
|
config.segmentation_method = 'hierarchy_fast'; // 'none', 'slic', 'hierarchy', 'hierarchy_fast'
|
|
245
|
+
|
|
246
|
+
// Performance preprocessing
|
|
247
|
+
config.max_resolution_mp = 1.5; // Cap resolution at 1.5 megapixels (0 = disabled)
|
|
248
|
+
config.max_color_preprocess = 16384; // Pre-quantize to 16K colors max (0 = disabled)
|
|
209
249
|
```
|
|
210
250
|
|
|
211
251
|
### Available Functions
|
|
@@ -255,6 +295,20 @@ smart-downscaler input.png output.png \
|
|
|
255
295
|
|
|
256
296
|
## Algorithm Details
|
|
257
297
|
|
|
298
|
+
### 0. Preprocessing (v0.3)
|
|
299
|
+
|
|
300
|
+
Before main processing, large images are optimized:
|
|
301
|
+
|
|
302
|
+
1. **Resolution Capping**: If pixels > `max_resolution_mp × 1,000,000`:
|
|
303
|
+
- Scale factor = sqrt(max_resolution_mp / current_mp)
|
|
304
|
+
- Downscale using nearest-neighbor interpolation
|
|
305
|
+
- Only downsizes (never upscales)
|
|
306
|
+
|
|
307
|
+
2. **Color Pre-Quantization**: If unique colors > `max_color_preprocess`:
|
|
308
|
+
- Build hash-based color histogram
|
|
309
|
+
- Apply bit truncation (RGB555 or RGB444)
|
|
310
|
+
- Map colors to weighted bucket averages
|
|
311
|
+
|
|
258
312
|
### 1. Palette Extraction (Oklab Median Cut)
|
|
259
313
|
|
|
260
314
|
1. Convert all pixels to Oklab color space
|
|
@@ -300,13 +354,16 @@ score(color) = oklab_distance(color, tile_avg) × (1 - neighbor_bias - region_bi
|
|
|
300
354
|
|
|
301
355
|
## Performance
|
|
302
356
|
|
|
303
|
-
Typical performance (single-threaded):
|
|
357
|
+
Typical performance (single-threaded, with preprocessing enabled):
|
|
358
|
+
|
|
359
|
+
| Image Size | Target Size | Palette | Time (v0.3) | Time (v0.2) |
|
|
360
|
+
|------------|-------------|---------|-------------|-------------|
|
|
361
|
+
| 256×256 | 32×32 | 16 | ~40ms | ~50ms |
|
|
362
|
+
| 512×512 | 64×64 | 32 | ~150ms | ~200ms |
|
|
363
|
+
| 1024×1024 | 128×128 | 32 | ~400ms | ~800ms |
|
|
364
|
+
| 2048×2048 | 256×256 | 32 | ~600ms | ~3200ms |
|
|
304
365
|
|
|
305
|
-
|
|
306
|
-
|------------|-------------|---------|------|
|
|
307
|
-
| 256×256 | 32×32 | 16 | ~50ms |
|
|
308
|
-
| 512×512 | 64×64 | 32 | ~200ms |
|
|
309
|
-
| 1024×1024 | 128×128 | 32 | ~800ms |
|
|
366
|
+
**Note**: Performance improvements are most significant for large images (>1MP) due to resolution capping.
|
|
310
367
|
|
|
311
368
|
Enable `parallel` feature for multi-threaded processing.
|
|
312
369
|
|
|
@@ -325,6 +382,8 @@ Enable `parallel` feature for multi-threaded processing.
|
|
|
325
382
|
| `refinement_iterations` | usize | 3 | Max iterations |
|
|
326
383
|
| `segmentation` | SegmentationMethod | Hierarchy | Pre-segmentation |
|
|
327
384
|
| `edge_weight` | f32 | 0.5 | Edge influence |
|
|
385
|
+
| `max_resolution_mp` | f32 | 1.5 | Max megapixels before downscale (0 = disabled) |
|
|
386
|
+
| `max_color_preprocess` | usize | 16384 | Max unique colors before quantize (0 = disabled) |
|
|
328
387
|
|
|
329
388
|
### PaletteStrategy
|
|
330
389
|
|
|
@@ -362,6 +421,26 @@ config.neighbor_weight = 0.5; // Up from 0.3
|
|
|
362
421
|
config.two_pass_refinement = true;
|
|
363
422
|
```
|
|
364
423
|
|
|
424
|
+
### Processing too slow for large images
|
|
425
|
+
|
|
426
|
+
Reduce preprocessing limits:
|
|
427
|
+
```javascript
|
|
428
|
+
config.max_resolution_mp = 1.0; // Aggressive cap
|
|
429
|
+
config.max_color_preprocess = 8192; // Fewer colors
|
|
430
|
+
// Or use the 'fast' preset
|
|
431
|
+
const config = WasmDownscaleConfig.fast();
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
### Want maximum quality (ignore performance)
|
|
435
|
+
|
|
436
|
+
Disable preprocessing by setting limits to 0:
|
|
437
|
+
```javascript
|
|
438
|
+
config.max_resolution_mp = 0; // Disable resolution capping
|
|
439
|
+
config.max_color_preprocess = 0; // Disable color pre-quantization
|
|
440
|
+
// Or use the 'quality' preset which has higher limits
|
|
441
|
+
const config = WasmDownscaleConfig.quality();
|
|
442
|
+
```
|
|
443
|
+
|
|
365
444
|
## License
|
|
366
445
|
|
|
367
446
|
MIT
|
package/package.json
CHANGED
package/smart_downscaler.d.ts
CHANGED
|
@@ -1,121 +1,194 @@
|
|
|
1
1
|
/* tslint:disable */
|
|
2
2
|
/* eslint-disable */
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Result of color analysis
|
|
6
|
+
*/
|
|
7
|
+
export class ColorAnalysisResult {
|
|
8
|
+
private constructor();
|
|
9
|
+
free(): void;
|
|
10
|
+
[Symbol.dispose](): void;
|
|
11
|
+
/**
|
|
12
|
+
* Get color at index
|
|
13
|
+
*/
|
|
14
|
+
get_color(index: number): ColorEntry | undefined;
|
|
15
|
+
/**
|
|
16
|
+
* Get all colors as a flat array: [r, g, b, count(4 bytes), percentage(4 bytes), ...]
|
|
17
|
+
* Each color is 11 bytes
|
|
18
|
+
*/
|
|
19
|
+
get_colors_flat(): Uint8Array;
|
|
20
|
+
/**
|
|
21
|
+
* Get colors as JSON-compatible array
|
|
22
|
+
*/
|
|
23
|
+
to_json(): any;
|
|
24
|
+
readonly color_count: number;
|
|
25
|
+
readonly success: boolean;
|
|
26
|
+
readonly total_pixels: number;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* A single color entry with statistics
|
|
31
|
+
*/
|
|
32
|
+
export class ColorEntry {
|
|
33
|
+
private constructor();
|
|
34
|
+
free(): void;
|
|
35
|
+
[Symbol.dispose](): void;
|
|
36
|
+
readonly b: number;
|
|
37
|
+
readonly count: number;
|
|
38
|
+
readonly g: number;
|
|
39
|
+
readonly hex: string;
|
|
40
|
+
readonly percentage: number;
|
|
41
|
+
readonly r: number;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Configuration options for the downscaler (JavaScript-compatible)
|
|
46
|
+
*/
|
|
4
47
|
export class WasmDownscaleConfig {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
48
|
+
free(): void;
|
|
49
|
+
[Symbol.dispose](): void;
|
|
50
|
+
/**
|
|
51
|
+
* Create configuration that uses only exact image colors (medoid)
|
|
52
|
+
*/
|
|
53
|
+
static exact_colors(): WasmDownscaleConfig;
|
|
54
|
+
/**
|
|
55
|
+
* Create configuration optimized for speed
|
|
56
|
+
*/
|
|
57
|
+
static fast(): WasmDownscaleConfig;
|
|
58
|
+
/**
|
|
59
|
+
* Create a new configuration with default values
|
|
60
|
+
*/
|
|
61
|
+
constructor();
|
|
62
|
+
/**
|
|
63
|
+
* Create configuration optimized for quality
|
|
64
|
+
*/
|
|
65
|
+
static quality(): WasmDownscaleConfig;
|
|
66
|
+
/**
|
|
67
|
+
* Create configuration optimized for vibrant colors
|
|
68
|
+
*/
|
|
69
|
+
static vibrant(): WasmDownscaleConfig;
|
|
70
|
+
/**
|
|
71
|
+
* Edge weight in tile color computation (default: 0.5)
|
|
72
|
+
*/
|
|
73
|
+
edge_weight: number;
|
|
74
|
+
/**
|
|
75
|
+
* For hierarchy: minimum region size (default: 4)
|
|
76
|
+
*/
|
|
77
|
+
hierarchy_min_size: number;
|
|
78
|
+
/**
|
|
79
|
+
* For hierarchy: merge threshold (default: 15.0)
|
|
80
|
+
*/
|
|
81
|
+
hierarchy_threshold: number;
|
|
82
|
+
/**
|
|
83
|
+
* K-Means iterations for palette refinement (default: 5)
|
|
84
|
+
*/
|
|
85
|
+
kmeans_iterations: number;
|
|
86
|
+
/**
|
|
87
|
+
* Maximum unique colors for preprocessing (default: 16384, 0 = disabled)
|
|
88
|
+
*/
|
|
89
|
+
max_color_preprocess: number;
|
|
90
|
+
/**
|
|
91
|
+
* Maximum resolution in megapixels for preprocessing (default: 1.5, 0 = disabled)
|
|
92
|
+
*/
|
|
93
|
+
max_resolution_mp: number;
|
|
94
|
+
/**
|
|
95
|
+
* Weight for neighbor color coherence [0.0, 1.0] (default: 0.3)
|
|
96
|
+
*/
|
|
97
|
+
neighbor_weight: number;
|
|
98
|
+
/**
|
|
99
|
+
* Number of colors in the output palette (default: 16)
|
|
100
|
+
*/
|
|
101
|
+
palette_size: number;
|
|
102
|
+
/**
|
|
103
|
+
* Maximum refinement iterations (default: 3)
|
|
104
|
+
*/
|
|
105
|
+
refinement_iterations: number;
|
|
106
|
+
/**
|
|
107
|
+
* Weight for region membership coherence [0.0, 1.0] (default: 0.2)
|
|
108
|
+
*/
|
|
109
|
+
region_weight: number;
|
|
110
|
+
/**
|
|
111
|
+
* For SLIC: compactness factor (default: 10.0)
|
|
112
|
+
*/
|
|
113
|
+
slic_compactness: number;
|
|
114
|
+
/**
|
|
115
|
+
* For SLIC: approximate number of superpixels (default: 100)
|
|
116
|
+
*/
|
|
117
|
+
slic_superpixels: number;
|
|
118
|
+
/**
|
|
119
|
+
* Enable two-pass refinement (default: true)
|
|
120
|
+
*/
|
|
121
|
+
two_pass_refinement: boolean;
|
|
122
|
+
/**
|
|
123
|
+
* Get the palette extraction strategy
|
|
124
|
+
*/
|
|
125
|
+
palette_strategy: string;
|
|
126
|
+
/**
|
|
127
|
+
* Get the segmentation method
|
|
128
|
+
*/
|
|
129
|
+
segmentation_method: string;
|
|
79
130
|
}
|
|
80
131
|
|
|
132
|
+
/**
|
|
133
|
+
* Result of downscaling operation
|
|
134
|
+
*/
|
|
81
135
|
export class WasmDownscaleResult {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
136
|
+
private constructor();
|
|
137
|
+
free(): void;
|
|
138
|
+
[Symbol.dispose](): void;
|
|
139
|
+
/**
|
|
140
|
+
* Get palette color at index as [r, g, b]
|
|
141
|
+
*/
|
|
142
|
+
get_palette_color(index: number): Uint8Array;
|
|
143
|
+
/**
|
|
144
|
+
* Get RGB pixel data as Uint8Array (without alpha)
|
|
145
|
+
*/
|
|
146
|
+
rgb_data(): Uint8Array;
|
|
147
|
+
/**
|
|
148
|
+
* Get RGBA pixel data as Uint8ClampedArray (for ImageData)
|
|
149
|
+
*/
|
|
150
|
+
readonly data: Uint8ClampedArray;
|
|
151
|
+
/**
|
|
152
|
+
* Get output height
|
|
153
|
+
*/
|
|
154
|
+
readonly height: number;
|
|
155
|
+
/**
|
|
156
|
+
* Get palette indices for each pixel
|
|
157
|
+
*/
|
|
158
|
+
readonly indices: Uint8Array;
|
|
159
|
+
/**
|
|
160
|
+
* Get palette as Uint8Array (RGB, 3 bytes per color)
|
|
161
|
+
*/
|
|
162
|
+
readonly palette: Uint8Array;
|
|
163
|
+
/**
|
|
164
|
+
* Get number of colors in palette
|
|
165
|
+
*/
|
|
166
|
+
readonly palette_size: number;
|
|
167
|
+
/**
|
|
168
|
+
* Get output width
|
|
169
|
+
*/
|
|
170
|
+
readonly width: number;
|
|
117
171
|
}
|
|
118
172
|
|
|
173
|
+
/**
|
|
174
|
+
* Analyze colors in an image
|
|
175
|
+
*
|
|
176
|
+
* # Arguments
|
|
177
|
+
* * `image_data` - RGBA pixel data
|
|
178
|
+
* * `max_colors` - Maximum number of unique colors to track (stops if exceeded)
|
|
179
|
+
* * `sort_method` - Sorting method: "frequency", "morton", or "hilbert"
|
|
180
|
+
*
|
|
181
|
+
* # Returns
|
|
182
|
+
* ColorAnalysisResult with array of colors (r, g, b, count, percentage, hex)
|
|
183
|
+
* If unique colors exceed max_colors, returns early with success=false
|
|
184
|
+
*/
|
|
185
|
+
export function analyze_colors(image_data: Uint8Array, max_colors: number, sort_method: string): ColorAnalysisResult;
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Compute perceptual color distance between two RGB colors
|
|
189
|
+
*/
|
|
190
|
+
export function color_distance(r1: number, g1: number, b1: number, r2: number, g2: number, b2: number): number;
|
|
191
|
+
|
|
119
192
|
/**
|
|
120
193
|
* Main downscaling function for WebAssembly
|
|
121
194
|
*
|
|
@@ -152,6 +225,16 @@ export function downscale_with_palette(image_data: Uint8Array, width: number, he
|
|
|
152
225
|
*/
|
|
153
226
|
export function extract_palette_from_image(image_data: Uint8Array, _width: number, _height: number, num_colors: number, kmeans_iterations: number, strategy?: string | null): Uint8Array;
|
|
154
227
|
|
|
228
|
+
/**
|
|
229
|
+
* Get chroma (saturation) of an RGB color
|
|
230
|
+
*/
|
|
231
|
+
export function get_chroma(r: number, g: number, b: number): number;
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Get lightness of an RGB color in Oklab space
|
|
235
|
+
*/
|
|
236
|
+
export function get_lightness(r: number, g: number, b: number): number;
|
|
237
|
+
|
|
155
238
|
/**
|
|
156
239
|
* Get available palette strategies
|
|
157
240
|
*/
|
|
@@ -167,11 +250,21 @@ export function init(): void;
|
|
|
167
250
|
*/
|
|
168
251
|
export function log(message: string): void;
|
|
169
252
|
|
|
253
|
+
/**
|
|
254
|
+
* Convert Oklab to RGB (utility function for JS)
|
|
255
|
+
*/
|
|
256
|
+
export function oklab_to_rgb(l: number, a: number, b: number): Uint8Array;
|
|
257
|
+
|
|
170
258
|
/**
|
|
171
259
|
* Quantize an image to a specific palette without resizing
|
|
172
260
|
*/
|
|
173
261
|
export function quantize_to_palette(image_data: Uint8Array, width: number, height: number, palette_data: Uint8Array): WasmDownscaleResult;
|
|
174
262
|
|
|
263
|
+
/**
|
|
264
|
+
* Convert RGB to Oklab (utility function for JS)
|
|
265
|
+
*/
|
|
266
|
+
export function rgb_to_oklab(r: number, g: number, b: number): Float32Array;
|
|
267
|
+
|
|
175
268
|
/**
|
|
176
269
|
* Get library version
|
|
177
270
|
*/
|
package/smart_downscaler.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
/* @ts-self-types="./smart_downscaler.d.ts" */
|
|
2
|
+
|
|
1
3
|
import * as wasm from "./smart_downscaler_bg.wasm";
|
|
2
|
-
export * from "./smart_downscaler_bg.js";
|
|
3
4
|
import { __wbg_set_wasm } from "./smart_downscaler_bg.js";
|
|
4
5
|
__wbg_set_wasm(wasm);
|
|
5
6
|
wasm.__wbindgen_start();
|
|
7
|
+
export {
|
|
8
|
+
ColorAnalysisResult, ColorEntry, WasmDownscaleConfig, WasmDownscaleResult, analyze_colors, color_distance, downscale, downscale_rgba, downscale_simple, downscale_with_palette, extract_palette_from_image, get_chroma, get_lightness, get_palette_strategies, init, log, oklab_to_rgb, quantize_to_palette, rgb_to_oklab, version
|
|
9
|
+
} from "./smart_downscaler_bg.js";
|