LL3RD commited on
Commit
4a51e72
·
1 Parent(s): 473b105
Files changed (1) hide show
  1. app.py +120 -119
app.py CHANGED
@@ -35,7 +35,7 @@ def remove_bg(image):
35
  mask = transforms.ToPILImage()(preds).resize(im.size)
36
  return mask
37
 
38
- class DreamblendGUI:
39
  def __init__(self):
40
  self.examples = [
41
  ["./examples/9_02.png",
@@ -174,124 +174,121 @@ class DreamblendGUI:
174
  };
175
 
176
  globalThis.initializeDrag = () => {
177
- console.log("初始化拖拽与缩放功能...");
178
- const observer = new MutationObserver(() => {
179
- const img = document.getElementById('draggable-img');
180
- const container = document.getElementById('canvas-container');
181
- const slider = document.getElementById('scale-slider');
182
- if (img && container && slider) {
183
- observer.disconnect();
184
- console.log("绑定拖拽与缩放事件...");
185
- img.ondragstart = (e) => { e.preventDefault(); return false; };
186
- let offsetX = 0, offsetY = 0;
187
- let isDragging = false;
188
- let scaleAnchor = null;
189
-
190
- img.addEventListener('mousedown', (e) => {
191
- isDragging = true;
192
- img.style.cursor = 'grabbing';
193
- const imgRect = img.getBoundingClientRect();
194
- offsetX = e.clientX - imgRect.left;
195
- offsetY = e.clientY - imgRect.top;
196
- img.style.transform = "none";
197
- img.style.left = img.offsetLeft + "px";
198
- img.style.top = img.offsetTop + "px";
199
- console.log("mousedown: left=", img.style.left, "top=", img.style.top);
200
- });
201
- document.addEventListener('mousemove', (e) => {
202
- if (!isDragging) return;
203
- e.preventDefault();
204
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
205
  const containerRect = container.getBoundingClientRect();
206
- // 计算当前拖拽后的坐标(基于容器)
207
- let left = e.clientX - containerRect.left - offsetX;
208
- let top = e.clientY - containerRect.top - offsetY;
209
-
210
- // 允许的拖拽范围:
211
- // 水平方向允许最少超出图像一半:最小值为 -img.clientWidth * (7/8)
212
- // 水平方向允许最多超出一半:最大值为 containerRect.width - img.clientWidth * (1/8)
213
- const minLeft = -img.clientWidth * (7/8);
214
- const maxLeft = containerRect.width - img.clientWidth * (1/8);
215
-
216
- // 垂直方向允许范围:
217
- // 最小值为 -img.clientHeight * (7/8)
218
- // 最大值为 containerRect.height - img.clientHeight * (1/8)
219
- const minTop = -img.clientHeight * (7/8);
220
- const maxTop = containerRect.height - img.clientHeight * (1/8);
221
-
222
- // 限制范围
223
- if (left < minLeft) left = minLeft;
224
- if (left > maxLeft) left = maxLeft;
225
-
226
- if (top < minTop) top = minTop;
227
- if (top > maxTop) top = maxTop;
228
-
229
- img.style.left = left + "px";
230
- img.style.top = top + "px";
231
- });
232
-
233
- window.addEventListener('mouseup', (e) => {
234
- if (isDragging) {
235
- isDragging = false;
236
- img.style.cursor = 'grab';
237
- const containerRect = container.getBoundingClientRect();
238
- const bgWidth = parseFloat(container.dataset.bgWidth);
239
- const bgHeight = parseFloat(container.dataset.bgHeight);
240
- const offsetLeft = (containerRect.width - bgWidth) / 2;
241
- const offsetTop = (containerRect.height - bgHeight) / 2;
242
- const absoluteLeft = parseFloat(img.style.left);
243
- const absoluteTop = parseFloat(img.style.top);
244
- const relativeX = absoluteLeft - offsetLeft;
245
- const relativeY = absoluteTop - offsetTop;
246
- document.getElementById("coordinate").textContent =
247
- `前景图坐标: (x=${relativeX.toFixed(2)}, y=${relativeY.toFixed(2)})`;
248
- updateTransformation();
249
- }
250
- scaleAnchor = null;
251
- });
252
-
253
- slider.addEventListener('mousedown', (e) => {
254
- const containerRect = container.getBoundingClientRect();
255
- const imgRect = img.getBoundingClientRect();
256
- scaleAnchor = {
257
- x: imgRect.left + imgRect.width/2 - containerRect.left,
258
- y: imgRect.top + imgRect.height/2 - containerRect.top
259
- };
260
- console.log("Slider mousedown, captured scaleAnchor: ", scaleAnchor);
261
- });
262
-
263
- slider.addEventListener('input', (e) => {
264
- const scale = parseFloat(e.target.value);
265
- const originalWidth = parseFloat(img.getAttribute('data-original-width'));
266
- const originalHeight = parseFloat(img.getAttribute('data-original-height'));
267
- const newWidth = originalWidth * scale;
268
- const newHeight = originalHeight * scale;
269
- const containerRect = container.getBoundingClientRect();
270
- let centerX, centerY;
271
- if (scaleAnchor) {
272
- centerX = scaleAnchor.x;
273
- centerY = scaleAnchor.y;
274
- } else {
275
- const imgRect = img.getBoundingClientRect();
276
- centerX = imgRect.left + imgRect.width/2 - containerRect.left;
277
- centerY = imgRect.top + imgRect.height/2 - containerRect.top;
278
- }
279
- const newLeft = centerX - newWidth/2;
280
- const newTop = centerY - newHeight/2;
281
- img.style.width = newWidth + "px";
282
- img.style.height = newHeight + "px";
283
- img.style.left = newLeft + "px";
284
- img.style.top = newTop + "px";
285
- console.log("slider: scale=", scale, "newWidth=", newWidth, "newHeight=", newHeight);
286
- updateTransformation();
287
- });
288
-
289
- slider.addEventListener('mouseup', (e) => {
290
- scaleAnchor = null;
291
- });
292
  }
 
 
 
 
 
 
 
 
 
 
 
293
  });
294
- observer.observe(document.body, { childList: true, subtree: true });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
295
  };
296
  }
297
  """
@@ -522,7 +519,13 @@ class DreamblendGUI:
522
  fn=self.on_upload,
523
  inputs=[background_img_in, draggable_img_in],
524
  outputs=[html_out, modified_fg_state],
 
 
 
 
 
525
  )
 
526
  model_generate_btn.click(
527
  fn=pipeline.gradio_generate,
528
  # fn=self.pil_to_base64,
@@ -538,9 +541,7 @@ class DreamblendGUI:
538
 
539
  if __name__ == "__main__":
540
 
541
- gui = DreamblendGUI()
542
  demo = gui.create_gui()
543
  demo.queue()
544
  demo.launch()
545
- # demo.launch(server_port=7789, ssr_mode=False)
546
- # demo.launch(server_name="[::]", share=True)
 
35
  mask = transforms.ToPILImage()(preds).resize(im.size)
36
  return mask
37
 
38
+ class DreamFuseGUI:
39
  def __init__(self):
40
  self.examples = [
41
  ["./examples/9_02.png",
 
174
  };
175
 
176
  globalThis.initializeDrag = () => {
177
+ console.log("初始化拖拽与缩放功能...");
178
+
179
+ const oldImg = document.getElementById('draggable-img');
180
+ const container = document.getElementById('canvas-container');
181
+ const slider = document.getElementById('scale-slider');
182
+
183
+ if (!oldImg || !container || !slider) {
184
+ console.warn("❌ 缺少必要的元素 (#draggable-img, #canvas-container, #scale-slider)");
185
+ return;
186
+ }
187
+
188
+ // clone 替换旧 img,清除之前的监听器
189
+ const img = oldImg.cloneNode(true);
190
+ oldImg.replaceWith(img);
191
+
192
+ img.ondragstart = (e) => { e.preventDefault(); return false; };
193
+ let offsetX = 0, offsetY = 0;
194
+ let isDragging = false;
195
+ let scaleAnchor = null;
196
+
197
+ img.addEventListener('mousedown', (e) => {
198
+ isDragging = true;
199
+ img.style.cursor = 'grabbing';
200
+ const imgRect = img.getBoundingClientRect();
201
+ offsetX = e.clientX - imgRect.left;
202
+ offsetY = e.clientY - imgRect.top;
203
+ img.style.transform = "none";
204
+ img.style.left = img.offsetLeft + "px";
205
+ img.style.top = img.offsetTop + "px";
206
+ console.log("mousedown: left=", img.style.left, "top=", img.style.top);
207
+ });
208
+
209
+ document.addEventListener('mousemove', (e) => {
210
+ if (!isDragging) return;
211
+ e.preventDefault();
212
+
213
+ const containerRect = container.getBoundingClientRect();
214
+ let left = e.clientX - containerRect.left - offsetX;
215
+ let top = e.clientY - containerRect.top - offsetY;
216
+
217
+ const minLeft = -img.clientWidth * (7/8);
218
+ const maxLeft = containerRect.width - img.clientWidth * (1/8);
219
+ const minTop = -img.clientHeight * (7/8);
220
+ const maxTop = containerRect.height - img.clientHeight * (1/8);
221
+
222
+ if (left < minLeft) left = minLeft;
223
+ if (left > maxLeft) left = maxLeft;
224
+ if (top < minTop) top = minTop;
225
+ if (top > maxTop) top = maxTop;
226
+
227
+ img.style.left = left + "px";
228
+ img.style.top = top + "px";
229
+ });
230
+
231
+ window.addEventListener('mouseup', (e) => {
232
+ if (isDragging) {
233
+ isDragging = false;
234
+ img.style.cursor = 'grab';
235
  const containerRect = container.getBoundingClientRect();
236
+ const bgWidth = parseFloat(container.dataset.bgWidth);
237
+ const bgHeight = parseFloat(container.dataset.bgHeight);
238
+ const offsetLeft = (containerRect.width - bgWidth) / 2;
239
+ const offsetTop = (containerRect.height - bgHeight) / 2;
240
+ const absoluteLeft = parseFloat(img.style.left);
241
+ const absoluteTop = parseFloat(img.style.top);
242
+ const relativeX = absoluteLeft - offsetLeft;
243
+ const relativeY = absoluteTop - offsetTop;
244
+ document.getElementById("coordinate").textContent =
245
+ `前景图坐标: (x=${relativeX.toFixed(2)}, y=${relativeY.toFixed(2)})`;
246
+ updateTransformation();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
  }
248
+ scaleAnchor = null;
249
+ });
250
+
251
+ slider.addEventListener('mousedown', (e) => {
252
+ const containerRect = container.getBoundingClientRect();
253
+ const imgRect = img.getBoundingClientRect();
254
+ scaleAnchor = {
255
+ x: imgRect.left + imgRect.width/2 - containerRect.left,
256
+ y: imgRect.top + imgRect.height/2 - containerRect.top
257
+ };
258
+ console.log("Slider mousedown, captured scaleAnchor: ", scaleAnchor);
259
  });
260
+
261
+ slider.addEventListener('input', (e) => {
262
+ const scale = parseFloat(e.target.value);
263
+ const originalWidth = parseFloat(img.getAttribute('data-original-width'));
264
+ const originalHeight = parseFloat(img.getAttribute('data-original-height'));
265
+ const newWidth = originalWidth * scale;
266
+ const newHeight = originalHeight * scale;
267
+ const containerRect = container.getBoundingClientRect();
268
+ let centerX, centerY;
269
+ if (scaleAnchor) {
270
+ centerX = scaleAnchor.x;
271
+ centerY = scaleAnchor.y;
272
+ } else {
273
+ const imgRect = img.getBoundingClientRect();
274
+ centerX = imgRect.left + imgRect.width/2 - containerRect.left;
275
+ centerY = imgRect.top + imgRect.height/2 - containerRect.top;
276
+ }
277
+ const newLeft = centerX - newWidth/2;
278
+ const newTop = centerY - newHeight/2;
279
+ img.style.width = newWidth + "px";
280
+ img.style.height = newHeight + "px";
281
+ img.style.left = newLeft + "px";
282
+ img.style.top = newTop + "px";
283
+ console.log("slider: scale=", scale, "newWidth=", newWidth, "newHeight=", newHeight);
284
+ updateTransformation();
285
+ });
286
+
287
+ slider.addEventListener('mouseup', (e) => {
288
+ scaleAnchor = null;
289
+ });
290
+
291
+ console.log("✅ 拖拽和缩放事件已绑定");
292
  };
293
  }
294
  """
 
519
  fn=self.on_upload,
520
  inputs=[background_img_in, draggable_img_in],
521
  outputs=[html_out, modified_fg_state],
522
+ ).then(
523
+ fn=None,
524
+ inputs=None,
525
+ outputs=None,
526
+ js="initializeDrag"
527
  )
528
+
529
  model_generate_btn.click(
530
  fn=pipeline.gradio_generate,
531
  # fn=self.pil_to_base64,
 
541
 
542
  if __name__ == "__main__":
543
 
544
+ gui = DreamFuseGUI()
545
  demo = gui.create_gui()
546
  demo.queue()
547
  demo.launch()