pixel-data-js 0.12.0 → 0.14.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/dist/index.dev.cjs +105 -67
- package/dist/index.dev.cjs.map +1 -1
- package/dist/index.dev.js +103 -67
- package/dist/index.dev.js.map +1 -1
- package/dist/index.prod.cjs +105 -67
- package/dist/index.prod.cjs.map +1 -1
- package/dist/index.prod.d.ts +48 -27
- package/dist/index.prod.js +103 -67
- package/dist/index.prod.js.map +1 -1
- package/package.json +2 -1
- package/src/BlendModes/blend-modes-fast.ts +2 -2
- package/src/BlendModes/blend-modes-perfect.ts +2 -2
- package/src/BlendModes/blend-modes.ts +4 -0
- package/src/ImageData/ReusableImageData.ts +33 -0
- package/src/ImageData/imageDataToUInt32Array.ts +13 -0
- package/src/ImageData/resizeImageData.ts +4 -2
- package/src/PixelData/PixelData.ts +36 -23
- package/src/PixelData/blendColorPixelData.ts +15 -23
- package/src/PixelData/blendPixelData.ts +8 -4
- package/src/PixelData/resamplePixelData.ts +3 -3
- package/src/PixelData/rotatePixelData.ts +13 -7
- package/src/_types.ts +5 -3
- package/src/index.ts +3 -1
package/dist/index.dev.cjs
CHANGED
|
@@ -80,6 +80,7 @@ __export(src_exports, {
|
|
|
80
80
|
imageDataToAlphaMask: () => imageDataToAlphaMask,
|
|
81
81
|
imageDataToDataUrl: () => imageDataToDataUrl,
|
|
82
82
|
imageDataToImgBlob: () => imageDataToImgBlob,
|
|
83
|
+
imageDataToUInt32Array: () => imageDataToUInt32Array,
|
|
83
84
|
imgBlobToImageData: () => imgBlobToImageData,
|
|
84
85
|
indexedImageToAverageColor: () => indexedImageToAverageColor,
|
|
85
86
|
indexedImageToImageData: () => indexedImageToImageData,
|
|
@@ -101,6 +102,7 @@ __export(src_exports, {
|
|
|
101
102
|
linearLightPerfect: () => linearLightPerfect,
|
|
102
103
|
makePixelCanvas: () => makePixelCanvas,
|
|
103
104
|
makeReusableCanvas: () => makeReusableCanvas,
|
|
105
|
+
makeReusableImageData: () => makeReusableImageData,
|
|
104
106
|
mergeMasks: () => mergeMasks,
|
|
105
107
|
multiplyFast: () => multiplyFast,
|
|
106
108
|
multiplyPerfect: () => multiplyPerfect,
|
|
@@ -173,9 +175,11 @@ var BlendMode = /* @__PURE__ */ ((BlendMode2) => {
|
|
|
173
175
|
BlendMode2[BlendMode2["divide"] = 22] = "divide";
|
|
174
176
|
return BlendMode2;
|
|
175
177
|
})(BlendMode || {});
|
|
178
|
+
var overwriteBase = (src, _dst) => src;
|
|
179
|
+
overwriteBase.isOverwrite = true;
|
|
176
180
|
|
|
177
181
|
// src/BlendModes/blend-modes-fast.ts
|
|
178
|
-
var overwriteFast =
|
|
182
|
+
var overwriteFast = overwriteBase;
|
|
179
183
|
var sourceOverFast = (src, dst) => {
|
|
180
184
|
const sa = src >>> 24 & 255;
|
|
181
185
|
if (sa === 255) return src;
|
|
@@ -990,7 +994,7 @@ function floodFillSelection(img, startX, startY, {
|
|
|
990
994
|
}
|
|
991
995
|
|
|
992
996
|
// src/BlendModes/blend-modes-perfect.ts
|
|
993
|
-
var overwritePerfect =
|
|
997
|
+
var overwritePerfect = overwriteBase;
|
|
994
998
|
var sourceOverPerfect = (src, dst) => {
|
|
995
999
|
const sa = src >>> 24 & 255;
|
|
996
1000
|
if (sa === 255) return src;
|
|
@@ -1573,6 +1577,22 @@ async function writeImageDataToClipboard(imageData) {
|
|
|
1573
1577
|
return writeImgBlobToClipboard(blob);
|
|
1574
1578
|
}
|
|
1575
1579
|
|
|
1580
|
+
// src/ImageData/ReusableImageData.ts
|
|
1581
|
+
function makeReusableImageData() {
|
|
1582
|
+
let imageData = null;
|
|
1583
|
+
let buffer = null;
|
|
1584
|
+
return function getReusableImageData(width, height) {
|
|
1585
|
+
const hasInstance = !!imageData;
|
|
1586
|
+
const widthMatches = hasInstance && imageData.width === width;
|
|
1587
|
+
const heightMatches = hasInstance && imageData.height === height;
|
|
1588
|
+
if (!widthMatches || !heightMatches) {
|
|
1589
|
+
const buffer2 = new Uint8ClampedArray(width * height * 4);
|
|
1590
|
+
imageData = new ImageData(buffer2, width, height);
|
|
1591
|
+
}
|
|
1592
|
+
return imageData;
|
|
1593
|
+
};
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1576
1596
|
// src/ImageData/copyImageData.ts
|
|
1577
1597
|
function copyImageData({ data, width, height }) {
|
|
1578
1598
|
return new ImageData(data.slice(), width, height);
|
|
@@ -1631,6 +1651,16 @@ function imageDataToDataUrl(imageData) {
|
|
|
1631
1651
|
}
|
|
1632
1652
|
imageDataToDataUrl.reset = get.reset;
|
|
1633
1653
|
|
|
1654
|
+
// src/ImageData/imageDataToUInt32Array.ts
|
|
1655
|
+
function imageDataToUInt32Array(imageData) {
|
|
1656
|
+
return new Uint32Array(
|
|
1657
|
+
imageData.data.buffer,
|
|
1658
|
+
imageData.data.byteOffset,
|
|
1659
|
+
// Shift right by 2 is a fast bitwise division by 4.
|
|
1660
|
+
imageData.data.byteLength >> 2
|
|
1661
|
+
);
|
|
1662
|
+
}
|
|
1663
|
+
|
|
1634
1664
|
// src/ImageData/invertImageData.ts
|
|
1635
1665
|
function invertImageData(imageData) {
|
|
1636
1666
|
const data = imageData.data;
|
|
@@ -1752,27 +1782,6 @@ function deserializeNullableImageData(serialized) {
|
|
|
1752
1782
|
return deserializeImageData(serialized);
|
|
1753
1783
|
}
|
|
1754
1784
|
|
|
1755
|
-
// src/ImageData/writeImageDataPixels.ts
|
|
1756
|
-
function writeImageDataPixels(imageData, data, _x, _y, _w, _h) {
|
|
1757
|
-
const { x, y, w, h } = typeof _x === "object" ? _x : { x: _x, y: _y, w: _w, h: _h };
|
|
1758
|
-
const { width: dstW, height: dstH, data: dst } = imageData;
|
|
1759
|
-
const x0 = Math.max(0, x);
|
|
1760
|
-
const y0 = Math.max(0, y);
|
|
1761
|
-
const x1 = Math.min(dstW, x + w);
|
|
1762
|
-
const y1 = Math.min(dstH, y + h);
|
|
1763
|
-
if (x1 <= x0 || y1 <= y0) return;
|
|
1764
|
-
const rowLen = (x1 - x0) * 4;
|
|
1765
|
-
const srcCol = x0 - x;
|
|
1766
|
-
const srcYOffset = y0 - y;
|
|
1767
|
-
const actualH = y1 - y0;
|
|
1768
|
-
for (let row = 0; row < actualH; row++) {
|
|
1769
|
-
const dstStart = ((y0 + row) * dstW + x0) * 4;
|
|
1770
|
-
const srcRow = srcYOffset + row;
|
|
1771
|
-
const o = (srcRow * w + srcCol) * 4;
|
|
1772
|
-
dst.set(data.subarray(o, o + rowLen), dstStart);
|
|
1773
|
-
}
|
|
1774
|
-
}
|
|
1775
|
-
|
|
1776
1785
|
// src/ImageData/writeImageData.ts
|
|
1777
1786
|
function writeImageData(target, source, x, y, sx = 0, sy = 0, sw = source.width, sh = source.height, mask = null, maskType = 1 /* BINARY */) {
|
|
1778
1787
|
const dstW = target.width;
|
|
@@ -1827,6 +1836,27 @@ function writeImageData(target, source, x, y, sx = 0, sy = 0, sw = source.width,
|
|
|
1827
1836
|
}
|
|
1828
1837
|
}
|
|
1829
1838
|
|
|
1839
|
+
// src/ImageData/writeImageDataPixels.ts
|
|
1840
|
+
function writeImageDataPixels(imageData, data, _x, _y, _w, _h) {
|
|
1841
|
+
const { x, y, w, h } = typeof _x === "object" ? _x : { x: _x, y: _y, w: _w, h: _h };
|
|
1842
|
+
const { width: dstW, height: dstH, data: dst } = imageData;
|
|
1843
|
+
const x0 = Math.max(0, x);
|
|
1844
|
+
const y0 = Math.max(0, y);
|
|
1845
|
+
const x1 = Math.min(dstW, x + w);
|
|
1846
|
+
const y1 = Math.min(dstH, y + h);
|
|
1847
|
+
if (x1 <= x0 || y1 <= y0) return;
|
|
1848
|
+
const rowLen = (x1 - x0) * 4;
|
|
1849
|
+
const srcCol = x0 - x;
|
|
1850
|
+
const srcYOffset = y0 - y;
|
|
1851
|
+
const actualH = y1 - y0;
|
|
1852
|
+
for (let row = 0; row < actualH; row++) {
|
|
1853
|
+
const dstStart = ((y0 + row) * dstW + x0) * 4;
|
|
1854
|
+
const srcRow = srcYOffset + row;
|
|
1855
|
+
const o = (srcRow * w + srcCol) * 4;
|
|
1856
|
+
dst.set(data.subarray(o, o + rowLen), dstStart);
|
|
1857
|
+
}
|
|
1858
|
+
}
|
|
1859
|
+
|
|
1830
1860
|
// src/IndexedImage/IndexedImage.ts
|
|
1831
1861
|
var IndexedImage = class _IndexedImage {
|
|
1832
1862
|
/** The width of the image in pixels. */
|
|
@@ -2166,28 +2196,34 @@ function mergeMasks(dst, dstWidth, src, opts) {
|
|
|
2166
2196
|
|
|
2167
2197
|
// src/PixelData/PixelData.ts
|
|
2168
2198
|
var PixelData = class _PixelData {
|
|
2199
|
+
data32;
|
|
2200
|
+
imageData;
|
|
2201
|
+
get width() {
|
|
2202
|
+
return this.imageData.width;
|
|
2203
|
+
}
|
|
2204
|
+
get height() {
|
|
2205
|
+
return this.imageData.height;
|
|
2206
|
+
}
|
|
2169
2207
|
constructor(imageData) {
|
|
2208
|
+
this.data32 = imageDataToUInt32Array(imageData);
|
|
2170
2209
|
this.imageData = imageData;
|
|
2171
|
-
this.width = imageData.width;
|
|
2172
|
-
this.height = imageData.height;
|
|
2173
|
-
this.data32 = new Uint32Array(
|
|
2174
|
-
imageData.data.buffer,
|
|
2175
|
-
imageData.data.byteOffset,
|
|
2176
|
-
// Shift right by 2 is a fast bitwise division by 4.
|
|
2177
|
-
imageData.data.byteLength >> 2
|
|
2178
|
-
);
|
|
2179
2210
|
}
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2211
|
+
set(imageData) {
|
|
2212
|
+
this.imageData = imageData;
|
|
2213
|
+
this.data32 = imageDataToUInt32Array(imageData);
|
|
2214
|
+
}
|
|
2215
|
+
/**
|
|
2216
|
+
* Creates a deep copy of the PixelData using the environment's ImageData constructor.
|
|
2217
|
+
*/
|
|
2183
2218
|
copy() {
|
|
2184
|
-
const buffer = new Uint8ClampedArray(this.
|
|
2185
|
-
const
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2219
|
+
const buffer = new Uint8ClampedArray(this.imageData.data);
|
|
2220
|
+
const ImageConstructor = typeof ImageData !== "undefined" ? ImageData : this.imageData.constructor;
|
|
2221
|
+
const newImageData = new ImageConstructor(
|
|
2222
|
+
buffer,
|
|
2223
|
+
this.width,
|
|
2224
|
+
this.height
|
|
2225
|
+
);
|
|
2226
|
+
return new _PixelData(newImageData);
|
|
2191
2227
|
}
|
|
2192
2228
|
};
|
|
2193
2229
|
|
|
@@ -2279,14 +2315,14 @@ function applyMaskToPixelData(dst, mask, opts) {
|
|
|
2279
2315
|
}
|
|
2280
2316
|
|
|
2281
2317
|
// src/PixelData/blendColorPixelData.ts
|
|
2282
|
-
function blendColorPixelData(dst, color, opts) {
|
|
2318
|
+
function blendColorPixelData(dst, color, opts = {}) {
|
|
2283
2319
|
const {
|
|
2284
2320
|
x: targetX = 0,
|
|
2285
2321
|
y: targetY = 0,
|
|
2286
2322
|
w: width = dst.width,
|
|
2287
2323
|
h: height = dst.height,
|
|
2288
2324
|
alpha: globalAlpha = 255,
|
|
2289
|
-
blendFn =
|
|
2325
|
+
blendFn = sourceOverFast,
|
|
2290
2326
|
mask,
|
|
2291
2327
|
maskType = 0 /* ALPHA */,
|
|
2292
2328
|
mw,
|
|
@@ -2295,6 +2331,9 @@ function blendColorPixelData(dst, color, opts) {
|
|
|
2295
2331
|
invertMask = false
|
|
2296
2332
|
} = opts;
|
|
2297
2333
|
if (globalAlpha === 0) return;
|
|
2334
|
+
const baseSrcAlpha = color >>> 24;
|
|
2335
|
+
const isOverwrite = blendFn.isOverwrite;
|
|
2336
|
+
if (baseSrcAlpha === 0 && !isOverwrite) return;
|
|
2298
2337
|
let x = targetX;
|
|
2299
2338
|
let y = targetY;
|
|
2300
2339
|
let w = width;
|
|
@@ -2320,15 +2359,8 @@ function blendColorPixelData(dst, color, opts) {
|
|
|
2320
2359
|
let mIdx = (my + dy) * mPitch + (mx + dx);
|
|
2321
2360
|
const dStride = dw - actualW;
|
|
2322
2361
|
const mStride = mPitch - actualW;
|
|
2323
|
-
const baseSrcColor = color;
|
|
2324
|
-
const baseSrcAlpha = baseSrcColor >>> 24;
|
|
2325
2362
|
for (let iy = 0; iy < actualH; iy++) {
|
|
2326
2363
|
for (let ix = 0; ix < actualW; ix++) {
|
|
2327
|
-
if (baseSrcAlpha === 0) {
|
|
2328
|
-
dIdx++;
|
|
2329
|
-
mIdx++;
|
|
2330
|
-
continue;
|
|
2331
|
-
}
|
|
2332
2364
|
let weight = globalAlpha;
|
|
2333
2365
|
if (mask) {
|
|
2334
2366
|
const mVal = mask[mIdx];
|
|
@@ -2361,20 +2393,20 @@ function blendColorPixelData(dst, color, opts) {
|
|
|
2361
2393
|
continue;
|
|
2362
2394
|
}
|
|
2363
2395
|
}
|
|
2364
|
-
let
|
|
2365
|
-
let currentSrcColor = baseSrcColor;
|
|
2396
|
+
let currentSrcColor = color;
|
|
2366
2397
|
if (weight < 255) {
|
|
2398
|
+
let currentSrcAlpha = baseSrcAlpha;
|
|
2367
2399
|
if (baseSrcAlpha === 255) {
|
|
2368
2400
|
currentSrcAlpha = weight;
|
|
2369
2401
|
} else {
|
|
2370
2402
|
currentSrcAlpha = baseSrcAlpha * weight + 128 >> 8;
|
|
2371
2403
|
}
|
|
2372
|
-
if (currentSrcAlpha === 0) {
|
|
2404
|
+
if (!isOverwrite && currentSrcAlpha === 0) {
|
|
2373
2405
|
dIdx++;
|
|
2374
2406
|
mIdx++;
|
|
2375
2407
|
continue;
|
|
2376
2408
|
}
|
|
2377
|
-
currentSrcColor = (
|
|
2409
|
+
currentSrcColor = (color & 16777215 | currentSrcAlpha << 24) >>> 0;
|
|
2378
2410
|
}
|
|
2379
2411
|
dst32[dIdx] = blendFn(currentSrcColor, dst32[dIdx]);
|
|
2380
2412
|
dIdx++;
|
|
@@ -2449,11 +2481,12 @@ function blendPixelData(dst, src, opts) {
|
|
|
2449
2481
|
const dStride = dw - actualW;
|
|
2450
2482
|
const sStride = sw - actualW;
|
|
2451
2483
|
const mStride = mPitch - actualW;
|
|
2484
|
+
const isOverwrite = blendFn.isOverwrite;
|
|
2452
2485
|
for (let iy = 0; iy < actualH; iy++) {
|
|
2453
2486
|
for (let ix = 0; ix < actualW; ix++) {
|
|
2454
2487
|
const baseSrcColor = src32[sIdx];
|
|
2455
2488
|
const baseSrcAlpha = baseSrcColor >>> 24;
|
|
2456
|
-
if (baseSrcAlpha === 0) {
|
|
2489
|
+
if (baseSrcAlpha === 0 && !isOverwrite) {
|
|
2457
2490
|
dIdx++;
|
|
2458
2491
|
sIdx++;
|
|
2459
2492
|
mIdx++;
|
|
@@ -2494,15 +2527,15 @@ function blendPixelData(dst, src, opts) {
|
|
|
2494
2527
|
continue;
|
|
2495
2528
|
}
|
|
2496
2529
|
}
|
|
2497
|
-
let currentSrcAlpha = baseSrcAlpha;
|
|
2498
2530
|
let currentSrcColor = baseSrcColor;
|
|
2499
2531
|
if (weight < 255) {
|
|
2532
|
+
let currentSrcAlpha = baseSrcAlpha;
|
|
2500
2533
|
if (baseSrcAlpha === 255) {
|
|
2501
2534
|
currentSrcAlpha = weight;
|
|
2502
2535
|
} else {
|
|
2503
2536
|
currentSrcAlpha = baseSrcAlpha * weight + 128 >> 8;
|
|
2504
2537
|
}
|
|
2505
|
-
if (currentSrcAlpha === 0) {
|
|
2538
|
+
if (!isOverwrite && currentSrcAlpha === 0) {
|
|
2506
2539
|
dIdx++;
|
|
2507
2540
|
sIdx++;
|
|
2508
2541
|
mIdx++;
|
|
@@ -2622,11 +2655,11 @@ function reflectPixelDataVertical(pixelData) {
|
|
|
2622
2655
|
// src/PixelData/resamplePixelData.ts
|
|
2623
2656
|
function resamplePixelData(pixelData, factor) {
|
|
2624
2657
|
const { data, width, height } = resample32(pixelData.data32, pixelData.width, pixelData.height, factor);
|
|
2625
|
-
return new PixelData(
|
|
2658
|
+
return new PixelData(new ImageData(
|
|
2659
|
+
new Uint8ClampedArray(data.buffer),
|
|
2626
2660
|
width,
|
|
2627
|
-
height
|
|
2628
|
-
|
|
2629
|
-
});
|
|
2661
|
+
height
|
|
2662
|
+
));
|
|
2630
2663
|
}
|
|
2631
2664
|
|
|
2632
2665
|
// src/PixelData/rotatePixelData.ts
|
|
@@ -2640,30 +2673,33 @@ function rotatePixelData(pixelData) {
|
|
|
2640
2673
|
}
|
|
2641
2674
|
const newWidth = height;
|
|
2642
2675
|
const newHeight = width;
|
|
2643
|
-
const
|
|
2676
|
+
const newData32 = new Uint32Array(data.length);
|
|
2644
2677
|
for (let y = 0; y < height; y++) {
|
|
2645
2678
|
for (let x = 0; x < width; x++) {
|
|
2646
2679
|
const oldIdx = y * width + x;
|
|
2647
2680
|
const newX = height - 1 - y;
|
|
2648
2681
|
const newY = x;
|
|
2649
2682
|
const newIdx = newY * newWidth + newX;
|
|
2650
|
-
|
|
2683
|
+
newData32[newIdx] = data[oldIdx];
|
|
2651
2684
|
}
|
|
2652
2685
|
}
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2686
|
+
const newImageData = new ImageData(
|
|
2687
|
+
new Uint8ClampedArray(newData32.buffer),
|
|
2688
|
+
newWidth,
|
|
2689
|
+
newHeight
|
|
2690
|
+
);
|
|
2691
|
+
pixelData.set(newImageData);
|
|
2656
2692
|
}
|
|
2657
2693
|
function rotateSquareInPlace(pixelData) {
|
|
2658
2694
|
const n = pixelData.width;
|
|
2659
2695
|
const data = pixelData.data32;
|
|
2660
2696
|
for (let i = 0; i < n / 2; i++) {
|
|
2661
2697
|
for (let j = i; j < n - i - 1; j++) {
|
|
2662
|
-
const temp = data[i * n + j];
|
|
2663
2698
|
const top = i * n + j;
|
|
2664
2699
|
const right = j * n + (n - 1 - i);
|
|
2665
2700
|
const bottom = (n - 1 - i) * n + (n - 1 - j);
|
|
2666
2701
|
const left = (n - 1 - j) * n + i;
|
|
2702
|
+
const temp = data[top];
|
|
2667
2703
|
data[top] = data[left];
|
|
2668
2704
|
data[left] = data[bottom];
|
|
2669
2705
|
data[bottom] = data[right];
|
|
@@ -2733,6 +2769,7 @@ function rotateSquareInPlace(pixelData) {
|
|
|
2733
2769
|
imageDataToAlphaMask,
|
|
2734
2770
|
imageDataToDataUrl,
|
|
2735
2771
|
imageDataToImgBlob,
|
|
2772
|
+
imageDataToUInt32Array,
|
|
2736
2773
|
imgBlobToImageData,
|
|
2737
2774
|
indexedImageToAverageColor,
|
|
2738
2775
|
indexedImageToImageData,
|
|
@@ -2754,6 +2791,7 @@ function rotateSquareInPlace(pixelData) {
|
|
|
2754
2791
|
linearLightPerfect,
|
|
2755
2792
|
makePixelCanvas,
|
|
2756
2793
|
makeReusableCanvas,
|
|
2794
|
+
makeReusableImageData,
|
|
2757
2795
|
mergeMasks,
|
|
2758
2796
|
multiplyFast,
|
|
2759
2797
|
multiplyPerfect,
|