@imgly/plugin-background-removal-web 0.1.0 → 0.2.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/LICENSE.md +652 -1
- package/README.md +4 -3
- package/dist/constants.d.ts +1 -1
- package/dist/index.mjs +1 -491
- package/dist/index.mjs.map +4 -4
- package/dist/plugin.d.ts +2 -0
- package/dist/registerComponents.d.ts +2 -1
- package/dist/types.d.ts +14 -7
- package/dist/utils.d.ts +8 -14
- package/package.json +6 -5
package/dist/constants.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const
|
|
1
|
+
export declare const PLUGIN_ID = "@imgly/plugin-background-removal-web";
|
|
2
2
|
export declare const CANVAS_MENU_COMPONENT_ID = "@imgly/plugin-background-removal-web.canvasMenu";
|
|
3
3
|
export declare const CANVAS_MENU_COMPONENT_BUTTON_ID = "@imgly/plugin-background-removal-web.canvasMenu.button";
|
|
4
4
|
export declare const FEATURE_ID = "@imgly/plugin-background-removal-web.feature";
|
package/dist/index.mjs
CHANGED
|
@@ -1,492 +1,2 @@
|
|
|
1
|
-
//
|
|
2
|
-
import isEqual from "lodash/isEqual";
|
|
3
|
-
|
|
4
|
-
// src/constants.ts
|
|
5
|
-
var BG_REMOVAL_ID = "@imgly/plugin-background-removal-web";
|
|
6
|
-
var CANVAS_MENU_COMPONENT_ID = `${BG_REMOVAL_ID}.canvasMenu`;
|
|
7
|
-
var CANVAS_MENU_COMPONENT_BUTTON_ID = `${CANVAS_MENU_COMPONENT_ID}.button`;
|
|
8
|
-
var FEATURE_ID = `${BG_REMOVAL_ID}.feature`;
|
|
9
|
-
|
|
10
|
-
// src/utils.ts
|
|
11
|
-
function setBGRemovalMetadata(cesdk, id, metadata) {
|
|
12
|
-
cesdk.engine.block.setMetadata(id, BG_REMOVAL_ID, JSON.stringify(metadata));
|
|
13
|
-
}
|
|
14
|
-
function getBGRemovalMetadata(cesdk, id) {
|
|
15
|
-
if (cesdk.engine.block.hasMetadata(id, BG_REMOVAL_ID)) {
|
|
16
|
-
return JSON.parse(cesdk.engine.block.getMetadata(id, BG_REMOVAL_ID));
|
|
17
|
-
} else {
|
|
18
|
-
return {
|
|
19
|
-
status: "IDLE"
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
function clearBGRemovalMetadata(cesdk, id) {
|
|
24
|
-
if (cesdk.engine.block.hasMetadata(id, BG_REMOVAL_ID)) {
|
|
25
|
-
cesdk.engine.block.removeMetadata(id, BG_REMOVAL_ID);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
function isDuplicate(cesdk, blockId, metadata) {
|
|
29
|
-
if (!cesdk.engine.block.isValid(blockId))
|
|
30
|
-
return false;
|
|
31
|
-
if (metadata.status === "IDLE" || metadata.status === "PENDING" || metadata.status === "ERROR")
|
|
32
|
-
return false;
|
|
33
|
-
if (!cesdk.engine.block.hasFill(blockId))
|
|
34
|
-
return false;
|
|
35
|
-
const fillId = cesdk.engine.block.getFill(blockId);
|
|
36
|
-
if (metadata.blockId === blockId || metadata.fillId === fillId)
|
|
37
|
-
return false;
|
|
38
|
-
return true;
|
|
39
|
-
}
|
|
40
|
-
function fixDuplicateMetadata(cesdk, blockId) {
|
|
41
|
-
const fillId = cesdk.engine.block.getFill(blockId);
|
|
42
|
-
const metadata = getBGRemovalMetadata(cesdk, blockId);
|
|
43
|
-
if (metadata.status === "IDLE" || metadata.status === "PENDING" || metadata.status === "ERROR")
|
|
44
|
-
return;
|
|
45
|
-
setBGRemovalMetadata(cesdk, blockId, {
|
|
46
|
-
...metadata,
|
|
47
|
-
blockId,
|
|
48
|
-
fillId
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
function isMetadataConsistent(cesdk, blockId) {
|
|
52
|
-
if (!cesdk.engine.block.isValid(blockId))
|
|
53
|
-
return false;
|
|
54
|
-
const metadata = getBGRemovalMetadata(cesdk, blockId);
|
|
55
|
-
if (metadata.status === "IDLE" || metadata.status === "PENDING")
|
|
56
|
-
return true;
|
|
57
|
-
if (!cesdk.engine.block.hasFill(blockId))
|
|
58
|
-
return false;
|
|
59
|
-
const fillId = cesdk.engine.block.getFill(blockId);
|
|
60
|
-
if (fillId == null)
|
|
61
|
-
return false;
|
|
62
|
-
if (blockId !== metadata.blockId || fillId !== metadata.fillId)
|
|
63
|
-
return false;
|
|
64
|
-
const sourceSet = cesdk.engine.block.getSourceSet(
|
|
65
|
-
fillId,
|
|
66
|
-
"fill/image/sourceSet"
|
|
67
|
-
);
|
|
68
|
-
const imageFileURI = cesdk.engine.block.getString(
|
|
69
|
-
fillId,
|
|
70
|
-
"fill/image/imageFileURI"
|
|
71
|
-
);
|
|
72
|
-
if (sourceSet.length === 0 && !imageFileURI && metadata.status === "PROCESSING") {
|
|
73
|
-
return true;
|
|
74
|
-
}
|
|
75
|
-
if (sourceSet?.length > 0) {
|
|
76
|
-
const initialSourceSet = metadata.initialSourceSet;
|
|
77
|
-
if (metadata.status === "PROCESSED_WITH_BG" || metadata.status === "PROCESSED_WITHOUT_BG") {
|
|
78
|
-
const removedBackground = metadata.removedBackground;
|
|
79
|
-
if (!isEqual(sourceSet, removedBackground) && !isEqual(sourceSet, initialSourceSet)) {
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
|
-
} else {
|
|
83
|
-
if (!isEqual(sourceSet, initialSourceSet)) {
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
} else {
|
|
88
|
-
if (metadata.status === "PROCESSED_WITH_BG" || metadata.status === "PROCESSED_WITHOUT_BG") {
|
|
89
|
-
if (imageFileURI !== metadata.initialImageFileURI && imageFileURI !== metadata.removedBackground) {
|
|
90
|
-
return false;
|
|
91
|
-
}
|
|
92
|
-
} else {
|
|
93
|
-
if (imageFileURI !== metadata.initialImageFileURI) {
|
|
94
|
-
return false;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
return true;
|
|
99
|
-
}
|
|
100
|
-
function toggleBackgroundRemovalData(cesdk, blockId) {
|
|
101
|
-
const blockApi = cesdk.engine.block;
|
|
102
|
-
if (!blockApi.hasFill(blockId))
|
|
103
|
-
return;
|
|
104
|
-
const fillId = blockApi.getFill(blockId);
|
|
105
|
-
const metadata = getBGRemovalMetadata(cesdk, blockId);
|
|
106
|
-
if (metadata.status === "PROCESSED_WITH_BG") {
|
|
107
|
-
setBGRemovalMetadata(cesdk, blockId, {
|
|
108
|
-
...metadata,
|
|
109
|
-
status: "PROCESSED_WITHOUT_BG"
|
|
110
|
-
});
|
|
111
|
-
if (typeof metadata.removedBackground === "string") {
|
|
112
|
-
blockApi.setString(
|
|
113
|
-
fillId,
|
|
114
|
-
"fill/image/imageFileURI",
|
|
115
|
-
metadata.removedBackground
|
|
116
|
-
);
|
|
117
|
-
} else {
|
|
118
|
-
blockApi.setSourceSet(
|
|
119
|
-
fillId,
|
|
120
|
-
"fill/image/sourceSet",
|
|
121
|
-
metadata.removedBackground
|
|
122
|
-
);
|
|
123
|
-
}
|
|
124
|
-
cesdk.engine.editor.addUndoStep();
|
|
125
|
-
} else if (metadata.status === "PROCESSED_WITHOUT_BG") {
|
|
126
|
-
setBGRemovalMetadata(cesdk, blockId, {
|
|
127
|
-
...metadata,
|
|
128
|
-
status: "PROCESSED_WITH_BG"
|
|
129
|
-
});
|
|
130
|
-
blockApi.setString(
|
|
131
|
-
fillId,
|
|
132
|
-
"fill/image/imageFileURI",
|
|
133
|
-
metadata.initialImageFileURI
|
|
134
|
-
);
|
|
135
|
-
blockApi.setSourceSet(
|
|
136
|
-
fillId,
|
|
137
|
-
"fill/image/sourceSet",
|
|
138
|
-
metadata.initialSourceSet
|
|
139
|
-
);
|
|
140
|
-
cesdk.engine.editor.addUndoStep();
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
function recoverInitialImageData(cesdk, blockId) {
|
|
144
|
-
const blockApi = cesdk.engine.block;
|
|
145
|
-
if (!blockApi.hasFill(blockId))
|
|
146
|
-
return;
|
|
147
|
-
const metadata = getBGRemovalMetadata(cesdk, blockId);
|
|
148
|
-
if (metadata.status === "PENDING" || metadata.status === "IDLE") {
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
const initialSourceSet = metadata.initialSourceSet;
|
|
152
|
-
const initialImageFileURI = metadata.initialImageFileURI;
|
|
153
|
-
const fillId = getValidFill(cesdk, blockId, metadata);
|
|
154
|
-
if (fillId == null)
|
|
155
|
-
return;
|
|
156
|
-
if (initialImageFileURI) {
|
|
157
|
-
cesdk.engine.block.setString(
|
|
158
|
-
fillId,
|
|
159
|
-
"fill/image/imageFileURI",
|
|
160
|
-
initialImageFileURI
|
|
161
|
-
);
|
|
162
|
-
}
|
|
163
|
-
if (initialSourceSet.length > 0) {
|
|
164
|
-
cesdk.engine.block.setSourceSet(
|
|
165
|
-
fillId,
|
|
166
|
-
"fill/image/sourceSet",
|
|
167
|
-
initialSourceSet
|
|
168
|
-
);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
function getValidFill(cesdk, blockId, metadata) {
|
|
172
|
-
if (!cesdk.engine.block.isValid(blockId) || !cesdk.engine.block.hasFill(blockId) || blockId !== metadata.blockId) {
|
|
173
|
-
return void 0;
|
|
174
|
-
}
|
|
175
|
-
const fillId = cesdk.engine.block.getFill(blockId);
|
|
176
|
-
if (fillId !== metadata.fillId) {
|
|
177
|
-
return void 0;
|
|
178
|
-
}
|
|
179
|
-
return fillId;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// src/registerComponents.ts
|
|
183
|
-
function registerComponents(cesdk) {
|
|
184
|
-
cesdk.ui.unstable_setCanvasMenuOrder([
|
|
185
|
-
CANVAS_MENU_COMPONENT_ID,
|
|
186
|
-
...cesdk.ui.unstable_getCanvasMenuOrder()
|
|
187
|
-
]);
|
|
188
|
-
cesdk.ui.unstable_registerComponent(
|
|
189
|
-
CANVAS_MENU_COMPONENT_ID,
|
|
190
|
-
({ builder: { Button }, engine }) => {
|
|
191
|
-
if (!cesdk.feature.unstable_isEnabled(FEATURE_ID, {
|
|
192
|
-
engine
|
|
193
|
-
})) {
|
|
194
|
-
return;
|
|
195
|
-
}
|
|
196
|
-
const [id] = engine.block.findAllSelected();
|
|
197
|
-
const metadata = getBGRemovalMetadata(cesdk, id);
|
|
198
|
-
const isActive = metadata.status === "PROCESSED_WITHOUT_BG";
|
|
199
|
-
const isLoading = metadata.status === "PROCESSING";
|
|
200
|
-
const isDisabled = metadata.status === "PENDING" || metadata.status === "PROCESSING";
|
|
201
|
-
let loadingProgress;
|
|
202
|
-
if (isLoading && metadata.progress) {
|
|
203
|
-
const { key, current, total } = metadata.progress;
|
|
204
|
-
if (key === "compute:inference") {
|
|
205
|
-
loadingProgress = void 0;
|
|
206
|
-
} else if (key.startsWith("fetch:/models/")) {
|
|
207
|
-
loadingProgress = current / total * 50;
|
|
208
|
-
} else if (key.startsWith("fetch:/onnxruntime-web/")) {
|
|
209
|
-
loadingProgress = 50 + current / total * 50;
|
|
210
|
-
} else {
|
|
211
|
-
loadingProgress = void 0;
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
Button(CANVAS_MENU_COMPONENT_BUTTON_ID, {
|
|
215
|
-
label: "BG Removal",
|
|
216
|
-
icon: "@imgly/icons/BGRemove",
|
|
217
|
-
isActive,
|
|
218
|
-
isLoading,
|
|
219
|
-
isDisabled,
|
|
220
|
-
loadingProgress,
|
|
221
|
-
onClick: () => {
|
|
222
|
-
switch (metadata.status) {
|
|
223
|
-
case "IDLE":
|
|
224
|
-
case "ERROR": {
|
|
225
|
-
setBGRemovalMetadata(cesdk, id, {
|
|
226
|
-
status: "PENDING"
|
|
227
|
-
});
|
|
228
|
-
break;
|
|
229
|
-
}
|
|
230
|
-
case "PROCESSED_WITHOUT_BG":
|
|
231
|
-
case "PROCESSED_WITH_BG": {
|
|
232
|
-
toggleBackgroundRemovalData(cesdk, id);
|
|
233
|
-
break;
|
|
234
|
-
}
|
|
235
|
-
default: {
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
});
|
|
240
|
-
}
|
|
241
|
-
);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// src/enableFeatures.ts
|
|
245
|
-
function enableFeatures(cesdk) {
|
|
246
|
-
cesdk.feature.unstable_enable(FEATURE_ID, ({ engine }) => {
|
|
247
|
-
const selectedIds = engine.block.findAllSelected();
|
|
248
|
-
if (selectedIds.length !== 1) {
|
|
249
|
-
return false;
|
|
250
|
-
}
|
|
251
|
-
const [selectedId] = selectedIds;
|
|
252
|
-
if (cesdk.engine.block.hasFill(selectedId)) {
|
|
253
|
-
const fillId = cesdk.engine.block.getFill(selectedId);
|
|
254
|
-
const fillType = cesdk.engine.block.getType(fillId);
|
|
255
|
-
if (fillType !== "//ly.img.ubq/fill/image") {
|
|
256
|
-
return false;
|
|
257
|
-
}
|
|
258
|
-
const fileUri = engine.block.getString(fillId, "fill/image/imageFileURI");
|
|
259
|
-
const sourceSet = engine.block.getSourceSet(
|
|
260
|
-
fillId,
|
|
261
|
-
"fill/image/sourceSet"
|
|
262
|
-
);
|
|
263
|
-
if (sourceSet.length > 0 || fileUri !== "")
|
|
264
|
-
return true;
|
|
265
|
-
const metadata = getBGRemovalMetadata(cesdk, selectedId);
|
|
266
|
-
return metadata.status === "PROCESSING";
|
|
267
|
-
}
|
|
268
|
-
return false;
|
|
269
|
-
});
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// src/processBackgroundRemoval.ts
|
|
273
|
-
import {
|
|
274
|
-
segmentForeground,
|
|
275
|
-
applySegmentationMask
|
|
276
|
-
} from "@imgly/background-removal";
|
|
277
|
-
import throttle from "lodash/throttle";
|
|
278
|
-
async function processBackgroundRemoval(cesdk, blockId, configuration) {
|
|
279
|
-
const blockApi = cesdk.engine.block;
|
|
280
|
-
if (!blockApi.hasFill(blockId))
|
|
281
|
-
throw new Error("Block has no fill to remove the background from");
|
|
282
|
-
const fillId = blockApi.getFill(blockId);
|
|
283
|
-
const initialSourceSet = blockApi.getSourceSet(
|
|
284
|
-
fillId,
|
|
285
|
-
"fill/image/sourceSet"
|
|
286
|
-
);
|
|
287
|
-
const initialImageFileURI = blockApi.getString(
|
|
288
|
-
fillId,
|
|
289
|
-
"fill/image/imageFileURI"
|
|
290
|
-
);
|
|
291
|
-
try {
|
|
292
|
-
blockApi.setString(fillId, "fill/image/imageFileURI", "");
|
|
293
|
-
blockApi.setSourceSet(fillId, "fill/image/sourceSet", []);
|
|
294
|
-
const metadata = getBGRemovalMetadata(cesdk, blockId);
|
|
295
|
-
setBGRemovalMetadata(cesdk, blockId, {
|
|
296
|
-
...metadata,
|
|
297
|
-
version: "0.1.0",
|
|
298
|
-
initialSourceSet,
|
|
299
|
-
initialImageFileURI,
|
|
300
|
-
blockId,
|
|
301
|
-
fillId,
|
|
302
|
-
status: "PROCESSING"
|
|
303
|
-
});
|
|
304
|
-
const uriToProcess = (
|
|
305
|
-
// Source sets have priority in the engine
|
|
306
|
-
initialSourceSet.length > 0 ? (
|
|
307
|
-
// Choose the highest resolution image in the source set
|
|
308
|
-
initialSourceSet.sort(
|
|
309
|
-
(a, b) => b.width * b.height - a.height * a.width
|
|
310
|
-
)[0].uri
|
|
311
|
-
) : initialImageFileURI
|
|
312
|
-
);
|
|
313
|
-
const mask = await segmentForeground(uriToProcess, configuration);
|
|
314
|
-
if (initialSourceSet.length > 0) {
|
|
315
|
-
const uploaded = await maskSourceSet(
|
|
316
|
-
cesdk,
|
|
317
|
-
blockId,
|
|
318
|
-
initialSourceSet,
|
|
319
|
-
mask,
|
|
320
|
-
configuration
|
|
321
|
-
);
|
|
322
|
-
if (uploaded == null)
|
|
323
|
-
return;
|
|
324
|
-
if (uploaded.every((url) => url == null)) {
|
|
325
|
-
throw new Error("Could not upload any BG removed image");
|
|
326
|
-
}
|
|
327
|
-
const newSourceSet = initialSourceSet.map((source, index) => {
|
|
328
|
-
return {
|
|
329
|
-
...source,
|
|
330
|
-
uri: uploaded[index]
|
|
331
|
-
};
|
|
332
|
-
});
|
|
333
|
-
setBGRemovalMetadata(cesdk, blockId, {
|
|
334
|
-
version: "0.1.0",
|
|
335
|
-
initialSourceSet,
|
|
336
|
-
initialImageFileURI,
|
|
337
|
-
blockId,
|
|
338
|
-
fillId,
|
|
339
|
-
status: "PROCESSED_WITHOUT_BG",
|
|
340
|
-
removedBackground: newSourceSet
|
|
341
|
-
});
|
|
342
|
-
blockApi.setSourceSet(fillId, "fill/image/sourceSet", newSourceSet);
|
|
343
|
-
} else {
|
|
344
|
-
const uploaded = await maskSourceSet(
|
|
345
|
-
cesdk,
|
|
346
|
-
blockId,
|
|
347
|
-
[{ uri: uriToProcess }],
|
|
348
|
-
mask,
|
|
349
|
-
configuration
|
|
350
|
-
);
|
|
351
|
-
if (uploaded == null)
|
|
352
|
-
return;
|
|
353
|
-
const uploadedUrl = uploaded[0];
|
|
354
|
-
if (uploadedUrl == null) {
|
|
355
|
-
throw new Error("Could not upload BG removed image");
|
|
356
|
-
}
|
|
357
|
-
setBGRemovalMetadata(cesdk, blockId, {
|
|
358
|
-
version: "0.1.0",
|
|
359
|
-
initialSourceSet,
|
|
360
|
-
initialImageFileURI,
|
|
361
|
-
blockId,
|
|
362
|
-
fillId,
|
|
363
|
-
status: "PROCESSED_WITHOUT_BG",
|
|
364
|
-
removedBackground: uploadedUrl
|
|
365
|
-
});
|
|
366
|
-
blockApi.setString(fillId, "fill/image/imageFileURI", uploadedUrl);
|
|
367
|
-
}
|
|
368
|
-
cesdk.engine.editor.addUndoStep();
|
|
369
|
-
} catch (error) {
|
|
370
|
-
if (cesdk.engine.block.isValid(blockId)) {
|
|
371
|
-
setBGRemovalMetadata(cesdk, blockId, {
|
|
372
|
-
version: "0.1.0",
|
|
373
|
-
initialSourceSet,
|
|
374
|
-
initialImageFileURI,
|
|
375
|
-
blockId,
|
|
376
|
-
fillId,
|
|
377
|
-
status: "ERROR"
|
|
378
|
-
});
|
|
379
|
-
recoverInitialImageData(cesdk, blockId);
|
|
380
|
-
}
|
|
381
|
-
console.log(error);
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
async function maskSourceSet(cesdk, blockId, urisOrSources, mask, configurationFromArgs) {
|
|
385
|
-
const configuration = {
|
|
386
|
-
...configurationFromArgs,
|
|
387
|
-
progress: throttle((key, current, total) => {
|
|
388
|
-
const metadataDuringProgress = getBGRemovalMetadata(cesdk, blockId);
|
|
389
|
-
if (metadataDuringProgress.status !== "PROCESSING" || !isMetadataConsistent(cesdk, blockId))
|
|
390
|
-
return;
|
|
391
|
-
configurationFromArgs.progress?.(key, current, total);
|
|
392
|
-
setBGRemovalMetadata(cesdk, blockId, {
|
|
393
|
-
...metadataDuringProgress,
|
|
394
|
-
progress: { key, current, total }
|
|
395
|
-
});
|
|
396
|
-
}, 100)
|
|
397
|
-
};
|
|
398
|
-
const masked = await Promise.all(
|
|
399
|
-
urisOrSources.map(async (source) => {
|
|
400
|
-
const blob = await applySegmentationMask(source.uri, mask, configuration);
|
|
401
|
-
return [blob, source];
|
|
402
|
-
})
|
|
403
|
-
);
|
|
404
|
-
if (getBGRemovalMetadata(cesdk, blockId).status !== "PROCESSING" || !isMetadataConsistent(cesdk, blockId))
|
|
405
|
-
return;
|
|
406
|
-
const uploaded = await Promise.all(
|
|
407
|
-
masked.map(async ([blob, source]) => {
|
|
408
|
-
const pathname = new URL(source.uri).pathname;
|
|
409
|
-
const parts = pathname.split("/");
|
|
410
|
-
const filename = parts[parts.length - 1];
|
|
411
|
-
const uploadedAssets = await cesdk.unstable_upload(
|
|
412
|
-
new File([blob], filename, { type: blob.type }),
|
|
413
|
-
() => {
|
|
414
|
-
}
|
|
415
|
-
);
|
|
416
|
-
const url = uploadedAssets.meta?.uri;
|
|
417
|
-
if (url == null) {
|
|
418
|
-
throw new Error("Could not upload BG removed image");
|
|
419
|
-
}
|
|
420
|
-
return [url, source];
|
|
421
|
-
})
|
|
422
|
-
);
|
|
423
|
-
if (getBGRemovalMetadata(cesdk, blockId).status !== "PROCESSING" || !isMetadataConsistent(cesdk, blockId))
|
|
424
|
-
return;
|
|
425
|
-
return uploaded.map(([url]) => url);
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
// src/plugin.ts
|
|
429
|
-
var plugin_default = (pluginConfiguration = {}) => {
|
|
430
|
-
const backgroundRemovalConfiguration = pluginConfiguration?.backgroundRemoval ?? {};
|
|
431
|
-
return {
|
|
432
|
-
initialize() {
|
|
433
|
-
},
|
|
434
|
-
update() {
|
|
435
|
-
},
|
|
436
|
-
initializeUserInterface({ cesdk }) {
|
|
437
|
-
cesdk.engine.event.subscribe([], async (events) => {
|
|
438
|
-
events.forEach((e) => {
|
|
439
|
-
const id = e.block;
|
|
440
|
-
if (!cesdk.engine.block.isValid(id) || !cesdk.engine.block.hasMetadata(id, BG_REMOVAL_ID)) {
|
|
441
|
-
return;
|
|
442
|
-
}
|
|
443
|
-
if (e.type === "Created") {
|
|
444
|
-
const metadata = getBGRemovalMetadata(cesdk, id);
|
|
445
|
-
if (isDuplicate(cesdk, id, metadata)) {
|
|
446
|
-
fixDuplicateMetadata(cesdk, id);
|
|
447
|
-
}
|
|
448
|
-
} else if (e.type === "Updated") {
|
|
449
|
-
handleUpdateEvent(cesdk, id, backgroundRemovalConfiguration);
|
|
450
|
-
}
|
|
451
|
-
});
|
|
452
|
-
});
|
|
453
|
-
registerComponents(cesdk);
|
|
454
|
-
enableFeatures(cesdk);
|
|
455
|
-
}
|
|
456
|
-
};
|
|
457
|
-
};
|
|
458
|
-
async function handleUpdateEvent(cesdk, blockId, configuration) {
|
|
459
|
-
const metadata = getBGRemovalMetadata(cesdk, blockId);
|
|
460
|
-
switch (metadata.status) {
|
|
461
|
-
case "PENDING": {
|
|
462
|
-
if (cesdk.feature.unstable_isEnabled(FEATURE_ID, {
|
|
463
|
-
engine: cesdk.engine
|
|
464
|
-
})) {
|
|
465
|
-
processBackgroundRemoval(cesdk, blockId, configuration);
|
|
466
|
-
}
|
|
467
|
-
break;
|
|
468
|
-
}
|
|
469
|
-
case "PROCESSING":
|
|
470
|
-
case "PROCESSED_WITH_BG":
|
|
471
|
-
case "PROCESSED_WITHOUT_BG": {
|
|
472
|
-
if (!isMetadataConsistent(cesdk, blockId)) {
|
|
473
|
-
clearBGRemovalMetadata(cesdk, blockId);
|
|
474
|
-
}
|
|
475
|
-
break;
|
|
476
|
-
}
|
|
477
|
-
default: {
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
// src/index.ts
|
|
483
|
-
var Plugin = (pluginConfiguration) => ({
|
|
484
|
-
name: BG_REMOVAL_ID,
|
|
485
|
-
version: "0.1.0",
|
|
486
|
-
...plugin_default(pluginConfiguration)
|
|
487
|
-
});
|
|
488
|
-
var src_default = Plugin;
|
|
489
|
-
export {
|
|
490
|
-
src_default as default
|
|
491
|
-
};
|
|
1
|
+
var m="@imgly/plugin-background-removal-web",R=`${m}.canvasMenu`,I=`${R}.button`,E=`${m}.feature`;import v from"lodash/isEqual";function p(e,t,i){e.engine.block.setMetadata(t,m,JSON.stringify(i))}function g(e,t){return e.engine.block.hasMetadata(t,m)?JSON.parse(e.engine.block.getMetadata(t,m)):{status:"IDLE"}}function D(e,t){e.engine.block.hasMetadata(t,m)&&e.engine.block.removeMetadata(t,m)}function N(e,t,i){if(!e.engine.block.isValid(t)||i.status==="IDLE"||i.status==="PENDING"||i.status==="ERROR"||!e.engine.block.hasFill(t))return!1;let n=e.engine.block.getFill(t);return!(i.blockId===t||i.fillId===n)}function U(e,t){let i=e.engine.block.getFill(t),n=g(e,t);n.status==="IDLE"||n.status==="PENDING"||n.status==="ERROR"||p(e,t,{...n,blockId:t,fillId:i})}function d(e,t){if(!e.engine.block.isValid(t))return!1;let i=g(e,t);if(i.status==="IDLE"||i.status==="PENDING")return!0;if(!e.engine.block.hasFill(t))return!1;let n=e.engine.block.getFill(t);if(n==null||t!==i.blockId||n!==i.fillId)return!1;let r=e.engine.block.getSourceSet(n,"fill/image/sourceSet"),a=e.engine.block.getString(n,"fill/image/imageFileURI");if(r.length===0&&!a&&i.status==="PROCESSING")return!0;if(r?.length>0){let l=i.initialSourceSet;if(i.status==="PROCESSED"){let u=i.removedBackground;if(!v(r,u)&&!v(r,l))return!1}else if(!v(r,l))return!1}else if(i.status==="PROCESSED"){if(a!==i.initialImageFileURI&&a!==i.removedBackground)return!1}else if(a!==i.initialImageFileURI)return!1;return!0}function b(e,t){if(!e.engine.block.hasFill(t))return;let n=g(e,t);if(n.status==="PENDING"||n.status==="IDLE")return;let r=n.initialSourceSet,a=n.initialImageFileURI,l=n.initialPreviewFileURI,u=G(e,t,n);u!=null&&(a&&e.engine.block.setString(u,"fill/image/imageFileURI",a),l&&e.engine.block.setString(u,"fill/image/previewFileURI",l),r.length>0&&e.engine.block.setSourceSet(u,"fill/image/sourceSet",r))}function G(e,t,i){if(!e.engine.block.isValid(t)||!e.engine.block.hasFill(t)||t!==i.blockId)return;let n=e.engine.block.getFill(t);if(n===i.fillId)return n}function h(e){e.feature.unstable_enable(E,({engine:t})=>{let i=t.block.findAllSelected();if(i.length!==1)return!1;let[n]=i;if(e.engine.block.hasFill(n)){let r=e.engine.block.getFill(n);if(e.engine.block.getType(r)!=="//ly.img.ubq/fill/image")return!1;let l=t.block.getString(r,"fill/image/imageFileURI");return t.block.getSourceSet(r,"fill/image/sourceSet").length>0||l!==""?!0:g(e,n).status==="PROCESSING"}return!1})}import{applySegmentationMask as w,segmentForeground as B}from"@imgly/background-removal";import A from"lodash/throttle";async function F(e,t,i){let n=e.engine.block;if(!n.hasFill(t))throw new Error("Block has no fill to remove the background from");let r=n.getFill(t),a=n.getSourceSet(r,"fill/image/sourceSet"),l=n.getString(r,"fill/image/imageFileURI"),u=n.getString(r,"fill/image/previewFileURI");try{n.setString(r,"fill/image/imageFileURI",""),n.setSourceSet(r,"fill/image/sourceSet",[]);let o=g(e,t);p(e,t,{...o,version:"0.2.0",initialSourceSet:a,initialImageFileURI:l,initialPreviewFileURI:u,blockId:t,fillId:r,status:"PROCESSING"});let f=a.length>0?a.sort((s,c)=>c.width*c.height-s.height*s.width)[0].uri:l;u||n.setString(r,"fill/image/previewFileURI",f);let S=await B(f,i);if(a.length>0){let s=await O(e,t,a,S,i);if(s==null)return;if(s.every(P=>P==null))throw new Error("Could not upload any BG removed image");let c=a.map((P,C)=>({...P,uri:s[C]}));p(e,t,{version:"0.2.0",initialSourceSet:a,initialImageFileURI:l,initialPreviewFileURI:u,blockId:t,fillId:r,status:"PROCESSED",removedBackground:c}),n.setSourceSet(r,"fill/image/sourceSet",c),n.setString(r,"fill/image/previewFileURI","")}else{let s=await O(e,t,[{uri:f}],S,i);if(s==null)return;let c=s[0];if(c==null)throw new Error("Could not upload BG removed image");p(e,t,{version:"0.2.0",initialSourceSet:a,initialImageFileURI:l,initialPreviewFileURI:u,blockId:t,fillId:r,status:"PROCESSED",removedBackground:c}),n.setString(r,"fill/image/imageFileURI",c),n.setString(r,"fill/image/previewFileURI","")}e.engine.editor.addUndoStep()}catch(o){e.engine.block.isValid(t)&&(p(e,t,{version:"0.2.0",initialSourceSet:a,initialImageFileURI:l,initialPreviewFileURI:u,blockId:t,fillId:r,status:"ERROR"}),b(e,t)),console.log(o)}}async function O(e,t,i,n,r){let a={...r,progress:A((o,f,S)=>{let s=g(e,t);s.status!=="PROCESSING"||!d(e,t)||(r.progress?.(o,f,S),p(e,t,{...s,progress:{key:o,current:f,total:S}}))},100)},l=await Promise.all(i.map(async o=>[await w(o.uri,n,a),o]));if(g(e,t).status!=="PROCESSING"||!d(e,t))return;let u=await Promise.all(l.map(async([o,f])=>{let s=new URL(f.uri).pathname.split("/"),c=s[s.length-1],C=(await e.unstable_upload(new File([o],c,{type:o.type}),()=>{})).meta?.uri;if(C==null)throw new Error("Could not upload BG removed image");return[C,f]}));if(!(g(e,t).status!=="PROCESSING"||!d(e,t)))return u.map(([o])=>o)}var M=`plugin.${m}.action.removeBackground`;function _(e,t={}){T("canvasMenu",t)&&e.ui.unstable_setCanvasMenuOrder([R,...e.ui.unstable_getCanvasMenuOrder()]),e.setTranslations({en:{[M]:"BG Removal"}}),e.ui.unstable_registerComponent(R,({builder:{Button:i},engine:n})=>{if(!e.feature.unstable_isEnabled(E,{engine:n}))return;let[r]=n.block.findAllSelected(),a=g(e,r),l=a.status==="PROCESSING",u=a.status==="PENDING"||a.status==="PROCESSING",o;if(l&&a.progress){let{key:f,current:S,total:s}=a.progress;f==="compute:inference"?o=void 0:f.startsWith("fetch:/models/")?o=S/s*50:f.startsWith("fetch:/onnxruntime-web/")?o=50+S/s*50:o=void 0}i(I,{label:M,icon:"@imgly/icons/BGRemove",isLoading:l,isDisabled:u,loadingProgress:o,onClick:()=>{(a.status==="IDLE"||a.status==="ERROR"||a.status==="PROCESSED")&&p(e,r,{status:"PENDING"})}})})}function T(e,t){return t.locations&&(Array.isArray(t.locations)?t.locations:[t.locations]).includes(e)}var y=(e={})=>{let t=e?.backgroundRemoval??{};return{initialize(){},update(){},initializeUserInterface({cesdk:i}){i.engine.event.subscribe([],async n=>{n.forEach(r=>{let a=r.block;if(!(!i.engine.block.isValid(a)||!i.engine.block.hasMetadata(a,m)))if(r.type==="Created"){let l=g(i,a);N(i,a,l)&&U(i,a)}else r.type==="Updated"&&x(i,a,t)})}),_(i,e.ui),h(i)}}};async function x(e,t,i){switch(g(e,t).status){case"PENDING":{e.feature.unstable_isEnabled(E,{engine:e.engine})&&F(e,t,i);break}case"PROCESSING":case"PROCESSED":{d(e,t)||D(e,t);break}default:}}var K=e=>({name:m,version:"0.2.0",...y(e)}),se=K;export{se as default};
|
|
492
2
|
//# sourceMappingURL=index.mjs.map
|