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.
Files changed (68) hide show
  1. package/dist/index.dev.cjs +1129 -717
  2. package/dist/index.dev.cjs.map +1 -1
  3. package/dist/index.dev.js +1114 -716
  4. package/dist/index.dev.js.map +1 -1
  5. package/dist/index.prod.cjs +1129 -717
  6. package/dist/index.prod.cjs.map +1 -1
  7. package/dist/index.prod.d.ts +317 -136
  8. package/dist/index.prod.js +1114 -716
  9. package/dist/index.prod.js.map +1 -1
  10. package/package.json +1 -1
  11. package/src/Algorithm/floodFillSelection.ts +12 -14
  12. package/src/BlendModes/toBlendModeIndexAndName.ts +0 -7
  13. package/src/Clipboard/writeImgBlobToClipboard.ts +1 -1
  14. package/src/History/PixelMutator/mutatorApplyAlphaMask.ts +3 -0
  15. package/src/History/PixelMutator/mutatorApplyBinaryMask.ts +3 -0
  16. package/src/History/PixelMutator/mutatorApplyCircleBrush.ts +25 -6
  17. package/src/History/PixelMutator/mutatorApplyCircleBrushStroke.ts +89 -46
  18. package/src/History/PixelMutator/mutatorApplyCirclePencil.ts +7 -7
  19. package/src/History/PixelMutator/mutatorApplyCirclePencilStroke.ts +81 -41
  20. package/src/History/PixelMutator/mutatorApplyRectBrush.ts +3 -0
  21. package/src/History/PixelMutator/mutatorApplyRectBrushStroke.ts +18 -5
  22. package/src/History/PixelMutator/mutatorApplyRectPencil.ts +3 -0
  23. package/src/History/PixelMutator/mutatorApplyRectPencilStroke.ts +19 -4
  24. package/src/History/PixelMutator/mutatorBlendColor.ts +4 -0
  25. package/src/History/PixelMutator/mutatorBlendPixelData.ts +5 -1
  26. package/src/History/PixelMutator/mutatorBlendPixelDataAlphaMask.ts +33 -0
  27. package/src/History/PixelMutator/mutatorBlendPixelDataBinaryMask.ts +33 -0
  28. package/src/History/PixelMutator/mutatorClear.ts +12 -10
  29. package/src/History/PixelMutator/mutatorFill.ts +7 -4
  30. package/src/History/PixelMutator/mutatorFillBinaryMask.ts +28 -0
  31. package/src/History/PixelMutator/mutatorInvert.ts +3 -0
  32. package/src/History/PixelMutator.ts +14 -11
  33. package/src/ImageData/extractImageDataBuffer.ts +3 -3
  34. package/src/ImageData/{imageDataToAlphaMask.ts → imageDataToAlphaMaskBuffer.ts} +3 -4
  35. package/src/ImageData/resizeImageData.ts +3 -5
  36. package/src/ImageData/writeImageDataBuffer.ts +7 -7
  37. package/src/Mask/AlphaMask.ts +16 -0
  38. package/src/Mask/BinaryMask.ts +16 -0
  39. package/src/Mask/CircleBrushAlphaMask.ts +32 -0
  40. package/src/Mask/CircleBrushBinaryMask.ts +30 -0
  41. package/src/Mask/applyBinaryMaskToAlphaMask.ts +12 -9
  42. package/src/Mask/copyMask.ts +9 -3
  43. package/src/Mask/extractMask.ts +33 -31
  44. package/src/Mask/extractMaskBuffer.ts +87 -0
  45. package/src/Mask/invertMask.ts +6 -4
  46. package/src/Mask/mergeAlphaMasks.ts +11 -10
  47. package/src/Mask/mergeBinaryMasks.ts +10 -9
  48. package/src/Mask/setMaskData.ts +7 -0
  49. package/src/MaskRect/merge2BinaryMaskRects.ts +81 -0
  50. package/src/MaskRect/mergeBinaryMaskRects.ts +39 -0
  51. package/src/MaskRect/subtractBinaryMaskRects.ts +80 -0
  52. package/src/PixelData/applyAlphaMaskToPixelData.ts +8 -5
  53. package/src/PixelData/applyBinaryMaskToPixelData.ts +8 -9
  54. package/src/PixelData/applyCircleBrushToPixelData.ts +54 -62
  55. package/src/PixelData/blendColorPixelDataAlphaMask.ts +35 -25
  56. package/src/PixelData/blendColorPixelDataBinaryMask.ts +26 -19
  57. package/src/PixelData/blendPixelData.ts +1 -1
  58. package/src/PixelData/blendPixelDataAlphaMask.ts +3 -3
  59. package/src/PixelData/blendPixelDataBinaryMask.ts +4 -4
  60. package/src/PixelData/fillPixelData.ts +15 -42
  61. package/src/PixelData/fillPixelDataBinaryMask.ts +79 -0
  62. package/src/PixelData/invertPixelData.ts +3 -3
  63. package/src/PixelData/pixelDataToAlphaMask.ts +4 -2
  64. package/src/PixelData/writePixelDataBuffer.ts +2 -3
  65. package/src/Rect/getRectsBounds.ts +22 -0
  66. package/src/Rect/trimRectBounds.ts +20 -17
  67. package/src/_types.ts +55 -29
  68. 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
- const mask = new Uint8Array(bw * bh) as AlphaMask
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 > mask[maskIdx]) {
147
- mask[maskIdx] = intensity
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
- const mask = new Uint8Array(bw * bh) as BinaryMask
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
- mask[maskIdx] = 1
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<BinaryMaskRect> = {},
19
+ rect: Partial<Rect> = {},
16
20
  ) {
17
- const {
18
- x = 0,
19
- y = 0,
20
- w = writer.target.width,
21
- h = writer.target.height,
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, mask)
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 { BinaryMaskRect, Color32, HistoryMutator } from '../../_types'
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<BinaryMaskRect> = {},
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, mask)
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 {@link Rect} object defining the region to extract.
14
- * @returns A {@link Uint8ClampedArray} containing the RGBA pixel data of the region.
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 {@link Uint8ClampedArray} containing the RGBA pixel data of the region.
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 imageDataToAlphaMask(
8
+ export function imageDataToAlphaMaskBuffer(
10
9
  imageData: ImageData,
11
- ): AlphaMask {
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) as AlphaMask
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 current The source {@link ImageDataLike} to resize.
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
- current: ImageDataLike,
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
- } = current
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 imageData - The target {@link ImageData} to write into. Must match the rect width/height.
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 {@link Rect} object defining the destination region.
15
+ * @param rect - A rect defining the destination region.
16
16
  */
17
17
  export function writeImageDataBuffer(
18
- imageData: ImageData,
18
+ target: ImageData,
19
19
  data: Uint8ClampedArray,
20
20
  rect: Rect,
21
21
  ): void
22
22
  /**
23
- * @param imageData - The target {@link ImageData} to write into.
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
- imageData: ImageData,
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
- imageData: ImageData,
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 } = imageData
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
+ }