pixel-data-js 0.31.0 → 0.33.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.prod.cjs +433 -310
- package/dist/index.prod.cjs.map +1 -1
- package/dist/index.prod.d.ts +78 -52
- package/dist/index.prod.js +430 -306
- package/dist/index.prod.js.map +1 -1
- package/package.json +1 -1
- package/src/ImageData/copyImageData.ts +4 -2
- package/src/ImageData/extractImageData.ts +54 -0
- package/src/ImageData/extractImageDataBuffer.ts +55 -28
- package/src/ImageData/writeImageData.ts +47 -69
- package/src/ImageData/writeImageDataBuffer.ts +77 -41
- package/src/PixelData/extractPixelDataBuffer.ts +51 -40
- package/src/PixelData/fillPixelData.ts +45 -28
- package/src/PixelData/fillPixelDataBinaryMask.ts +43 -38
- package/src/PixelData/fillPixelDataFast.ts +25 -16
- package/src/PixelData/invertPixelData.ts +38 -21
- package/src/PixelData/resizePixelData.ts +75 -0
- package/src/PixelData/writePixelData.ts +55 -0
- package/src/PixelData/writePixelDataBuffer.ts +53 -38
- package/src/index.ts +3 -1
- package/src/Rect/resolveClipping.ts +0 -140
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import type { Color32 } from '../_types'
|
|
2
2
|
import type { BinaryMask } from '../Mask/_mask-types'
|
|
3
|
-
import { makeClippedRect, resolveRectClipping } from '../Rect/resolveClipping'
|
|
4
3
|
import type { PixelData32 } from './_pixelData-types'
|
|
5
4
|
|
|
6
|
-
const SCRATCH_RECT = makeClippedRect()
|
|
7
|
-
|
|
8
5
|
/**
|
|
9
|
-
* Fills
|
|
6
|
+
* Fills the target PixelData with a color based on a binary mask.
|
|
7
|
+
*
|
|
10
8
|
* @param target - The target to modify.
|
|
11
9
|
* @param color - The color to apply.
|
|
12
|
-
* @param mask - The mask
|
|
13
|
-
* @param x -
|
|
14
|
-
* @param y -
|
|
10
|
+
* @param mask - The binary mask determining where to fill.
|
|
11
|
+
* @param x - Horizontal offset to place the mask.
|
|
12
|
+
* @param y - Vertical offset to place the mask.
|
|
13
|
+
* @returns true if any pixels were actually modified.
|
|
15
14
|
*/
|
|
16
15
|
export function fillPixelDataBinaryMask(
|
|
17
16
|
target: PixelData32,
|
|
@@ -20,55 +19,61 @@ export function fillPixelDataBinaryMask(
|
|
|
20
19
|
x = 0,
|
|
21
20
|
y = 0,
|
|
22
21
|
): boolean {
|
|
23
|
-
|
|
22
|
+
const targetW = target.w
|
|
23
|
+
const targetH = target.h
|
|
24
24
|
const maskW = mask.w
|
|
25
25
|
const maskH = mask.h
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
27
|
+
// Inline clipping logic
|
|
28
|
+
let dstX = x
|
|
29
|
+
let dstY = y
|
|
30
|
+
let actualW = maskW
|
|
31
|
+
let actualH = maskH
|
|
32
|
+
|
|
33
|
+
if (dstX < 0) {
|
|
34
|
+
actualW += dstX
|
|
35
|
+
dstX = 0
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (dstY < 0) {
|
|
39
|
+
actualH += dstY
|
|
40
|
+
dstY = 0
|
|
41
|
+
}
|
|
36
42
|
|
|
37
|
-
|
|
43
|
+
actualW = Math.min(actualW, targetW - dstX)
|
|
44
|
+
actualH = Math.min(actualH, targetH - dstY)
|
|
38
45
|
|
|
39
|
-
|
|
40
|
-
x: finalX,
|
|
41
|
-
y: finalY,
|
|
42
|
-
w: actualW,
|
|
43
|
-
h: actualH,
|
|
44
|
-
} = clip
|
|
46
|
+
if (actualW <= 0 || actualH <= 0) return false
|
|
45
47
|
|
|
46
48
|
const maskData = mask.data
|
|
47
49
|
const dst32 = target.data
|
|
48
|
-
|
|
50
|
+
|
|
51
|
+
// Calculate offsets for the mask based on clipping
|
|
52
|
+
const mx = dstX - x
|
|
53
|
+
const my = dstY - y
|
|
49
54
|
|
|
50
55
|
let hasChanged = false
|
|
51
56
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const maskOffset = maskY * maskW
|
|
57
|
+
// Stride-based loop for performance
|
|
58
|
+
let dIdx = dstY * targetW + dstX
|
|
59
|
+
let mIdx = my * maskW + mx
|
|
56
60
|
|
|
57
|
-
|
|
61
|
+
const dStride = targetW - actualW
|
|
62
|
+
const mStride = maskW - actualW
|
|
58
63
|
|
|
64
|
+
for (let iy = 0; iy < actualH; iy++) {
|
|
59
65
|
for (let ix = 0; ix < actualW; ix++) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if (maskData[maskIndex]) {
|
|
65
|
-
const current = dst32[dstRowOffset + currentX]
|
|
66
|
-
if (current !== color) {
|
|
67
|
-
dst32[dstRowOffset + currentX] = color
|
|
66
|
+
if (maskData[mIdx]) {
|
|
67
|
+
if (dst32[dIdx] !== color) {
|
|
68
|
+
dst32[dIdx] = color
|
|
68
69
|
hasChanged = true
|
|
69
70
|
}
|
|
70
71
|
}
|
|
72
|
+
dIdx++
|
|
73
|
+
mIdx++
|
|
71
74
|
}
|
|
75
|
+
dIdx += dStride
|
|
76
|
+
mIdx += mStride
|
|
72
77
|
}
|
|
73
78
|
|
|
74
79
|
return hasChanged
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import type { Color32 } from '../_types'
|
|
2
2
|
import type { Rect } from '../Rect/_rect-types'
|
|
3
|
-
import { makeClippedRect, resolveRectClipping } from '../Rect/resolveClipping'
|
|
4
3
|
import type { PixelData32 } from './_pixelData-types'
|
|
5
4
|
|
|
6
|
-
const SCRATCH_RECT = makeClippedRect()
|
|
7
|
-
|
|
8
5
|
/**
|
|
9
6
|
* Fills a region or the {@link PixelData32} buffer with a solid color.
|
|
10
7
|
* This function is faster than {@link fillPixelData} but does not
|
|
@@ -44,6 +41,9 @@ export function fillPixelDataFast(
|
|
|
44
41
|
_w?: number,
|
|
45
42
|
_h?: number,
|
|
46
43
|
): void {
|
|
44
|
+
const dstW = dst.w
|
|
45
|
+
const dstH = dst.h
|
|
46
|
+
|
|
47
47
|
let x: number
|
|
48
48
|
let y: number
|
|
49
49
|
let w: number
|
|
@@ -66,31 +66,40 @@ export function fillPixelDataFast(
|
|
|
66
66
|
h = dst.h
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
// Inline bounds clipping
|
|
70
|
+
let dstX = x
|
|
71
|
+
let dstY = y
|
|
72
|
+
let fillW = w
|
|
73
|
+
let fillH = h
|
|
74
|
+
|
|
75
|
+
if (dstX < 0) {
|
|
76
|
+
fillW += dstX
|
|
77
|
+
dstX = 0
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (dstY < 0) {
|
|
81
|
+
fillH += dstY
|
|
82
|
+
dstY = 0
|
|
83
|
+
}
|
|
70
84
|
|
|
71
|
-
|
|
85
|
+
fillW = Math.min(fillW, dstW - dstX)
|
|
86
|
+
fillH = Math.min(fillH, dstH - dstY)
|
|
72
87
|
|
|
73
|
-
|
|
74
|
-
const {
|
|
75
|
-
x: finalX,
|
|
76
|
-
y: finalY,
|
|
77
|
-
w: actualW,
|
|
78
|
-
h: actualH,
|
|
79
|
-
} = clip
|
|
88
|
+
if (fillW <= 0 || fillH <= 0) return
|
|
80
89
|
|
|
81
90
|
const dst32 = dst.data
|
|
82
91
|
const dw = dst.w
|
|
83
92
|
|
|
84
93
|
// Optimization: If filling the entire buffer, use the native .fill()
|
|
85
|
-
if (
|
|
94
|
+
if (fillW === dw && fillH === dst.h && dstX === 0 && dstY === 0) {
|
|
86
95
|
dst32.fill(color)
|
|
87
96
|
return
|
|
88
97
|
}
|
|
89
98
|
|
|
90
99
|
// Row-by-row fill for partial rectangles
|
|
91
|
-
for (let iy = 0; iy <
|
|
92
|
-
const start = (
|
|
93
|
-
const end = start +
|
|
100
|
+
for (let iy = 0; iy < fillH; iy++) {
|
|
101
|
+
const start = (dstY + iy) * dw + dstX
|
|
102
|
+
const end = start + fillW
|
|
94
103
|
dst32.fill(color, start, end)
|
|
95
104
|
}
|
|
96
105
|
}
|
|
@@ -1,49 +1,66 @@
|
|
|
1
1
|
import { type PixelMutateOptions } from '../_types'
|
|
2
|
-
import { makeClippedRect, resolveRectClipping } from '../Rect/resolveClipping'
|
|
3
2
|
import type { PixelData32 } from './_pixelData-types'
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Inverts the RGB color data of the target PixelData, optionally controlled by a mask.
|
|
6
|
+
* @param target - The target to modify.
|
|
7
|
+
* @param opts - Options defining the area, mask, and offsets.
|
|
8
|
+
* @returns true if the operation was performed within bounds.
|
|
9
|
+
*/
|
|
7
10
|
export function invertPixelData(
|
|
8
11
|
target: PixelData32,
|
|
9
12
|
opts?: PixelMutateOptions,
|
|
10
13
|
): boolean {
|
|
14
|
+
const targetW = target.w
|
|
15
|
+
const targetH = target.h
|
|
16
|
+
|
|
11
17
|
const mask = opts?.mask
|
|
18
|
+
const invertMask = opts?.invertMask ?? false
|
|
19
|
+
|
|
12
20
|
const targetX = opts?.x ?? 0
|
|
13
21
|
const targetY = opts?.y ?? 0
|
|
14
22
|
const mx = opts?.mx ?? 0
|
|
15
23
|
const my = opts?.my ?? 0
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const invertMask = opts?.invertMask ?? false
|
|
24
|
+
const w = opts?.w ?? targetW
|
|
25
|
+
const h = opts?.h ?? targetH
|
|
19
26
|
|
|
20
|
-
|
|
27
|
+
// Inline clipping logic
|
|
28
|
+
let x = targetX
|
|
29
|
+
let y = targetY
|
|
30
|
+
let actualW = w
|
|
31
|
+
let actualH = h
|
|
21
32
|
|
|
22
|
-
if (
|
|
33
|
+
if (x < 0) {
|
|
34
|
+
actualW += x
|
|
35
|
+
x = 0
|
|
36
|
+
}
|
|
23
37
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
y
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
38
|
+
if (y < 0) {
|
|
39
|
+
actualH += y
|
|
40
|
+
y = 0
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
actualW = Math.min(actualW, targetW - x)
|
|
44
|
+
actualH = Math.min(actualH, targetH - y)
|
|
45
|
+
|
|
46
|
+
if (actualW <= 0 || actualH <= 0) return false
|
|
30
47
|
|
|
31
48
|
const dst32 = target.data
|
|
32
|
-
const dw =
|
|
33
|
-
const mPitch = mask?.w ?? width
|
|
49
|
+
const dw = targetW
|
|
34
50
|
|
|
51
|
+
// Calculate relative movement for the mask coordinate
|
|
35
52
|
const dx = x - targetX
|
|
36
53
|
const dy = y - targetY
|
|
37
54
|
|
|
38
55
|
let dIdx = y * dw + x
|
|
39
|
-
let mIdx = (my + dy) * mPitch + (mx + dx)
|
|
40
|
-
|
|
41
56
|
const dStride = dw - actualW
|
|
42
|
-
const mStride = mPitch - actualW
|
|
43
57
|
|
|
44
|
-
// Optimization: Split loops to avoid checking `if (mask)` for every pixel.
|
|
45
58
|
if (mask) {
|
|
46
59
|
const maskData = mask.data
|
|
60
|
+
const mPitch = mask.w
|
|
61
|
+
let mIdx = (my + dy) * mPitch + (mx + dx)
|
|
62
|
+
const mStride = mPitch - actualW
|
|
63
|
+
|
|
47
64
|
for (let iy = 0; iy < actualH; iy++) {
|
|
48
65
|
for (let ix = 0; ix < actualW; ix++) {
|
|
49
66
|
const mVal = maskData[mIdx]
|
|
@@ -52,7 +69,7 @@ export function invertPixelData(
|
|
|
52
69
|
: mVal === 1
|
|
53
70
|
|
|
54
71
|
if (isHit) {
|
|
55
|
-
// XOR with 0x00FFFFFF flips RGB bits and ignores Alpha
|
|
72
|
+
// XOR with 0x00FFFFFF flips RGB bits and ignores Alpha
|
|
56
73
|
dst32[dIdx] = dst32[dIdx] ^ 0x00FFFFFF
|
|
57
74
|
}
|
|
58
75
|
dIdx++
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { MutablePixelData32, PixelData32 } from './_pixelData-types'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Non-destructively resizes the {@link PixelData32} buffer to new dimensions, optionally
|
|
5
|
+
* offsetting the original content.
|
|
6
|
+
* This operation creates a new buffer. It does not scale or stretch pixels;
|
|
7
|
+
* instead, it crops or pads the image based on the new dimensions.
|
|
8
|
+
*
|
|
9
|
+
* @param target - The source pixel data to resize.
|
|
10
|
+
* @param newWidth - The target width in pixels.
|
|
11
|
+
* @param newHeight - The target height in pixels.
|
|
12
|
+
* @param offsetX - The horizontal offset for placing the original image.
|
|
13
|
+
* @param offsetY - The vertical offset for placing the original image.
|
|
14
|
+
* @param out - output object
|
|
15
|
+
* @returns A new {@link PixelData32} object with the specified dimensions.
|
|
16
|
+
*/
|
|
17
|
+
export function resizePixelData(
|
|
18
|
+
target: PixelData32,
|
|
19
|
+
newWidth: number,
|
|
20
|
+
newHeight: number,
|
|
21
|
+
offsetX = 0,
|
|
22
|
+
offsetY = 0,
|
|
23
|
+
out?: MutablePixelData32,
|
|
24
|
+
): PixelData32 {
|
|
25
|
+
const newData = new Uint32Array(newWidth * newHeight)
|
|
26
|
+
const {
|
|
27
|
+
w: oldW,
|
|
28
|
+
h: oldH,
|
|
29
|
+
data: oldData,
|
|
30
|
+
} = target
|
|
31
|
+
|
|
32
|
+
const result = out ?? {} as MutablePixelData32
|
|
33
|
+
result.w = newWidth
|
|
34
|
+
result.h = newHeight
|
|
35
|
+
result.data = newData
|
|
36
|
+
|
|
37
|
+
// Determine intersection of the old image (at offset) and new canvas bounds
|
|
38
|
+
const x0 = Math.max(0, offsetX)
|
|
39
|
+
const y0 = Math.max(0, offsetY)
|
|
40
|
+
const x1 = Math.min(newWidth, offsetX + oldW)
|
|
41
|
+
const y1 = Math.min(newHeight, offsetY + oldH)
|
|
42
|
+
|
|
43
|
+
if (x1 <= x0 || y1 <= y0) {
|
|
44
|
+
return result
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const copyW = x1 - x0
|
|
48
|
+
const copyH = y1 - y0
|
|
49
|
+
|
|
50
|
+
// Optimization: If we are copying the full width of both buffers,
|
|
51
|
+
// we can perform a single bulk 1D copy.
|
|
52
|
+
if (copyW === oldW && copyW === newWidth && offsetX === 0) {
|
|
53
|
+
const srcStart = (y0 - offsetY) * oldW
|
|
54
|
+
const dstStart = y0 * newWidth
|
|
55
|
+
const len = copyW * copyH
|
|
56
|
+
|
|
57
|
+
newData.set(oldData.subarray(srcStart, srcStart + len), dstStart)
|
|
58
|
+
return result
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Standard row-by-row copy
|
|
62
|
+
for (let row = 0; row < copyH; row++) {
|
|
63
|
+
const dstY = y0 + row
|
|
64
|
+
const srcY = dstY - offsetY
|
|
65
|
+
const srcX = x0 - offsetX
|
|
66
|
+
|
|
67
|
+
const dstStart = dstY * newWidth + x0
|
|
68
|
+
const srcStart = srcY * oldW + srcX
|
|
69
|
+
const chunk = oldData.subarray(srcStart, srcStart + copyW)
|
|
70
|
+
|
|
71
|
+
newData.set(chunk, dstStart)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return result
|
|
75
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { PixelData32 } from './_pixelData-types'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Writes PixelData from a source to a target.
|
|
5
|
+
* @param target - The destination to write to.
|
|
6
|
+
* @param source - The source to read from.
|
|
7
|
+
* @param x - The x-coordinate in the target where drawing starts.
|
|
8
|
+
* @param y - The y-coordinate in the target where drawing starts.
|
|
9
|
+
*/
|
|
10
|
+
export function writePixelData(
|
|
11
|
+
target: PixelData32,
|
|
12
|
+
source: PixelData32,
|
|
13
|
+
x = 0,
|
|
14
|
+
y = 0,
|
|
15
|
+
): void {
|
|
16
|
+
const dstW = target.w
|
|
17
|
+
const dstH = target.h
|
|
18
|
+
const dst = target.data
|
|
19
|
+
|
|
20
|
+
const srcW = source.w
|
|
21
|
+
const srcH = source.h
|
|
22
|
+
const src = source.data
|
|
23
|
+
|
|
24
|
+
let dstX = x
|
|
25
|
+
let dstY = y
|
|
26
|
+
let srcX = 0
|
|
27
|
+
let srcY = 0
|
|
28
|
+
let copyW = srcW
|
|
29
|
+
let copyH = srcH
|
|
30
|
+
|
|
31
|
+
if (dstX < 0) {
|
|
32
|
+
srcX = -dstX
|
|
33
|
+
copyW += dstX
|
|
34
|
+
dstX = 0
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (dstY < 0) {
|
|
38
|
+
srcY = -dstY
|
|
39
|
+
copyH += dstY
|
|
40
|
+
dstY = 0
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
copyW = Math.min(copyW, dstW - dstX)
|
|
44
|
+
copyH = Math.min(copyH, dstH - dstY)
|
|
45
|
+
|
|
46
|
+
if (copyW <= 0 || copyH <= 0) return
|
|
47
|
+
|
|
48
|
+
for (let row = 0; row < copyH; row++) {
|
|
49
|
+
const dstStart = (dstY + row) * dstW + dstX
|
|
50
|
+
const srcStart = (srcY + row) * srcW + srcX
|
|
51
|
+
const chunk = src.subarray(srcStart, srcStart + copyW)
|
|
52
|
+
|
|
53
|
+
dst.set(chunk, dstStart)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
import type { Rect } from '../Rect/_rect-types'
|
|
2
|
-
import { makeClippedBlit, resolveBlitClipping } from '../Rect/resolveClipping'
|
|
3
2
|
import type { PixelData32 } from './_pixelData-types'
|
|
4
3
|
|
|
5
|
-
const SCRATCH_BLIT = makeClippedBlit()
|
|
6
|
-
|
|
7
4
|
/**
|
|
8
5
|
* Copies a pixel buffer into a specific region of a {@link PixelData32} object.
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
6
|
+
* @param target - The target to write into.
|
|
7
|
+
* @param data - The source pixel data (Uint32Array).
|
|
8
|
+
* @param rect - A rect defining the destination region.
|
|
12
9
|
*/
|
|
13
10
|
export function writePixelDataBuffer(
|
|
14
11
|
target: PixelData32,
|
|
15
12
|
data: Uint32Array,
|
|
16
13
|
rect: Rect,
|
|
17
14
|
): void
|
|
15
|
+
/**
|
|
16
|
+
* @param target - The target to write into.
|
|
17
|
+
* @param data - The source pixel data (Uint32Array).
|
|
18
|
+
* @param x - The starting horizontal coordinate in the target.
|
|
19
|
+
* @param y - The starting vertical coordinate in the target.
|
|
20
|
+
* @param w - The width of the region to write.
|
|
21
|
+
* @param h - The height of the region to write.
|
|
22
|
+
*/
|
|
18
23
|
export function writePixelDataBuffer(
|
|
19
24
|
target: PixelData32,
|
|
20
25
|
data: Uint32Array,
|
|
@@ -31,49 +36,59 @@ export function writePixelDataBuffer(
|
|
|
31
36
|
_w?: number,
|
|
32
37
|
_h?: number,
|
|
33
38
|
): void {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
let x: number
|
|
40
|
+
let y: number
|
|
41
|
+
let w: number
|
|
42
|
+
let h: number
|
|
43
|
+
|
|
44
|
+
if (typeof _x === 'object') {
|
|
45
|
+
x = _x.x
|
|
46
|
+
y = _x.y
|
|
47
|
+
w = _x.w
|
|
48
|
+
h = _x.h
|
|
49
|
+
} else {
|
|
50
|
+
x = _x
|
|
51
|
+
y = _y!
|
|
52
|
+
w = _w!
|
|
53
|
+
h = _h!
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (w <= 0 || h <= 0) return
|
|
42
57
|
|
|
43
58
|
const dstW = target.w
|
|
44
59
|
const dstH = target.h
|
|
45
60
|
const dstData = target.data
|
|
46
61
|
|
|
47
|
-
//
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
62
|
+
// Inline clipping logic
|
|
63
|
+
let dstX = x
|
|
64
|
+
let dstY = y
|
|
65
|
+
let srcX = 0
|
|
66
|
+
let srcY = 0
|
|
67
|
+
let copyW = w
|
|
68
|
+
let copyH = h
|
|
69
|
+
|
|
70
|
+
if (dstX < 0) {
|
|
71
|
+
srcX = -dstX
|
|
72
|
+
copyW += dstX
|
|
73
|
+
dstX = 0
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (dstY < 0) {
|
|
77
|
+
srcY = -dstY
|
|
78
|
+
copyH += dstY
|
|
79
|
+
dstY = 0
|
|
80
|
+
}
|
|
61
81
|
|
|
62
|
-
|
|
82
|
+
copyW = Math.min(copyW, dstW - dstX)
|
|
83
|
+
copyH = Math.min(copyH, dstH - dstY)
|
|
63
84
|
|
|
64
|
-
|
|
65
|
-
x: dstX,
|
|
66
|
-
y: dstY,
|
|
67
|
-
sx: srcX,
|
|
68
|
-
sy: srcY,
|
|
69
|
-
w: copyW,
|
|
70
|
-
h: copyH,
|
|
71
|
-
} = clip
|
|
85
|
+
if (copyW <= 0 || copyH <= 0) return
|
|
72
86
|
|
|
73
87
|
for (let row = 0; row < copyH; row++) {
|
|
74
88
|
const dstStart = (dstY + row) * dstW + dstX
|
|
75
89
|
const srcStart = (srcY + row) * w + srcX
|
|
90
|
+
const chunk = data.subarray(srcStart, srcStart + copyW)
|
|
76
91
|
|
|
77
|
-
dstData.set(
|
|
92
|
+
dstData.set(chunk, dstStart)
|
|
78
93
|
}
|
|
79
94
|
}
|
package/src/index.ts
CHANGED
|
@@ -58,6 +58,7 @@ export * from './History/PixelWriter'
|
|
|
58
58
|
|
|
59
59
|
export * from './ImageData/_ImageData-types'
|
|
60
60
|
export * from './ImageData/copyImageData'
|
|
61
|
+
export * from './ImageData/extractImageData'
|
|
61
62
|
export * from './ImageData/extractImageDataBuffer'
|
|
62
63
|
export * from './ImageData/ImageDataLike'
|
|
63
64
|
export * from './ImageData/imageDataToAlphaMaskBuffer'
|
|
@@ -160,15 +161,16 @@ export * from './PixelData/PixelData'
|
|
|
160
161
|
export * from './PixelData/pixelDataToAlphaMask'
|
|
161
162
|
export * from './PixelData/reflectPixelData'
|
|
162
163
|
export * from './PixelData/resamplePixelData'
|
|
164
|
+
export * from './PixelData/resizePixelData'
|
|
163
165
|
export * from './PixelData/ReusablePixelData'
|
|
164
166
|
export * from './PixelData/rotatePixelData'
|
|
165
167
|
export * from './PixelData/uInt32ArrayToPixelData'
|
|
166
168
|
export * from './PixelData/writePaintBufferToPixelData'
|
|
169
|
+
export * from './PixelData/writePixelData'
|
|
167
170
|
export * from './PixelData/writePixelDataBuffer'
|
|
168
171
|
|
|
169
172
|
export * from './Rect/_rect-types'
|
|
170
173
|
export * from './Rect/getRectsBounds'
|
|
171
|
-
export * from './Rect/resolveClipping'
|
|
172
174
|
export * from './Rect/trimMaskRectBounds'
|
|
173
175
|
export * from './Rect/trimRectBounds'
|
|
174
176
|
|