pixel-data-js 0.21.0 → 0.23.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 +1129 -717
- package/dist/index.dev.cjs.map +1 -1
- package/dist/index.dev.js +1114 -716
- package/dist/index.dev.js.map +1 -1
- package/dist/index.prod.cjs +1129 -717
- package/dist/index.prod.cjs.map +1 -1
- package/dist/index.prod.d.ts +317 -136
- package/dist/index.prod.js +1114 -716
- package/dist/index.prod.js.map +1 -1
- package/package.json +1 -1
- package/src/Algorithm/floodFillSelection.ts +12 -14
- package/src/BlendModes/toBlendModeIndexAndName.ts +0 -7
- package/src/Clipboard/writeImgBlobToClipboard.ts +1 -1
- package/src/History/PixelMutator/mutatorApplyAlphaMask.ts +3 -0
- package/src/History/PixelMutator/mutatorApplyBinaryMask.ts +3 -0
- package/src/History/PixelMutator/mutatorApplyCircleBrush.ts +25 -6
- package/src/History/PixelMutator/mutatorApplyCircleBrushStroke.ts +89 -46
- package/src/History/PixelMutator/mutatorApplyCirclePencil.ts +7 -7
- package/src/History/PixelMutator/mutatorApplyCirclePencilStroke.ts +81 -41
- package/src/History/PixelMutator/mutatorApplyRectBrush.ts +3 -0
- package/src/History/PixelMutator/mutatorApplyRectBrushStroke.ts +18 -5
- package/src/History/PixelMutator/mutatorApplyRectPencil.ts +3 -0
- package/src/History/PixelMutator/mutatorApplyRectPencilStroke.ts +19 -4
- package/src/History/PixelMutator/mutatorBlendColor.ts +4 -0
- package/src/History/PixelMutator/mutatorBlendPixelData.ts +5 -1
- package/src/History/PixelMutator/mutatorBlendPixelDataAlphaMask.ts +33 -0
- package/src/History/PixelMutator/mutatorBlendPixelDataBinaryMask.ts +33 -0
- package/src/History/PixelMutator/mutatorClear.ts +12 -10
- package/src/History/PixelMutator/mutatorFill.ts +7 -4
- package/src/History/PixelMutator/mutatorFillBinaryMask.ts +28 -0
- package/src/History/PixelMutator/mutatorInvert.ts +3 -0
- package/src/History/PixelMutator.ts +14 -11
- package/src/ImageData/extractImageDataBuffer.ts +3 -3
- package/src/ImageData/{imageDataToAlphaMask.ts → imageDataToAlphaMaskBuffer.ts} +3 -4
- package/src/ImageData/resizeImageData.ts +3 -5
- package/src/ImageData/writeImageDataBuffer.ts +7 -7
- package/src/Mask/AlphaMask.ts +16 -0
- package/src/Mask/BinaryMask.ts +16 -0
- package/src/Mask/CircleBrushAlphaMask.ts +32 -0
- package/src/Mask/CircleBrushBinaryMask.ts +30 -0
- package/src/Mask/applyBinaryMaskToAlphaMask.ts +12 -9
- package/src/Mask/copyMask.ts +9 -3
- package/src/Mask/extractMask.ts +33 -31
- package/src/Mask/extractMaskBuffer.ts +87 -0
- package/src/Mask/invertMask.ts +6 -4
- package/src/Mask/mergeAlphaMasks.ts +11 -10
- package/src/Mask/mergeBinaryMasks.ts +10 -9
- package/src/Mask/setMaskData.ts +7 -0
- package/src/MaskRect/merge2BinaryMaskRects.ts +81 -0
- package/src/MaskRect/mergeBinaryMaskRects.ts +39 -0
- package/src/MaskRect/subtractBinaryMaskRects.ts +80 -0
- package/src/PixelData/applyAlphaMaskToPixelData.ts +8 -5
- package/src/PixelData/applyBinaryMaskToPixelData.ts +8 -9
- package/src/PixelData/applyCircleBrushToPixelData.ts +54 -62
- package/src/PixelData/blendColorPixelDataAlphaMask.ts +35 -25
- package/src/PixelData/blendColorPixelDataBinaryMask.ts +26 -19
- package/src/PixelData/blendPixelData.ts +1 -1
- package/src/PixelData/blendPixelDataAlphaMask.ts +3 -3
- package/src/PixelData/blendPixelDataBinaryMask.ts +4 -4
- package/src/PixelData/fillPixelData.ts +15 -42
- package/src/PixelData/fillPixelDataBinaryMask.ts +79 -0
- package/src/PixelData/invertPixelData.ts +3 -3
- package/src/PixelData/pixelDataToAlphaMask.ts +4 -2
- package/src/PixelData/writePixelDataBuffer.ts +2 -3
- package/src/Rect/getRectsBounds.ts +22 -0
- package/src/Rect/trimRectBounds.ts +20 -17
- package/src/_types.ts +55 -29
- package/src/index.ts +18 -1
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
type BlendColor32,
|
|
4
4
|
type Color32,
|
|
5
5
|
type ColorBlendOptions,
|
|
6
|
-
type HistoryMutator,
|
|
6
|
+
type HistoryMutator, MaskType,
|
|
7
7
|
type Rect,
|
|
8
8
|
} from '../../_types'
|
|
9
9
|
import { forEachLinePoint } from '../../Algorithm/forEachLinePoint'
|
|
@@ -22,6 +22,9 @@ const defaults = {
|
|
|
22
22
|
|
|
23
23
|
type Deps = Partial<typeof defaults>
|
|
24
24
|
|
|
25
|
+
/**
|
|
26
|
+
* @param deps - @hidden
|
|
27
|
+
*/
|
|
25
28
|
export const mutatorApplyRectBrushStroke = ((writer: PixelWriter<any>, deps: Deps = defaults) => {
|
|
26
29
|
const {
|
|
27
30
|
forEachLinePoint = defaults.forEachLinePoint,
|
|
@@ -53,6 +56,13 @@ export const mutatorApplyRectBrushStroke = ((writer: PixelWriter<any>, deps: Dep
|
|
|
53
56
|
h: 0,
|
|
54
57
|
}
|
|
55
58
|
|
|
59
|
+
const mask = {
|
|
60
|
+
type: MaskType.ALPHA,
|
|
61
|
+
data: null as unknown as Uint8Array,
|
|
62
|
+
w: 0,
|
|
63
|
+
h: 0,
|
|
64
|
+
}
|
|
65
|
+
|
|
56
66
|
return {
|
|
57
67
|
applyRectBrushStroke(
|
|
58
68
|
color: Color32,
|
|
@@ -83,8 +93,11 @@ export const mutatorApplyRectBrushStroke = ((writer: PixelWriter<any>, deps: Dep
|
|
|
83
93
|
|
|
84
94
|
if (bw <= 0 || bh <= 0) return
|
|
85
95
|
|
|
86
|
-
|
|
96
|
+
mask.data = new Uint8Array(bw * bh)
|
|
97
|
+
mask.w = bw
|
|
98
|
+
mask.h = bh
|
|
87
99
|
|
|
100
|
+
const maskData = mask.data
|
|
88
101
|
const halfW = brushWidth / 2
|
|
89
102
|
const halfH = brushHeight / 2
|
|
90
103
|
const invHalfW = 1 / halfW
|
|
@@ -143,8 +156,8 @@ export const mutatorApplyRectBrushStroke = ((writer: PixelWriter<any>, deps: Dep
|
|
|
143
156
|
if (strength > 0) {
|
|
144
157
|
const intensity = (strength * 255) | 0
|
|
145
158
|
|
|
146
|
-
if (intensity >
|
|
147
|
-
|
|
159
|
+
if (intensity > maskData[maskIdx]) {
|
|
160
|
+
maskData[maskIdx] = intensity
|
|
148
161
|
}
|
|
149
162
|
}
|
|
150
163
|
}
|
|
@@ -161,7 +174,7 @@ export const mutatorApplyRectBrushStroke = ((writer: PixelWriter<any>, deps: Dep
|
|
|
161
174
|
blendColorPixelDataAlphaMask(
|
|
162
175
|
writer.target,
|
|
163
176
|
color,
|
|
164
|
-
mask,
|
|
177
|
+
mask as AlphaMask,
|
|
165
178
|
blendColorPixelOptions,
|
|
166
179
|
)
|
|
167
180
|
},
|
|
@@ -11,6 +11,9 @@ const defaults = {
|
|
|
11
11
|
|
|
12
12
|
type Deps = Partial<typeof defaults>
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* @param deps - @hidden
|
|
16
|
+
*/
|
|
14
17
|
export const mutatorApplyRectPencil = ((writer: PixelWriter<any>, deps: Deps = defaults) => {
|
|
15
18
|
const {
|
|
16
19
|
applyRectBrushToPixelData = defaults.applyRectBrushToPixelData,
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
type BlendColor32,
|
|
4
4
|
type Color32,
|
|
5
5
|
type ColorBlendOptions,
|
|
6
|
-
type HistoryMutator,
|
|
6
|
+
type HistoryMutator, MaskType,
|
|
7
7
|
type Rect,
|
|
8
8
|
} from '../../_types'
|
|
9
9
|
import { forEachLinePoint } from '../../Algorithm/forEachLinePoint'
|
|
@@ -21,6 +21,10 @@ const defaults = {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
type Deps = Partial<typeof defaults>
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @param deps - @hidden
|
|
27
|
+
*/
|
|
24
28
|
export const mutatorApplyRectPencilStroke = ((writer: PixelWriter<any>, deps: Deps = defaults) => {
|
|
25
29
|
const {
|
|
26
30
|
forEachLinePoint = defaults.forEachLinePoint,
|
|
@@ -52,6 +56,13 @@ export const mutatorApplyRectPencilStroke = ((writer: PixelWriter<any>, deps: De
|
|
|
52
56
|
h: 0,
|
|
53
57
|
}
|
|
54
58
|
|
|
59
|
+
const mask = {
|
|
60
|
+
type: MaskType.BINARY,
|
|
61
|
+
data: null as unknown as Uint8Array,
|
|
62
|
+
w: 0,
|
|
63
|
+
h: 0,
|
|
64
|
+
}
|
|
65
|
+
|
|
55
66
|
return {
|
|
56
67
|
applyRectPencilStroke(
|
|
57
68
|
color: Color32,
|
|
@@ -81,7 +92,11 @@ export const mutatorApplyRectPencilStroke = ((writer: PixelWriter<any>, deps: De
|
|
|
81
92
|
|
|
82
93
|
if (bw <= 0 || bh <= 0) return
|
|
83
94
|
|
|
84
|
-
|
|
95
|
+
mask.data = new Uint8Array(bw * bh)
|
|
96
|
+
mask.w = bw
|
|
97
|
+
mask.h = bh
|
|
98
|
+
|
|
99
|
+
const maskData = mask.data
|
|
85
100
|
|
|
86
101
|
const halfW = brushWidth / 2
|
|
87
102
|
const halfH = brushHeight / 2
|
|
@@ -130,7 +145,7 @@ export const mutatorApplyRectPencilStroke = ((writer: PixelWriter<any>, deps: De
|
|
|
130
145
|
const maskIdx = maskRowOffset + (mx - bx)
|
|
131
146
|
|
|
132
147
|
if (dx <= halfW && dy <= halfH) {
|
|
133
|
-
|
|
148
|
+
maskData[maskIdx] = 1
|
|
134
149
|
}
|
|
135
150
|
}
|
|
136
151
|
}
|
|
@@ -143,7 +158,7 @@ export const mutatorApplyRectPencilStroke = ((writer: PixelWriter<any>, deps: De
|
|
|
143
158
|
blendColorPixelOptions.w = bw
|
|
144
159
|
blendColorPixelOptions.h = bh
|
|
145
160
|
|
|
146
|
-
blendColorPixelDataBinaryMask(writer.target, color, mask, blendColorPixelOptions)
|
|
161
|
+
blendColorPixelDataBinaryMask(writer.target, color, mask as BinaryMask, blendColorPixelOptions)
|
|
147
162
|
},
|
|
148
163
|
}
|
|
149
164
|
}) satisfies HistoryMutator<any, Deps>
|
|
@@ -4,6 +4,10 @@ import { PixelWriter } from '../PixelWriter'
|
|
|
4
4
|
|
|
5
5
|
const defaults = { blendColorPixelData }
|
|
6
6
|
type Deps = Partial<typeof defaults>
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @param deps - @hidden
|
|
10
|
+
*/
|
|
7
11
|
export const mutatorBlendColor = ((writer: PixelWriter<any>, deps: Deps = defaults) => {
|
|
8
12
|
const {
|
|
9
13
|
blendColorPixelData = defaults.blendColorPixelData,
|
|
@@ -4,6 +4,10 @@ import { PixelWriter } from '../PixelWriter'
|
|
|
4
4
|
|
|
5
5
|
const defaults = { blendPixelData }
|
|
6
6
|
type Deps = Partial<typeof defaults>
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @param deps - @hidden
|
|
10
|
+
*/
|
|
7
11
|
export const mutatorBlendPixelData = ((writer: PixelWriter<any>, deps: Partial<Deps> = defaults) => {
|
|
8
12
|
const {
|
|
9
13
|
blendPixelData = defaults.blendPixelData,
|
|
@@ -12,7 +16,7 @@ export const mutatorBlendPixelData = ((writer: PixelWriter<any>, deps: Partial<D
|
|
|
12
16
|
return {
|
|
13
17
|
blendPixelData(
|
|
14
18
|
src: IPixelData,
|
|
15
|
-
opts: PixelBlendOptions,
|
|
19
|
+
opts: PixelBlendOptions = {},
|
|
16
20
|
) {
|
|
17
21
|
const {
|
|
18
22
|
x = 0,
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { AlphaMask, HistoryMutator, IPixelData, PixelBlendMaskOptions } from '../../_types'
|
|
2
|
+
import { blendPixelDataAlphaMask } from '../../PixelData/blendPixelDataAlphaMask'
|
|
3
|
+
import { PixelWriter } from '../PixelWriter'
|
|
4
|
+
|
|
5
|
+
const defaults = { blendPixelDataAlphaMask }
|
|
6
|
+
type Deps = Partial<typeof defaults>
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @param deps - @hidden
|
|
10
|
+
*/
|
|
11
|
+
export const mutatorBlendPixelDataAlphaMask = ((writer: PixelWriter<any>, deps: Partial<Deps> = defaults) => {
|
|
12
|
+
const {
|
|
13
|
+
blendPixelDataAlphaMask = defaults.blendPixelDataAlphaMask,
|
|
14
|
+
} = deps
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
blendPixelDataAlphaMask(
|
|
18
|
+
src: IPixelData,
|
|
19
|
+
mask: AlphaMask,
|
|
20
|
+
opts: PixelBlendMaskOptions = {},
|
|
21
|
+
) {
|
|
22
|
+
const x = opts.x ?? 0
|
|
23
|
+
const y = opts.y ?? 0
|
|
24
|
+
const w = opts.w ?? src.width
|
|
25
|
+
const h = opts.h ?? src.height
|
|
26
|
+
|
|
27
|
+
writer.accumulator.storeRegionBeforeState(x, y, w, h)
|
|
28
|
+
|
|
29
|
+
blendPixelDataAlphaMask(writer.target, src, mask, opts)
|
|
30
|
+
},
|
|
31
|
+
}
|
|
32
|
+
}) satisfies HistoryMutator<any, Deps>
|
|
33
|
+
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { BinaryMask, HistoryMutator, IPixelData, PixelBlendMaskOptions } from '../../_types'
|
|
2
|
+
import { blendPixelDataBinaryMask } from '../../PixelData/blendPixelDataBinaryMask'
|
|
3
|
+
import { PixelWriter } from '../PixelWriter'
|
|
4
|
+
|
|
5
|
+
const defaults = { blendPixelDataBinaryMask }
|
|
6
|
+
type Deps = Partial<typeof defaults>
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @param deps - @hidden
|
|
10
|
+
*/
|
|
11
|
+
export const mutatorBlendPixelDataBinaryMask = ((writer: PixelWriter<any>, deps: Partial<Deps> = defaults) => {
|
|
12
|
+
const {
|
|
13
|
+
blendPixelDataBinaryMask = defaults.blendPixelDataBinaryMask,
|
|
14
|
+
} = deps
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
blendPixelDataBinaryMask(
|
|
18
|
+
src: IPixelData,
|
|
19
|
+
mask: BinaryMask,
|
|
20
|
+
opts: PixelBlendMaskOptions = {},
|
|
21
|
+
) {
|
|
22
|
+
const x = opts.x ?? 0
|
|
23
|
+
const y = opts.y ?? 0
|
|
24
|
+
const w = opts.w ?? src.width
|
|
25
|
+
const h = opts.h ?? src.height
|
|
26
|
+
|
|
27
|
+
writer.accumulator.storeRegionBeforeState(x, y, w, h)
|
|
28
|
+
|
|
29
|
+
blendPixelDataBinaryMask(writer.target, src, mask, opts)
|
|
30
|
+
},
|
|
31
|
+
}
|
|
32
|
+
}) satisfies HistoryMutator<any, Deps>
|
|
33
|
+
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import type { BinaryMaskRect, Color32, HistoryMutator } from '../../_types'
|
|
1
|
+
import type { BinaryMaskRect, Color32, HistoryMutator, Rect } from '../../_types'
|
|
2
2
|
import { fillPixelData } from '../../PixelData/fillPixelData'
|
|
3
3
|
import { PixelWriter } from '../PixelWriter'
|
|
4
4
|
|
|
5
5
|
const defaults = { fillPixelData }
|
|
6
6
|
|
|
7
7
|
type Deps = Partial<typeof defaults>
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @param deps - @hidden
|
|
11
|
+
*/
|
|
8
12
|
export const mutatorClear = ((writer: PixelWriter<any>, deps: Deps = defaults) => {
|
|
9
13
|
const {
|
|
10
14
|
fillPixelData = defaults.fillPixelData,
|
|
@@ -12,17 +16,15 @@ export const mutatorClear = ((writer: PixelWriter<any>, deps: Deps = defaults) =
|
|
|
12
16
|
|
|
13
17
|
return {
|
|
14
18
|
clear(
|
|
15
|
-
rect: Partial<
|
|
19
|
+
rect: Partial<Rect> = {},
|
|
16
20
|
) {
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
mask = undefined,
|
|
23
|
-
} = rect
|
|
21
|
+
const x = rect.x ?? 0
|
|
22
|
+
const y = rect.y ?? 0
|
|
23
|
+
const w = rect.w ?? writer.target.width
|
|
24
|
+
const h = rect.h ?? writer.target.height
|
|
25
|
+
|
|
24
26
|
writer.accumulator.storeRegionBeforeState(x, y, w, h)
|
|
25
|
-
fillPixelData(writer.target, 0 as Color32, x, y, w, h
|
|
27
|
+
fillPixelData(writer.target, 0 as Color32, x, y, w, h)
|
|
26
28
|
},
|
|
27
29
|
}
|
|
28
30
|
}) satisfies HistoryMutator<any, Deps>
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Color32, HistoryMutator, Rect } from '../../_types'
|
|
2
2
|
import { fillPixelData } from '../../PixelData/fillPixelData'
|
|
3
3
|
import { PixelWriter } from '../PixelWriter'
|
|
4
4
|
|
|
5
5
|
const defaults = { fillPixelData }
|
|
6
6
|
type Deps = Partial<typeof defaults>
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @param deps - @hidden
|
|
10
|
+
*/
|
|
7
11
|
export const mutatorFill = ((writer: PixelWriter<any>, deps: Deps = defaults) => {
|
|
8
12
|
const {
|
|
9
13
|
fillPixelData = defaults.fillPixelData,
|
|
@@ -12,17 +16,16 @@ export const mutatorFill = ((writer: PixelWriter<any>, deps: Deps = defaults) =>
|
|
|
12
16
|
return {
|
|
13
17
|
fill(
|
|
14
18
|
color: Color32,
|
|
15
|
-
rect: Partial<
|
|
19
|
+
rect: Partial<Rect> = {},
|
|
16
20
|
) {
|
|
17
21
|
const {
|
|
18
22
|
x = 0,
|
|
19
23
|
y = 0,
|
|
20
24
|
w = writer.target.width,
|
|
21
25
|
h = writer.target.height,
|
|
22
|
-
mask = undefined,
|
|
23
26
|
} = rect
|
|
24
27
|
writer.accumulator.storeRegionBeforeState(x, y, w, h)
|
|
25
|
-
fillPixelData(writer.target, color, x, y, w, h
|
|
28
|
+
fillPixelData(writer.target, color, x, y, w, h)
|
|
26
29
|
},
|
|
27
30
|
}
|
|
28
31
|
}) satisfies HistoryMutator<any, Deps>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { BinaryMask, Color32, HistoryMutator } from '../../_types'
|
|
2
|
+
import { fillPixelDataBinaryMask } from '../../PixelData/fillPixelDataBinaryMask'
|
|
3
|
+
import { PixelWriter } from '../PixelWriter'
|
|
4
|
+
|
|
5
|
+
const defaults = { fillPixelDataBinaryMask }
|
|
6
|
+
type Deps = Partial<typeof defaults>
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @param deps - @hidden
|
|
10
|
+
*/
|
|
11
|
+
export const mutatorFillBinaryMask = ((writer: PixelWriter<any>, deps: Deps = defaults) => {
|
|
12
|
+
const {
|
|
13
|
+
fillPixelDataBinaryMask = defaults.fillPixelDataBinaryMask,
|
|
14
|
+
} = deps
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
fillBinaryMask(
|
|
18
|
+
color: Color32,
|
|
19
|
+
mask: BinaryMask,
|
|
20
|
+
alpha = 255,
|
|
21
|
+
x = 0,
|
|
22
|
+
y = 0,
|
|
23
|
+
) {
|
|
24
|
+
writer.accumulator.storeRegionBeforeState(x, y, mask.w, mask.h)
|
|
25
|
+
fillPixelDataBinaryMask(writer.target, color, mask, alpha, x, y)
|
|
26
|
+
},
|
|
27
|
+
}
|
|
28
|
+
}) satisfies HistoryMutator<any, Deps>
|
|
@@ -5,6 +5,9 @@ import { PixelWriter } from '../PixelWriter'
|
|
|
5
5
|
const defaults = { invertPixelData }
|
|
6
6
|
type Deps = Partial<typeof defaults>
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* @param deps - @hidden
|
|
10
|
+
*/
|
|
8
11
|
export const mutatorInvert = ((writer: PixelWriter<any>, deps: Deps = defaults) => {
|
|
9
12
|
const {
|
|
10
13
|
invertPixelData = defaults.invertPixelData,
|
|
@@ -2,6 +2,7 @@ import { mutatorApplyAlphaMask } from './PixelMutator/mutatorApplyAlphaMask'
|
|
|
2
2
|
import { mutatorApplyBinaryMask } from './PixelMutator/mutatorApplyBinaryMask'
|
|
3
3
|
import { mutatorApplyCircleBrush } from './PixelMutator/mutatorApplyCircleBrush'
|
|
4
4
|
import { mutatorApplyCircleBrushStroke } from './PixelMutator/mutatorApplyCircleBrushStroke'
|
|
5
|
+
import { mutatorApplyCirclePencil } from './PixelMutator/mutatorApplyCirclePencil'
|
|
5
6
|
import { mutatorApplyCirclePencilStroke } from './PixelMutator/mutatorApplyCirclePencilStroke'
|
|
6
7
|
import { mutatorApplyRectBrush } from './PixelMutator/mutatorApplyRectBrush'
|
|
7
8
|
import { mutatorApplyRectBrushStroke } from './PixelMutator/mutatorApplyRectBrushStroke'
|
|
@@ -10,33 +11,35 @@ import { mutatorApplyRectPencilStroke } from './PixelMutator/mutatorApplyRectPen
|
|
|
10
11
|
import { mutatorBlendColor } from './PixelMutator/mutatorBlendColor'
|
|
11
12
|
import { mutatorBlendPixel } from './PixelMutator/mutatorBlendPixel'
|
|
12
13
|
import { mutatorBlendPixelData } from './PixelMutator/mutatorBlendPixelData'
|
|
14
|
+
import { mutatorBlendPixelDataAlphaMask } from './PixelMutator/mutatorBlendPixelDataAlphaMask'
|
|
15
|
+
import { mutatorBlendPixelDataBinaryMask } from './PixelMutator/mutatorBlendPixelDataBinaryMask'
|
|
13
16
|
import { mutatorClear } from './PixelMutator/mutatorClear'
|
|
14
17
|
import { mutatorFill } from './PixelMutator/mutatorFill'
|
|
18
|
+
import { mutatorFillBinaryMask } from './PixelMutator/mutatorFillBinaryMask'
|
|
15
19
|
import { mutatorInvert } from './PixelMutator/mutatorInvert'
|
|
16
20
|
import type { PixelWriter } from './PixelWriter'
|
|
17
21
|
|
|
18
22
|
export function makeFullPixelMutator(writer: PixelWriter<any>) {
|
|
19
23
|
return {
|
|
24
|
+
// @sort
|
|
20
25
|
...mutatorApplyAlphaMask(writer),
|
|
21
26
|
...mutatorApplyBinaryMask(writer),
|
|
22
|
-
|
|
23
|
-
...mutatorBlendPixelData(writer),
|
|
24
|
-
...mutatorBlendColor(writer),
|
|
25
|
-
...mutatorBlendPixel(writer),
|
|
26
|
-
...mutatorFill(writer),
|
|
27
|
-
...mutatorInvert(writer),
|
|
28
|
-
|
|
29
27
|
...mutatorApplyCircleBrush(writer),
|
|
30
28
|
...mutatorApplyCircleBrushStroke(writer),
|
|
31
|
-
|
|
29
|
+
...mutatorApplyCirclePencil(writer),
|
|
32
30
|
...mutatorApplyCirclePencilStroke(writer),
|
|
33
|
-
|
|
34
31
|
...mutatorApplyRectBrush(writer),
|
|
35
32
|
...mutatorApplyRectBrushStroke(writer),
|
|
36
|
-
|
|
37
33
|
...mutatorApplyRectPencil(writer),
|
|
38
34
|
...mutatorApplyRectPencilStroke(writer),
|
|
39
|
-
|
|
35
|
+
...mutatorBlendColor(writer),
|
|
36
|
+
...mutatorBlendPixel(writer),
|
|
37
|
+
...mutatorBlendPixelData(writer),
|
|
38
|
+
...mutatorBlendPixelDataAlphaMask(writer),
|
|
39
|
+
...mutatorBlendPixelDataBinaryMask(writer),
|
|
40
40
|
...mutatorClear(writer),
|
|
41
|
+
...mutatorFill(writer),
|
|
42
|
+
...mutatorFillBinaryMask(writer),
|
|
43
|
+
...mutatorInvert(writer),
|
|
41
44
|
}
|
|
42
45
|
}
|
|
@@ -10,8 +10,8 @@ const SCRATCH_BLIT = makeClippedBlit()
|
|
|
10
10
|
* This is a "read-only" operation that returns a copy of the pixel data.
|
|
11
11
|
*
|
|
12
12
|
* @param imageData - The source image data to read from.
|
|
13
|
-
* @param rect - A
|
|
14
|
-
* @returns A
|
|
13
|
+
* @param rect - A rect defining the region to extract.
|
|
14
|
+
* @returns A buffer containing the RGBA pixel data of the region.
|
|
15
15
|
*/
|
|
16
16
|
export function extractImageDataBuffer(
|
|
17
17
|
imageData: ImageDataLike,
|
|
@@ -23,7 +23,7 @@ export function extractImageDataBuffer(
|
|
|
23
23
|
* @param y - The starting vertical coordinate.
|
|
24
24
|
* @param w - The width of the region to extract.
|
|
25
25
|
* @param h - The height of the region to extract.
|
|
26
|
-
* @returns A
|
|
26
|
+
* @returns A buffer containing the RGBA pixel data of the region.
|
|
27
27
|
*/
|
|
28
28
|
export function extractImageDataBuffer(
|
|
29
29
|
imageData: ImageDataLike,
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { AlphaMask } from '../_types'
|
|
2
1
|
import { pixelDataToAlphaMask } from '../PixelData/pixelDataToAlphaMask'
|
|
3
2
|
|
|
4
3
|
/**
|
|
@@ -6,9 +5,9 @@ import { pixelDataToAlphaMask } from '../PixelData/pixelDataToAlphaMask'
|
|
|
6
5
|
* When possible use {@link pixelDataToAlphaMask} instead.
|
|
7
6
|
* Repeat calls to the same data will use less memory.
|
|
8
7
|
*/
|
|
9
|
-
export function
|
|
8
|
+
export function imageDataToAlphaMaskBuffer(
|
|
10
9
|
imageData: ImageData,
|
|
11
|
-
):
|
|
10
|
+
): Uint8Array {
|
|
12
11
|
const {
|
|
13
12
|
width,
|
|
14
13
|
height,
|
|
@@ -22,7 +21,7 @@ export function imageDataToAlphaMask(
|
|
|
22
21
|
data.byteLength >> 2,
|
|
23
22
|
)
|
|
24
23
|
const len = data32.length
|
|
25
|
-
const mask = new Uint8Array(width * height)
|
|
24
|
+
const mask = new Uint8Array(width * height)
|
|
26
25
|
|
|
27
26
|
for (let i = 0; i < len; i++) {
|
|
28
27
|
const val = data32[i]
|
|
@@ -7,15 +7,13 @@ import type { ImageDataLike } from '../_types'
|
|
|
7
7
|
* instead, it crops or pads the image based on the new dimensions and
|
|
8
8
|
* provides an offset for repositioning.
|
|
9
9
|
*
|
|
10
|
-
* @param
|
|
10
|
+
* @param target The target to resize.
|
|
11
11
|
* @param newWidth The target width in pixels.
|
|
12
12
|
* @param newHeight The target height in pixels.
|
|
13
13
|
* @param offsetX The horizontal offset for placing the
|
|
14
14
|
* original image within the new buffer.
|
|
15
|
-
* @default 0
|
|
16
15
|
* @param offsetY The vertical offset for placing the
|
|
17
16
|
* original image within the new buffer.
|
|
18
|
-
* @default 0
|
|
19
17
|
*
|
|
20
18
|
* @returns A new {@link ImageData} instance with the specified dimensions.
|
|
21
19
|
*
|
|
@@ -32,7 +30,7 @@ import type { ImageDataLike } from '../_types'
|
|
|
32
30
|
* ```
|
|
33
31
|
*/
|
|
34
32
|
export function resizeImageData(
|
|
35
|
-
|
|
33
|
+
target: ImageDataLike,
|
|
36
34
|
newWidth: number,
|
|
37
35
|
newHeight: number,
|
|
38
36
|
offsetX = 0,
|
|
@@ -43,7 +41,7 @@ export function resizeImageData(
|
|
|
43
41
|
width: oldW,
|
|
44
42
|
height: oldH,
|
|
45
43
|
data: oldData,
|
|
46
|
-
} =
|
|
44
|
+
} = target
|
|
47
45
|
const newData = result.data
|
|
48
46
|
|
|
49
47
|
// Determine intersection of the old image (at offset) and new canvas bounds
|
|
@@ -10,17 +10,17 @@ const SCRATCH_BLIT = makeClippedBlit()
|
|
|
10
10
|
* into the target {@link ImageData} buffer. It supports both {@link Rect}
|
|
11
11
|
* objects and discrete coordinates.
|
|
12
12
|
*
|
|
13
|
-
* @param
|
|
13
|
+
* @param target - The target to write into. Must match the rect width/height.
|
|
14
14
|
* @param data - The source pixel data (RGBA).
|
|
15
|
-
* @param rect - A
|
|
15
|
+
* @param rect - A rect defining the destination region.
|
|
16
16
|
*/
|
|
17
17
|
export function writeImageDataBuffer(
|
|
18
|
-
|
|
18
|
+
target: ImageData,
|
|
19
19
|
data: Uint8ClampedArray,
|
|
20
20
|
rect: Rect,
|
|
21
21
|
): void
|
|
22
22
|
/**
|
|
23
|
-
* @param
|
|
23
|
+
* @param target - The target to write into.
|
|
24
24
|
* @param data - The source pixel data (RGBA). Must match the width/height.
|
|
25
25
|
* @param x - The starting horizontal coordinate in the target.
|
|
26
26
|
* @param y - The starting vertical coordinate in the target.
|
|
@@ -28,7 +28,7 @@ export function writeImageDataBuffer(
|
|
|
28
28
|
* @param h - The height of the region to write.
|
|
29
29
|
*/
|
|
30
30
|
export function writeImageDataBuffer(
|
|
31
|
-
|
|
31
|
+
target: ImageData,
|
|
32
32
|
data: Uint8ClampedArray,
|
|
33
33
|
x: number,
|
|
34
34
|
y: number,
|
|
@@ -36,7 +36,7 @@ export function writeImageDataBuffer(
|
|
|
36
36
|
h: number,
|
|
37
37
|
): void
|
|
38
38
|
export function writeImageDataBuffer(
|
|
39
|
-
|
|
39
|
+
target: ImageData,
|
|
40
40
|
data: Uint8ClampedArray,
|
|
41
41
|
_x: Rect | number,
|
|
42
42
|
_y?: number,
|
|
@@ -47,7 +47,7 @@ export function writeImageDataBuffer(
|
|
|
47
47
|
? _x
|
|
48
48
|
: { x: _x, y: _y!, w: _w!, h: _h! }
|
|
49
49
|
|
|
50
|
-
const { width: dstW, height: dstH, data: dst } =
|
|
50
|
+
const { width: dstW, height: dstH, data: dst } = target
|
|
51
51
|
|
|
52
52
|
const clip = resolveBlitClipping(
|
|
53
53
|
x,
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type AlphaMask, MaskType } from '../_types'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Creates an Alpha Mask
|
|
5
|
+
* @param w - width
|
|
6
|
+
* @param h - height
|
|
7
|
+
* @param data - values 0-255
|
|
8
|
+
*/
|
|
9
|
+
export function makeAlphaMask(w: number, h: number, data?: Uint8Array): AlphaMask {
|
|
10
|
+
return {
|
|
11
|
+
type: MaskType.ALPHA,
|
|
12
|
+
data: data ?? new Uint8Array(w * h),
|
|
13
|
+
w,
|
|
14
|
+
h,
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type BinaryMask, MaskType } from '../_types'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Creates a Binary Mask
|
|
5
|
+
* @param w - width
|
|
6
|
+
* @param h - height
|
|
7
|
+
* @param data - values 0-1
|
|
8
|
+
*/
|
|
9
|
+
export function makeBinaryMask(w: number, h: number, data?: Uint8Array): BinaryMask {
|
|
10
|
+
return {
|
|
11
|
+
type: MaskType.BINARY,
|
|
12
|
+
data: data ?? new Uint8Array(w * h),
|
|
13
|
+
w,
|
|
14
|
+
h,
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type CircleBrushAlphaMask, MaskType } from '../_types'
|
|
2
|
+
|
|
3
|
+
export function makeCircleBrushAlphaMask(size: number, fallOff: (d: number) => number = () => 1): CircleBrushAlphaMask {
|
|
4
|
+
const area = size * size
|
|
5
|
+
const data = new Uint8Array(area)
|
|
6
|
+
const radius = size / 2
|
|
7
|
+
const invR = 1 / radius
|
|
8
|
+
|
|
9
|
+
const minOffset = -Math.ceil(radius - 0.5)
|
|
10
|
+
|
|
11
|
+
for (let y = 0; y < size; y++) {
|
|
12
|
+
for (let x = 0; x < size; x++) {
|
|
13
|
+
const dx = x - radius + 0.5
|
|
14
|
+
const dy = y - radius + 0.5
|
|
15
|
+
const distSqr = dx * dx + dy * dy
|
|
16
|
+
if (distSqr <= (radius * radius)) {
|
|
17
|
+
const dist = Math.sqrt(distSqr)
|
|
18
|
+
data[y * size + x] = (fallOff(1 - (dist * invR)) * 255) | 0
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
type: MaskType.ALPHA,
|
|
25
|
+
data,
|
|
26
|
+
w: size,
|
|
27
|
+
h: size,
|
|
28
|
+
radius,
|
|
29
|
+
size,
|
|
30
|
+
minOffset,
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type CircleBrushBinaryMask, MaskType } from '../_types'
|
|
2
|
+
|
|
3
|
+
export function makeCircleBrushBinaryMask(size: number): CircleBrushBinaryMask {
|
|
4
|
+
const area = size * size
|
|
5
|
+
const data = new Uint8Array(area)
|
|
6
|
+
const radius = size / 2
|
|
7
|
+
|
|
8
|
+
const minOffset = -Math.ceil(radius - 0.5)
|
|
9
|
+
|
|
10
|
+
for (let y = 0; y < size; y++) {
|
|
11
|
+
for (let x = 0; x < size; x++) {
|
|
12
|
+
const dx = x - radius + 0.5
|
|
13
|
+
const dy = y - radius + 0.5
|
|
14
|
+
const distSqr = dx * dx + dy * dy
|
|
15
|
+
if (distSqr <= (radius * radius)) {
|
|
16
|
+
data[y * size + x] = 1
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
type: MaskType.BINARY,
|
|
23
|
+
data,
|
|
24
|
+
w: size,
|
|
25
|
+
h: size,
|
|
26
|
+
radius,
|
|
27
|
+
size,
|
|
28
|
+
minOffset,
|
|
29
|
+
}
|
|
30
|
+
}
|