pixel-data-js 0.11.1 → 0.12.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.
@@ -653,34 +653,69 @@ declare function writeImageDataPixels(imageData: ImageData, data: Uint8ClampedAr
653
653
  declare function writeImageDataPixels(imageData: ImageData, data: Uint8ClampedArray, x: number, y: number, w: number, h: number): void;
654
654
 
655
655
  /**
656
- * Compressed data format for image processing optimization.
657
- * Representing an image as a grid of palette indices rather than raw RGBA values
658
- * significantly reduces memory overhead and optimizes pattern matching logic.
656
+ * Writes image data from a source to a target with support for clipping and alpha masking.
657
+ *
658
+ * @param target - The destination ImageData to write to.
659
+ * @param source - The source ImageData to read from.
660
+ * @param x - The x-coordinate in the target where drawing starts.
661
+ * @param y - The y-coordinate in the target where drawing starts.
662
+ * @param sx - The x-coordinate in the source to start copying from.
663
+ * @param sy - The y-coordinate in the source to start copying from.
664
+ * @param sw - The width of the rectangle to copy.
665
+ * @param sh - The height of the rectangle to copy.
666
+ * @param mask - An optional Uint8Array mask (0-255). 0 is transparent, 255 is opaque.
667
+ * @param maskType - type of mask
668
+ */
669
+ declare function writeImageData(target: ImageData, source: ImageData, x: number, y: number, sx?: number, sy?: number, sw?: number, sh?: number, mask?: Uint8Array | null, maskType?: MaskType): void;
670
+
671
+ /**
672
+ * Represents an image using a palette-based indexing system.
673
+ * Instead of storing 4 bytes (RGBA) per pixel, this class stores a single index
674
+ * into a color palette. This format is optimized for memory efficiency and
675
+ * high-speed pattern matching or recoloring operations.
659
676
  */
660
- type IndexedImage = {
677
+ declare class IndexedImage {
661
678
  /** The width of the image in pixels. */
662
- width: number;
679
+ readonly width: number;
663
680
  /** The height of the image in pixels. */
664
- height: number;
681
+ readonly height: number;
682
+ /** Flat array of palette indices. Index = x + (y * width). */
683
+ readonly data: Int32Array;
684
+ /** The palette of unique 32-bit colors (ABGR/RGBA packed) found in the image. */
685
+ readonly palette: Uint32Array;
686
+ /** The specific index in the palette reserved for fully transparent pixels. */
687
+ readonly transparentPalletIndex: number;
665
688
  /**
666
- * A flat array of indices where each value points to a color in the palette.
667
- * Accessible via the formula: `index = x + (y * width)`.
689
+ * @param width - Image width.
690
+ * @param height - Image height.
691
+ * @param data - The indexed pixel data.
692
+ * @param palette - The array of packed colors.
693
+ * @param transparentPalletIndex - The index representing alpha 0.
668
694
  */
669
- data: Int32Array;
695
+ constructor(width: number, height: number, data: Int32Array, palette: Uint32Array, transparentPalletIndex: number);
670
696
  /**
671
- * A palette of packed 32-bit colors (ABGR).
697
+ * Creates an IndexedImage from standard browser ImageData.
698
+ * @param imageData - The source ImageData to convert.
699
+ * @returns A new IndexedImage instance.
672
700
  */
673
- palette: Uint32Array;
701
+ static fromImageData(imageData: ImageData): IndexedImage;
674
702
  /**
675
- * The specific index in the palette that represents a fully transparent pixel.
703
+ * Creates an IndexedImage from a raw byte buffer and dimensions.
704
+ * Any pixel with an alpha channel of 0 is normalized to the transparent palette index.
705
+ * @param data - Raw RGBA byte data.
706
+ * @param width - Image width.
707
+ * @param height - Image height.
708
+ * @returns A new IndexedImage instance.
676
709
  */
677
- transparentPalletIndex: number;
678
- };
679
- /**
680
- * Converts standard ImageData into an IndexedImage format.
681
- */
682
- declare function makeIndexedImage(imageData: ImageData): IndexedImage;
683
- declare function makeIndexedImage(data: Uint8ClampedArray, width: number, height: number): IndexedImage;
710
+ static fromRaw(data: Uint8ClampedArray, width: number, height: number): IndexedImage;
711
+ /**
712
+ * Retrieves the 32-bit packed color value at the given coordinates.
713
+ * @param x - X coordinate.
714
+ * @param y - Y coordinate.
715
+ * @returns The packed color from the palette.
716
+ */
717
+ getColorAt(x: number, y: number): Color32;
718
+ }
684
719
 
685
720
  /**
686
721
  * Calculates the frequency of each palette index based on the image data.
@@ -710,6 +745,11 @@ declare function indexedImageToAverageColor(indexedImage: IndexedImage, includeT
710
745
  */
711
746
  declare function resampleIndexedImage(source: IndexedImage, factor: number): IndexedImage;
712
747
 
748
+ /**
749
+ * Converts an IndexedImage back into standard ImageData.
750
+ */
751
+ declare function indexedImageToImageData(indexedImage: IndexedImage): ImageData;
752
+
713
753
  /**
714
754
  * A convenience wrapper that extracts the first {@link File} from an
715
755
  * {@link HTMLInputElement} change event and converts it into {@link ImageData}.
@@ -937,4 +977,4 @@ declare function rotatePixelData(pixelData: PixelData): void;
937
977
  */
938
978
  declare function trimRectBounds<T extends Rect | SelectionRect>(target: T, bounds: Rect): void;
939
979
 
940
- export { type AlphaMask, type AnyMask, type ApplyMaskOptions, type Base64EncodedUInt8Array, type BinaryMask, type BlendColor32, BlendMode, type BlendModeIndex, type BlendToIndexGetter, type Color32, type ColorBlendOptions, FAST_BLENDER_REGISTRY, FAST_BLEND_MODES, FAST_BLEND_MODE_BY_NAME, FAST_BLEND_TO_INDEX, type FastBlendModes, type FloodFillImageDataOptions, type FloodFillResult, INDEX_TO_FAST_BLEND, INDEX_TO_PERFECT_BLEND, type ImageDataLike, type IndexToBlendGetter, type IndexedImage, MaskType, PERFECT_BLENDER_REGISTRY, PERFECT_BLEND_MODES, PERFECT_BLEND_MODE_BY_NAME, PERFECT_BLEND_TO_INDEX, type PerfectBlendModes, type PixelBlendOptions, type PixelCanvas, PixelData, type PixelOptions, type Point, type RGBA, type Rect, type RegisteredFastBlender, type RegisteredPerfectBlender, type ReusableCanvas, type SelectionRect, type SerializedImageData, UnsupportedFormatError, applyMaskToPixelData, base64DecodeArrayBuffer, base64EncodeArrayBuffer, blendColorPixelData, blendPixelData, clearPixelData, color32ToCssRGBA, color32ToHex, colorBurnFast, colorBurnPerfect, colorDistance, colorDodgeFast, colorDodgePerfect, copyImageData, copyImageDataLike, copyMask, darkenFast, darkenPerfect, darkerFast, darkerPerfect, deserializeImageData, deserializeNullableImageData, deserializeRawImageData, differenceFast, differencePerfect, divideFast, dividePerfect, exclusionFast, exclusionPerfect, extractImageDataPixels, extractMask, fileInputChangeToImageData, fileToImageData, fillPixelData, floodFillSelection, getImageDataFromClipboard, getIndexedImageColorCounts, getSupportedPixelFormats, hardLightFast, hardLightPerfect, hardMixFast, hardMixPerfect, imageDataToAlphaMask, imageDataToDataUrl, imageDataToImgBlob, imgBlobToImageData, indexedImageToAverageColor, invertAlphaMask, invertBinaryMask, invertImageData, invertPixelData, lerpColor32, lerpColor32Fast, lightenFast, lightenPerfect, lighterFast, lighterPerfect, linearBurnFast, linearBurnPerfect, linearDodgeFast, linearDodgePerfect, linearLightFast, linearLightPerfect, makeIndexedImage, makePixelCanvas, makeReusableCanvas, mergeMasks, multiplyFast, multiplyPerfect, overlayFast, overlayPerfect, overwriteFast, overwritePerfect, packColor, packRGBA, pinLightFast, pinLightPerfect, pixelDataToAlphaMask, reflectPixelDataHorizontal, reflectPixelDataVertical, resampleImageData, resampleIndexedImage, resamplePixelData, resizeImageData, rotatePixelData, screenFast, screenPerfect, serializeImageData, serializeNullableImageData, softLightFast, softLightPerfect, sourceOverFast, sourceOverPerfect, subtractFast, subtractPerfect, trimRectBounds, unpackAlpha, unpackBlue, unpackColor, unpackColorTo, unpackGreen, unpackRed, vividLightFast, vividLightPerfect, writeImageDataPixels, writeImageDataToClipboard, writeImgBlobToClipboard };
980
+ export { type AlphaMask, type AnyMask, type ApplyMaskOptions, type Base64EncodedUInt8Array, type BinaryMask, type BlendColor32, BlendMode, type BlendModeIndex, type BlendToIndexGetter, type Color32, type ColorBlendOptions, FAST_BLENDER_REGISTRY, FAST_BLEND_MODES, FAST_BLEND_MODE_BY_NAME, FAST_BLEND_TO_INDEX, type FastBlendModes, type FloodFillImageDataOptions, type FloodFillResult, INDEX_TO_FAST_BLEND, INDEX_TO_PERFECT_BLEND, type ImageDataLike, type IndexToBlendGetter, IndexedImage, MaskType, PERFECT_BLENDER_REGISTRY, PERFECT_BLEND_MODES, PERFECT_BLEND_MODE_BY_NAME, PERFECT_BLEND_TO_INDEX, type PerfectBlendModes, type PixelBlendOptions, type PixelCanvas, PixelData, type PixelOptions, type Point, type RGBA, type Rect, type RegisteredFastBlender, type RegisteredPerfectBlender, type ReusableCanvas, type SelectionRect, type SerializedImageData, UnsupportedFormatError, applyMaskToPixelData, base64DecodeArrayBuffer, base64EncodeArrayBuffer, blendColorPixelData, blendPixelData, clearPixelData, color32ToCssRGBA, color32ToHex, colorBurnFast, colorBurnPerfect, colorDistance, colorDodgeFast, colorDodgePerfect, copyImageData, copyImageDataLike, copyMask, darkenFast, darkenPerfect, darkerFast, darkerPerfect, deserializeImageData, deserializeNullableImageData, deserializeRawImageData, differenceFast, differencePerfect, divideFast, dividePerfect, exclusionFast, exclusionPerfect, extractImageDataPixels, extractMask, fileInputChangeToImageData, fileToImageData, fillPixelData, floodFillSelection, getImageDataFromClipboard, getIndexedImageColorCounts, getSupportedPixelFormats, hardLightFast, hardLightPerfect, hardMixFast, hardMixPerfect, imageDataToAlphaMask, imageDataToDataUrl, imageDataToImgBlob, imgBlobToImageData, indexedImageToAverageColor, indexedImageToImageData, invertAlphaMask, invertBinaryMask, invertImageData, invertPixelData, lerpColor32, lerpColor32Fast, lightenFast, lightenPerfect, lighterFast, lighterPerfect, linearBurnFast, linearBurnPerfect, linearDodgeFast, linearDodgePerfect, linearLightFast, linearLightPerfect, makePixelCanvas, makeReusableCanvas, mergeMasks, multiplyFast, multiplyPerfect, overlayFast, overlayPerfect, overwriteFast, overwritePerfect, packColor, packRGBA, pinLightFast, pinLightPerfect, pixelDataToAlphaMask, reflectPixelDataHorizontal, reflectPixelDataVertical, resampleImageData, resampleIndexedImage, resamplePixelData, resizeImageData, rotatePixelData, screenFast, screenPerfect, serializeImageData, serializeNullableImageData, softLightFast, softLightPerfect, sourceOverFast, sourceOverPerfect, subtractFast, subtractPerfect, trimRectBounds, unpackAlpha, unpackBlue, unpackColor, unpackColorTo, unpackGreen, unpackRed, vividLightFast, vividLightPerfect, writeImageData, writeImageDataPixels, writeImageDataToClipboard, writeImgBlobToClipboard };
@@ -1625,40 +1625,144 @@ function writeImageDataPixels(imageData, data, _x, _y, _w, _h) {
1625
1625
  }
1626
1626
  }
1627
1627
 
1628
- // src/IndexedImage/IndexedImage.ts
1629
- function makeIndexedImage(imageOrData, width, height) {
1630
- const isImageData = "width" in imageOrData;
1631
- const actualWidth = isImageData ? imageOrData.width : width;
1632
- const actualHeight = isImageData ? imageOrData.height : height;
1633
- const buffer = isImageData ? imageOrData.data.buffer : imageOrData.buffer;
1634
- const rawData = new Uint32Array(buffer);
1635
- const indexedData = new Int32Array(rawData.length);
1636
- const colorMap = /* @__PURE__ */ new Map();
1637
- const transparentColor = 0;
1638
- const transparentPalletIndex = 0;
1639
- colorMap.set(transparentColor, transparentPalletIndex);
1640
- for (let i = 0; i < rawData.length; i++) {
1641
- const pixel = rawData[i];
1642
- const alpha = pixel >>> 24 & 255;
1643
- const isTransparent = alpha === 0;
1644
- const colorKey = isTransparent ? transparentColor : pixel >>> 0;
1645
- let id = colorMap.get(colorKey);
1646
- if (id === void 0) {
1647
- id = colorMap.size;
1648
- colorMap.set(colorKey, id);
1628
+ // src/ImageData/writeImageData.ts
1629
+ function writeImageData(target, source, x, y, sx = 0, sy = 0, sw = source.width, sh = source.height, mask = null, maskType = 1 /* BINARY */) {
1630
+ const dstW = target.width;
1631
+ const dstH = target.height;
1632
+ const dstData = target.data;
1633
+ const srcW = source.width;
1634
+ const srcData = source.data;
1635
+ const x0 = Math.max(0, x);
1636
+ const y0 = Math.max(0, y);
1637
+ const x1 = Math.min(dstW, x + sw);
1638
+ const y1 = Math.min(dstH, y + sh);
1639
+ if (x1 <= x0 || y1 <= y0) {
1640
+ return;
1641
+ }
1642
+ const useMask = !!mask;
1643
+ const rowCount = y1 - y0;
1644
+ const rowLenPixels = x1 - x0;
1645
+ for (let row = 0; row < rowCount; row++) {
1646
+ const dstY = y0 + row;
1647
+ const srcY = sy + (dstY - y);
1648
+ const srcXBase = sx + (x0 - x);
1649
+ const dstStart = (dstY * dstW + x0) * 4;
1650
+ const srcStart = (srcY * srcW + srcXBase) * 4;
1651
+ if (useMask && mask) {
1652
+ for (let ix = 0; ix < rowLenPixels; ix++) {
1653
+ const mi = srcY * srcW + (srcXBase + ix);
1654
+ const alpha = mask[mi];
1655
+ if (alpha === 0) {
1656
+ continue;
1657
+ }
1658
+ const di = dstStart + ix * 4;
1659
+ const si = srcStart + ix * 4;
1660
+ if (maskType === 1 /* BINARY */ || alpha === 255) {
1661
+ dstData[di] = srcData[si];
1662
+ dstData[di + 1] = srcData[si + 1];
1663
+ dstData[di + 2] = srcData[si + 2];
1664
+ dstData[di + 3] = srcData[si + 3];
1665
+ } else {
1666
+ const a = alpha / 255;
1667
+ const invA = 1 - a;
1668
+ dstData[di] = srcData[si] * a + dstData[di] * invA;
1669
+ dstData[di + 1] = srcData[si + 1] * a + dstData[di + 1] * invA;
1670
+ dstData[di + 2] = srcData[si + 2] * a + dstData[di + 2] * invA;
1671
+ dstData[di + 3] = srcData[si + 3] * a + dstData[di + 3] * invA;
1672
+ }
1673
+ }
1674
+ } else {
1675
+ const byteLen = rowLenPixels * 4;
1676
+ const sub = srcData.subarray(srcStart, srcStart + byteLen);
1677
+ dstData.set(sub, dstStart);
1649
1678
  }
1650
- indexedData[i] = id;
1651
1679
  }
1652
- const palette = Uint32Array.from(colorMap.keys());
1653
- return {
1654
- width: actualWidth,
1655
- height: actualHeight,
1656
- data: indexedData,
1657
- transparentPalletIndex,
1658
- palette
1659
- };
1660
1680
  }
1661
1681
 
1682
+ // src/IndexedImage/IndexedImage.ts
1683
+ var IndexedImage = class _IndexedImage {
1684
+ /** The width of the image in pixels. */
1685
+ width;
1686
+ /** The height of the image in pixels. */
1687
+ height;
1688
+ /** Flat array of palette indices. Index = x + (y * width). */
1689
+ data;
1690
+ /** The palette of unique 32-bit colors (ABGR/RGBA packed) found in the image. */
1691
+ palette;
1692
+ /** The specific index in the palette reserved for fully transparent pixels. */
1693
+ transparentPalletIndex;
1694
+ /**
1695
+ * @param width - Image width.
1696
+ * @param height - Image height.
1697
+ * @param data - The indexed pixel data.
1698
+ * @param palette - The array of packed colors.
1699
+ * @param transparentPalletIndex - The index representing alpha 0.
1700
+ */
1701
+ constructor(width, height, data, palette, transparentPalletIndex) {
1702
+ this.width = width;
1703
+ this.height = height;
1704
+ this.data = data;
1705
+ this.palette = palette;
1706
+ this.transparentPalletIndex = transparentPalletIndex;
1707
+ }
1708
+ /**
1709
+ * Creates an IndexedImage from standard browser ImageData.
1710
+ * @param imageData - The source ImageData to convert.
1711
+ * @returns A new IndexedImage instance.
1712
+ */
1713
+ static fromImageData(imageData) {
1714
+ return _IndexedImage.fromRaw(imageData.data, imageData.width, imageData.height);
1715
+ }
1716
+ /**
1717
+ * Creates an IndexedImage from a raw byte buffer and dimensions.
1718
+ * Any pixel with an alpha channel of 0 is normalized to the transparent palette index.
1719
+ * @param data - Raw RGBA byte data.
1720
+ * @param width - Image width.
1721
+ * @param height - Image height.
1722
+ * @returns A new IndexedImage instance.
1723
+ */
1724
+ static fromRaw(data, width, height) {
1725
+ const buffer = data.buffer;
1726
+ const rawData = new Uint32Array(buffer);
1727
+ const indexedData = new Int32Array(rawData.length);
1728
+ const colorMap = /* @__PURE__ */ new Map();
1729
+ const transparentColor = 0;
1730
+ const transparentPalletIndex = 0;
1731
+ colorMap.set(transparentColor, transparentPalletIndex);
1732
+ for (let i = 0; i < rawData.length; i++) {
1733
+ const pixel = rawData[i];
1734
+ const alpha = pixel >>> 24 & 255;
1735
+ const isTransparent = alpha === 0;
1736
+ const colorKey = isTransparent ? transparentColor : pixel >>> 0;
1737
+ let id = colorMap.get(colorKey);
1738
+ if (id === void 0) {
1739
+ id = colorMap.size;
1740
+ colorMap.set(colorKey, id);
1741
+ }
1742
+ indexedData[i] = id;
1743
+ }
1744
+ const palette = Uint32Array.from(colorMap.keys());
1745
+ return new _IndexedImage(
1746
+ width,
1747
+ height,
1748
+ indexedData,
1749
+ palette,
1750
+ transparentPalletIndex
1751
+ );
1752
+ }
1753
+ /**
1754
+ * Retrieves the 32-bit packed color value at the given coordinates.
1755
+ * @param x - X coordinate.
1756
+ * @param y - Y coordinate.
1757
+ * @returns The packed color from the palette.
1758
+ */
1759
+ getColorAt(x, y) {
1760
+ const index = x + y * this.width;
1761
+ const paletteIndex = this.data[index];
1762
+ return this.palette[paletteIndex];
1763
+ }
1764
+ };
1765
+
1662
1766
  // src/IndexedImage/getIndexedImageColorCounts.ts
1663
1767
  function getIndexedImageColorCounts(indexedImage) {
1664
1768
  const data = indexedImage.data;
@@ -1721,13 +1825,26 @@ function resampleIndexedImage(source, factor) {
1721
1825
  source.height,
1722
1826
  factor
1723
1827
  );
1724
- return {
1828
+ return new IndexedImage(
1725
1829
  width,
1726
1830
  height,
1727
1831
  data,
1728
- palette: source.palette,
1729
- transparentPalletIndex: source.transparentPalletIndex
1730
- };
1832
+ source.palette,
1833
+ source.transparentPalletIndex
1834
+ );
1835
+ }
1836
+
1837
+ // src/IndexedImage/indexedImageToImageData.ts
1838
+ function indexedImageToImageData(indexedImage) {
1839
+ const { width, height, data, palette } = indexedImage;
1840
+ const result = new ImageData(width, height);
1841
+ const data32 = new Uint32Array(result.data.buffer);
1842
+ for (let i = 0; i < data.length; i++) {
1843
+ const paletteIndex = data[i];
1844
+ const color = palette[paletteIndex];
1845
+ data32[i] = color;
1846
+ }
1847
+ return result;
1731
1848
  }
1732
1849
 
1733
1850
  // src/Input/fileInputChangeToImageData.ts
@@ -2414,6 +2531,7 @@ export {
2414
2531
  FAST_BLEND_TO_INDEX,
2415
2532
  INDEX_TO_FAST_BLEND,
2416
2533
  INDEX_TO_PERFECT_BLEND,
2534
+ IndexedImage,
2417
2535
  MaskType,
2418
2536
  PERFECT_BLENDER_REGISTRY,
2419
2537
  PERFECT_BLEND_MODES,
@@ -2468,6 +2586,7 @@ export {
2468
2586
  imageDataToImgBlob,
2469
2587
  imgBlobToImageData,
2470
2588
  indexedImageToAverageColor,
2589
+ indexedImageToImageData,
2471
2590
  invertAlphaMask,
2472
2591
  invertBinaryMask,
2473
2592
  invertImageData,
@@ -2484,7 +2603,6 @@ export {
2484
2603
  linearDodgePerfect,
2485
2604
  linearLightFast,
2486
2605
  linearLightPerfect,
2487
- makeIndexedImage,
2488
2606
  makePixelCanvas,
2489
2607
  makeReusableCanvas,
2490
2608
  mergeMasks,
@@ -2525,6 +2643,7 @@ export {
2525
2643
  unpackRed,
2526
2644
  vividLightFast,
2527
2645
  vividLightPerfect,
2646
+ writeImageData,
2528
2647
  writeImageDataPixels,
2529
2648
  writeImageDataToClipboard,
2530
2649
  writeImgBlobToClipboard