@gradio/imageeditor 0.14.5 → 0.15.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/CHANGELOG.md +14 -0
- package/InteractiveImageEditor.svelte +4 -7
- package/dist/InteractiveImageEditor.svelte +4 -3
- package/dist/InteractiveImageEditor.svelte.d.ts +1 -1
- package/dist/shared/Controls.svelte +32 -1
- package/dist/shared/Controls.svelte.d.ts +2 -0
- package/dist/shared/ImageEditor.svelte +23 -1
- package/dist/shared/ImageEditor.svelte.d.ts +2 -1
- package/dist/shared/brush/brush-cursor.js +0 -42
- package/dist/shared/brush/brush-textures.d.ts +19 -2
- package/dist/shared/brush/brush-textures.js +120 -82
- package/dist/shared/brush/brush.js +0 -52
- package/dist/shared/{utils → core}/commands.d.ts +19 -58
- package/dist/shared/core/commands.js +70 -0
- package/dist/shared/core/editor.d.ts +4 -91
- package/dist/shared/core/editor.js +18 -708
- package/dist/shared/core/layers.d.ts +143 -0
- package/dist/shared/core/layers.js +774 -0
- package/dist/shared/image/image.d.ts +14 -4
- package/dist/shared/image/image.js +91 -18
- package/dist/shared/resize/resize.d.ts +31 -0
- package/dist/shared/resize/resize.js +127 -290
- package/dist/shared/zoom/zoom.js +0 -51
- package/package.json +7 -7
- package/shared/Controls.svelte +33 -1
- package/shared/ImageEditor.svelte +25 -9
- package/shared/Toolbar.svelte +1 -4
- package/shared/brush/ColorSwatch.svelte +0 -3
- package/shared/brush/brush-cursor.ts +0 -42
- package/shared/brush/brush-textures.ts +166 -83
- package/shared/brush/brush.ts +0 -53
- package/shared/core/commands.ts +118 -0
- package/shared/core/editor.ts +33 -957
- package/shared/core/layers.ts +1068 -0
- package/shared/image/image.ts +139 -21
- package/shared/resize/resize.ts +160 -299
- package/shared/zoom/zoom.ts +0 -51
- package/dist/shared/utils/commands.js +0 -73
- package/shared/utils/commands.ts +0 -174
package/shared/image/image.ts
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from "pixi.js";
|
|
11
11
|
import { type ImageEditorContext, type Tool } from "../core/editor";
|
|
12
12
|
import { type Tool as ToolbarTool, type Subtool } from "../Toolbar.svelte";
|
|
13
|
-
import { type Command } from "../
|
|
13
|
+
import { type Command } from "../core/commands";
|
|
14
14
|
import { make_graphics } from "../utils/pixi";
|
|
15
15
|
import { get } from "svelte/store";
|
|
16
16
|
|
|
@@ -66,15 +66,16 @@ interface BgImageCommand extends Command {
|
|
|
66
66
|
* Initial setup for the bg command
|
|
67
67
|
* @returns
|
|
68
68
|
*/
|
|
69
|
-
start: () => Promise<
|
|
69
|
+
start: () => Promise<void>;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
export class AddImageCommand implements BgImageCommand {
|
|
73
|
-
sprite: Sprite;
|
|
73
|
+
sprite: Sprite | null = null;
|
|
74
74
|
fixed_canvas: boolean;
|
|
75
75
|
context: ImageEditorContext;
|
|
76
76
|
background: Blob | File | Texture;
|
|
77
77
|
current_canvas_size: { width: number; height: number };
|
|
78
|
+
computed_dimensions: { width: number; height: number };
|
|
78
79
|
current_scale: number;
|
|
79
80
|
current_position: { x: number; y: number };
|
|
80
81
|
border_region: number;
|
|
@@ -82,12 +83,23 @@ export class AddImageCommand implements BgImageCommand {
|
|
|
82
83
|
scaled_width!: number;
|
|
83
84
|
scaled_height!: number;
|
|
84
85
|
|
|
86
|
+
private previous_image: {
|
|
87
|
+
texture: Texture;
|
|
88
|
+
width: number;
|
|
89
|
+
height: number;
|
|
90
|
+
x: number;
|
|
91
|
+
y: number;
|
|
92
|
+
border_region: number;
|
|
93
|
+
} | null = null;
|
|
94
|
+
name: string;
|
|
95
|
+
|
|
85
96
|
constructor(
|
|
86
97
|
context: ImageEditorContext,
|
|
87
98
|
background: Blob | File | Texture,
|
|
88
99
|
fixed_canvas: boolean,
|
|
89
100
|
border_region = 0
|
|
90
101
|
) {
|
|
102
|
+
this.name = "AddImage";
|
|
91
103
|
this.context = context;
|
|
92
104
|
this.background = background;
|
|
93
105
|
this.fixed_canvas = fixed_canvas;
|
|
@@ -95,11 +107,50 @@ export class AddImageCommand implements BgImageCommand {
|
|
|
95
107
|
this.current_canvas_size = get(this.context.dimensions);
|
|
96
108
|
this.current_scale = get(this.context.scale);
|
|
97
109
|
this.current_position = get(this.context.position);
|
|
98
|
-
|
|
110
|
+
|
|
111
|
+
this.computed_dimensions = { width: 0, height: 0 };
|
|
112
|
+
|
|
113
|
+
if (
|
|
114
|
+
this.context.background_image &&
|
|
115
|
+
this.context.background_image.texture
|
|
116
|
+
) {
|
|
117
|
+
const bg = this.context.background_image;
|
|
118
|
+
const stored_border_region = (bg as any).borderRegion || 0;
|
|
119
|
+
|
|
120
|
+
this.previous_image = {
|
|
121
|
+
texture: this.clone_texture(bg.texture),
|
|
122
|
+
width: bg.width,
|
|
123
|
+
height: bg.height,
|
|
124
|
+
x: bg.position.x,
|
|
125
|
+
y: bg.position.y,
|
|
126
|
+
border_region: stored_border_region
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Creates a copy of a texture to avoid reference issues
|
|
133
|
+
*/
|
|
134
|
+
private clone_texture(texture: Texture): Texture {
|
|
135
|
+
const render_texture = RenderTexture.create({
|
|
136
|
+
width: texture.width,
|
|
137
|
+
height: texture.height,
|
|
138
|
+
resolution: window.devicePixelRatio || 1
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
const sprite = new Sprite(texture);
|
|
142
|
+
const container = new Container();
|
|
143
|
+
container.addChild(sprite);
|
|
144
|
+
|
|
145
|
+
this.context.app.renderer.render(container, {
|
|
146
|
+
renderTexture: render_texture
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
container.destroy({ children: true });
|
|
150
|
+
return render_texture;
|
|
99
151
|
}
|
|
100
152
|
|
|
101
|
-
async start(): Promise<
|
|
102
|
-
// Create the sprite from the blob
|
|
153
|
+
async start(): Promise<void> {
|
|
103
154
|
let image_texture: Texture;
|
|
104
155
|
if (this.background instanceof Texture) {
|
|
105
156
|
image_texture = this.background;
|
|
@@ -110,13 +161,15 @@ export class AddImageCommand implements BgImageCommand {
|
|
|
110
161
|
|
|
111
162
|
this.sprite = new Sprite(image_texture);
|
|
112
163
|
|
|
113
|
-
|
|
164
|
+
const [width, height] = this.handle_image();
|
|
165
|
+
this.computed_dimensions = { width, height };
|
|
114
166
|
}
|
|
115
167
|
|
|
116
168
|
private handle_image(): [number, number] {
|
|
117
|
-
|
|
169
|
+
if (this.sprite === null) {
|
|
170
|
+
return [0, 0];
|
|
171
|
+
}
|
|
118
172
|
if (this.fixed_canvas) {
|
|
119
|
-
// Calculate the effective canvas size accounting for border region
|
|
120
173
|
const effectiveCanvasWidth = Math.max(
|
|
121
174
|
this.current_canvas_size.width - this.border_region * 2,
|
|
122
175
|
10
|
|
@@ -126,8 +179,6 @@ export class AddImageCommand implements BgImageCommand {
|
|
|
126
179
|
10
|
|
127
180
|
);
|
|
128
181
|
|
|
129
|
-
// Fit the image to the canvas while maintaining aspect ratio
|
|
130
|
-
|
|
131
182
|
const { width, height, x, y } = fit_image_to_canvas(
|
|
132
183
|
this.sprite.width,
|
|
133
184
|
this.sprite.height,
|
|
@@ -138,15 +189,12 @@ export class AddImageCommand implements BgImageCommand {
|
|
|
138
189
|
this.sprite.width = width;
|
|
139
190
|
this.sprite.height = height;
|
|
140
191
|
|
|
141
|
-
// Center the image in the canvas
|
|
142
192
|
this.sprite.x = x + this.border_region;
|
|
143
193
|
this.sprite.y = y + this.border_region;
|
|
144
194
|
} else {
|
|
145
|
-
// For non-fixed canvas, use natural dimensions plus border
|
|
146
195
|
const width = this.sprite.width;
|
|
147
196
|
const height = this.sprite.height;
|
|
148
197
|
|
|
149
|
-
// Position at the border's offset from origin
|
|
150
198
|
this.sprite.x = this.border_region;
|
|
151
199
|
this.sprite.y = this.border_region;
|
|
152
200
|
|
|
@@ -157,12 +205,16 @@ export class AddImageCommand implements BgImageCommand {
|
|
|
157
205
|
}
|
|
158
206
|
|
|
159
207
|
async execute(): Promise<void> {
|
|
160
|
-
|
|
161
|
-
|
|
208
|
+
await this.start();
|
|
209
|
+
|
|
210
|
+
if (this.sprite === null) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const { width, height } = this.computed_dimensions;
|
|
162
215
|
|
|
163
|
-
// Update image properties with the original dimensions and center in viewport
|
|
164
216
|
await this.context.set_image_properties({
|
|
165
|
-
scale: 1,
|
|
217
|
+
scale: 1,
|
|
166
218
|
position: {
|
|
167
219
|
x: this.context.app.screen.width / 2,
|
|
168
220
|
y: this.context.app.screen.height / 2
|
|
@@ -171,7 +223,6 @@ export class AddImageCommand implements BgImageCommand {
|
|
|
171
223
|
height: this.fixed_canvas ? this.current_canvas_size.height : height
|
|
172
224
|
});
|
|
173
225
|
|
|
174
|
-
// Create new background layer and add the sprite
|
|
175
226
|
const background_layer = this.context.layer_manager.create_background_layer(
|
|
176
227
|
this.fixed_canvas ? this.current_canvas_size.width : width,
|
|
177
228
|
this.fixed_canvas ? this.current_canvas_size.height : height
|
|
@@ -179,13 +230,16 @@ export class AddImageCommand implements BgImageCommand {
|
|
|
179
230
|
this.sprite.zIndex = 0;
|
|
180
231
|
background_layer.addChild(this.sprite);
|
|
181
232
|
|
|
182
|
-
// Resize and preserve content of existing layers
|
|
183
233
|
this.context.layer_manager.reset_layers(
|
|
184
234
|
this.fixed_canvas ? this.current_canvas_size.width : width,
|
|
185
235
|
this.fixed_canvas ? this.current_canvas_size.height : height,
|
|
186
236
|
true
|
|
187
237
|
);
|
|
188
238
|
|
|
239
|
+
if (this.border_region > 0) {
|
|
240
|
+
(this.sprite as any).borderRegion = this.border_region;
|
|
241
|
+
}
|
|
242
|
+
|
|
189
243
|
this.context.set_background_image(this.sprite);
|
|
190
244
|
|
|
191
245
|
this.context.reset();
|
|
@@ -194,6 +248,70 @@ export class AddImageCommand implements BgImageCommand {
|
|
|
194
248
|
async undo(): Promise<void> {
|
|
195
249
|
if (this.sprite) {
|
|
196
250
|
this.sprite.destroy();
|
|
251
|
+
|
|
252
|
+
if (this.previous_image) {
|
|
253
|
+
const previous_sprite = new Sprite(this.previous_image.texture);
|
|
254
|
+
previous_sprite.width = this.previous_image.width;
|
|
255
|
+
previous_sprite.height = this.previous_image.height;
|
|
256
|
+
previous_sprite.position.set(
|
|
257
|
+
this.previous_image.x,
|
|
258
|
+
this.previous_image.y
|
|
259
|
+
);
|
|
260
|
+
|
|
261
|
+
if (this.previous_image.border_region > 0) {
|
|
262
|
+
(previous_sprite as any).borderRegion =
|
|
263
|
+
this.previous_image.border_region;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
await this.context.set_image_properties({
|
|
267
|
+
scale: 1,
|
|
268
|
+
position: {
|
|
269
|
+
x: this.context.app.screen.width / 2,
|
|
270
|
+
y: this.context.app.screen.height / 2
|
|
271
|
+
},
|
|
272
|
+
width: this.previous_image.width,
|
|
273
|
+
height: this.previous_image.height
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
const background_layer =
|
|
277
|
+
this.context.layer_manager.create_background_layer(
|
|
278
|
+
this.previous_image.width,
|
|
279
|
+
this.previous_image.height
|
|
280
|
+
);
|
|
281
|
+
|
|
282
|
+
previous_sprite.zIndex = 0;
|
|
283
|
+
background_layer.addChild(previous_sprite);
|
|
284
|
+
|
|
285
|
+
this.context.layer_manager.reset_layers(
|
|
286
|
+
this.previous_image.width,
|
|
287
|
+
this.previous_image.height,
|
|
288
|
+
true
|
|
289
|
+
);
|
|
290
|
+
|
|
291
|
+
this.context.set_background_image(previous_sprite);
|
|
292
|
+
} else {
|
|
293
|
+
await this.context.set_image_properties({
|
|
294
|
+
scale: 1,
|
|
295
|
+
position: {
|
|
296
|
+
x: this.context.app.screen.width / 2,
|
|
297
|
+
y: this.context.app.screen.height / 2
|
|
298
|
+
},
|
|
299
|
+
width: this.current_canvas_size.width,
|
|
300
|
+
height: this.current_canvas_size.height
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
this.context.layer_manager.create_background_layer(
|
|
304
|
+
this.current_canvas_size.width,
|
|
305
|
+
this.current_canvas_size.height
|
|
306
|
+
);
|
|
307
|
+
|
|
308
|
+
this.context.layer_manager.reset_layers(
|
|
309
|
+
this.current_canvas_size.width,
|
|
310
|
+
this.current_canvas_size.height
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
this.context.reset();
|
|
197
315
|
}
|
|
198
316
|
}
|
|
199
317
|
}
|
|
@@ -229,6 +347,7 @@ export function add_bg_color(
|
|
|
229
347
|
): BgColorCommand {
|
|
230
348
|
let sprite: Sprite;
|
|
231
349
|
return {
|
|
350
|
+
name: "AddBgColor",
|
|
232
351
|
start() {
|
|
233
352
|
container.removeChildren();
|
|
234
353
|
const graphics = make_graphics(1);
|
|
@@ -285,7 +404,6 @@ export function fit_image_to_canvas(
|
|
|
285
404
|
new_width = canvas_height * image_aspect_ratio;
|
|
286
405
|
}
|
|
287
406
|
|
|
288
|
-
// center image
|
|
289
407
|
const x = Math.round((canvas_width - new_width) / 2);
|
|
290
408
|
const y = Math.round((canvas_height - new_height) / 2);
|
|
291
409
|
|