smart-downscaler 0.4.2 β†’ 0.4.4

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 CHANGED
@@ -4,6 +4,27 @@ 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
+
8
+ ## What's New in v0.3.5
9
+
10
+ ### ⚑ Performance: Direct LUT Optimization
11
+
12
+ The preprocessing pipeline has been completely rewritten for speed:
13
+
14
+ | Old Method (v0.3) | New Method (v0.3.5) | Improvement |
15
+ | ------------------------------ | --------------------- | --------------------- |
16
+ | HashMap Pre-quantization | **Direct LUT (64MB)** | O(1) Access |
17
+ | Oklab Conversion on All Pixels | **Cached Oklab** | \~100x Fewer Math Ops |
18
+ | Iterative Resolution Cap | **One-pass NN** | Instant Resizing |
19
+
20
+ **Key Optimizations:**
21
+
22
+ 1. **Direct Lookup Table**: Uses a 64MB flat array to map 24-bit RGB colors to unique indices instantly. No hashing overhead.
23
+
24
+ 2. **RGBA-Only Preprocessing**: Resolution capping and quantization now happen strictly in RGBA space before any expensive Oklab math.
25
+
26
+ 3. **Oklab Caching**: If color reduction is enabled (default), Oklab conversion is only performed once per unique color, not per pixel.
27
+
7
28
  <!---->
8
29
 
9
30
  const config = new WasmDownscaleConfig();
@@ -240,98 +261,4 @@ MIT
240
261
  - K-Means++ initialization
241
262
 
242
263
  - VTracer hierarchical clustering approach
243
- Smart Pixel Art DownscalerA sophisticated Rust library for intelligent image downscaling with focus on pixel art quality.Available as both a native Rust library and a WebAssembly module for browser/Node.js usage.What's New in v0.4.0🐞 Critical Fix: Large Image StabilityFixed an integer overflow issue that caused large images (typically > 0.5MP) to render as a solid brown/dark color. The accumulation pipeline now uses 64-bit integers for correctness while preserving the speed of the fixed-point arithmetic.⚑ Performance: Direct LUT OptimizationThe preprocessing pipeline has been completely rewritten for speed:Old Method (v0.3)New Method (v0.4.0)ImprovementHashMap Pre-quantizationDirect LUT (64MB)O(1) AccessOklab Conversion on All PixelsCached Oklab~100x Fewer Math OpsIterative Resolution CapOne-pass NNInstant ResizingKey Optimizations:Direct Lookup Table: Uses a 64MB flat array to map 24-bit RGB colors to unique indices instantly. No hashing overhead.RGBA-Only Preprocessing: Resolution capping and quantization now happen strictly in RGBA space before any expensive Oklab math.Oklab Caching: If color reduction is enabled (default), Oklab conversion is only performed once per unique color, not per pixel.<!---->const config = new WasmDownscaleConfig();
244
- config.max_resolution_mp = 1.5; // Fast nearest-neighbor cap
245
- config.max_color_preprocess = 16384; // Direct LUT quantization
246
- 🎯 K-Centroid Tile LogicNew k_centroid configuration allows finer control over how a source tile is reduced to a single representative color before matching:ModeNameDescriptionBest For1AverageSimple average of all pixels (Default)Smooth gradients, noise reduction2DominantAverage of the largest color cluster ($k=2$)Sharp edges, separating foreground/background3ForemostAverage of the "foremost" distinct part ($k=3$)Complex textures, detailed sprites// Example: Use dominant part for sharper edges
247
- config.k_centroid = 2;
248
- config.k_centroid_iterations = 2;
249
- Configuration ReferenceDownscaleConfigFieldTypeDefaultDescriptionk_centroidusize11=Avg, 2=Dominant, 3=Foremostk_centroid_iterationsusize0Refinement for tile colormax_resolution_mpf321.6Resolution cap (0=disabled)max_color_preprocessusize16384LUT Quantization limitsegmentationMethodHierarchyRegion detection methodCommand Line Interface# Enable Dominant Color mode (sharper details)
250
- smart-downscaler input.png output.png --k-centroid 2 --k-centroid-iterations 2
251
-
252
- # Fast mode (reduce preprocessing limits)
253
- smart-downscaler input.png output.png --segmentation none --no-refinement
254
- FeaturesOklab Color Space: Modern perceptual color space with superior hue linearityGlobal Palette Extraction: Median Cut + K-Means++ refinementMultiple Segmentation Methods:SLIC superpixels for fast, balanced regionsVTracer-style hierarchical clustering for content-aware boundariesUnion-find based fast hierarchical clusteringEdge-Aware Processing: Sobel/Scharr edge detection to preserve boundariesNeighbor-Coherent Assignment: Spatial coherence through neighbor and region votingTwo-Pass Refinement: Iterative optimization for smooth resultsWebAssembly Support: Run in browsers with full performancePerformance Preprocessing: Resolution capping and color pre-quantizationInstallationNative (Rust)Add to your Cargo.toml:[dependencies]
255
- smart-downscaler = "0.4.0"
256
- WebAssembly (npm)npm install smart-downscaler
257
- Quick StartWebAssembly (Browser)import init, { WasmDownscaleConfig, downscale_rgba } from 'smart-downscaler';
258
-
259
- await init();
260
-
261
- // Create config
262
- const config = new WasmDownscaleConfig();
263
-
264
- // PERFORMANCE: New Direct LUT settings
265
- config.max_resolution_mp = 1.5; // Nearest-neighbor cap (0 = disabled)
266
- config.max_color_preprocess = 16384; // Trigger LUT path if < 16k colors
267
-
268
- // QUALITY: New K-Centroid settings
269
- config.k_centroid = 2; // 2 = Dominant Color Mode
270
- config.k_centroid_iterations = 2; // Refine the dominant color
271
-
272
- // Standard settings
273
- config.palette_size = 16;
274
- config.palette_strategy = 'oklab';
275
-
276
- // Run
277
- const result = downscale_rgba(
278
- imageData.data,
279
- imageData.width, imageData.height,
280
- 64, 64, // Target size
281
- config
282
- );
283
-
284
- // Draw result
285
- const output = new ImageData(result.data, result.width, result.height);
286
- ctx.putImageData(output, 0, 0);
287
- Configuration Presets// Speed optimized (max_resolution_mp: 1.0, max_color_preprocess: 8192)
288
- const fast = WasmDownscaleConfig.fast();
289
-
290
- // Best quality (max_resolution_mp: 2.0, max_color_preprocess: 32768)
291
- const quality = WasmDownscaleConfig.quality();
292
-
293
- // Preserve vibrant colors (max_resolution_mp: 1.5, max_color_preprocess: 16384)
294
- const vibrant = WasmDownscaleConfig.vibrant();
295
-
296
- // Use only exact source colors
297
- const exact = WasmDownscaleConfig.exact_colors();
298
- Why Oklab?Traditional RGB-based palette extraction has fundamental problems:The Problem: RGB Averaging Desaturates ColorsRed [255, 0, 0] + Cyan [0, 255, 255]
299
- RGB Average β†’ Gray [127, 127, 127] ❌
300
- When you average colors in RGB space, saturated colors get pulled toward gray. This is why downscaled images often look "washed out" or "tanned."The Solution: Oklab Color SpaceOklab is a perceptually uniform color space where:Euclidean distance = perceived color differenceAveraging preserves hue and saturationInterpolations look natural<!---->Red (Oklab) + Cyan (Oklab)
301
- Oklab Average β†’ Preserves colorfulness βœ”
302
- API ReferenceWasmDownscaleConfigconst config = new WasmDownscaleConfig();
303
-
304
- // Palette settings
305
- config.palette_size = 16; // Number of output colors
306
- config.palette_strategy = 'oklab'; // 'oklab', 'saturation', 'medoid', 'kmeans', 'legacy'
307
- config.kmeans_iterations = 5; // Refinement iterations
308
-
309
- // Spatial coherence
310
- config.neighbor_weight = 0.3; // [0-1] Prefer neighbor colors
311
- config.region_weight = 0.2; // [0-1] Prefer region colors
312
-
313
- // Refinement
314
- config.two_pass_refinement = true;
315
- config.refinement_iterations = 3;
316
-
317
- // Edge detection
318
- config.edge_weight = 0.5;
319
-
320
- // Segmentation
321
- config.segmentation_method = 'hierarchy_fast'; // 'none', 'slic', 'hierarchy', 'hierarchy_fast'
322
-
323
- // Performance preprocessing
324
- config.max_resolution_mp = 1.5; // Cap resolution at 1.5 megapixels (0 = disabled)
325
- config.max_color_preprocess = 16384; // Pre-quantize to 16K colors max (0 = disabled)
326
-
327
- // Tile Logic
328
- config.k_centroid = 1; // 1=Avg, 2=Dom, 3=Foremost
329
- config.k_centroid_iterations = 0; // Refine the dominant color
330
- Available FunctionsFunctionDescriptiondownscale(data, w, h, tw, th, config?)Main downscale functiondownscale_rgba(data, w, h, tw, th, config?)For Uint8ClampedArray inputdownscale_simple(data, w, h, tw, th, colors)Simple APIdownscale_with_palette(...)Use custom paletteextract_palette_from_image(data, w, h, colors, iters, strategy?)Extract palette onlyquantize_to_palette(data, w, h, palette)Quantize without resizingget_palette_strategies()List available strategiesWasmDownscaleResultresult.width // Output width
331
- result.height // Output height
332
- result.data // Uint8ClampedArray (RGBA)
333
- result.rgb_data() // Uint8Array (RGB only)
334
- result.palette // Uint8Array (RGB, 3 bytes per color)
335
- result.indices // Uint8Array (palette index per pixel)
336
- result.palette_size // Number of colors
337
- LicenseMITCreditsOklab color space by BjΓΆrn OttossonSLIC superpixel algorithmK-Means++ initializationVTracer hierarchical clustering approach
264
+
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "Pixagram"
6
6
  ],
7
7
  "description": "Intelligent pixel art downscaler with region-aware color quantization",
8
- "version": "0.4.2",
8
+ "version": "0.4.4",
9
9
  "license": "MIT",
10
10
  "repository": {
11
11
  "type": "git",
Binary file