Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] GUI Problem #205

Open
Wastoon opened this issue Sep 26, 2023 · 0 comments
Open

[Bug] GUI Problem #205

Wastoon opened this issue Sep 26, 2023 · 0 comments

Comments

@Wastoon
Copy link

Wastoon commented Sep 26, 2023

Describe the bug
When I use co-lab to run this demo, I could normally input prompt. But after I click start button, the canvas show such code instead of a image:

  • numpy - Pillow from pyodide import to_js, create_proxy from PIL import Image import io import time import base64 import numpy as np from js import ( console, document, parent, devicePixelRatio, ImageData, Uint8ClampedArray, CanvasRenderingContext2D as Context2d, requestAnimationFrame, window, encodeURIComponent, w2ui, update_eraser, update_scale, adjust_selection, update_count, enable_result_lst, setup_shortcut, ) import base64 import json import io import numpy as np from PIL import Image from pyodide import to_js, create_proxy import gc from js import ( console, document, devicePixelRatio, ImageData, Uint8ClampedArray, CanvasRenderingContext2D as Context2d, requestAnimationFrame, update_overlay, setup_overlay, window ) PAINT_SELECTION = "selection" IMAGE_SELECTION = "canvas" BRUSH_SELECTION = "eraser" NOP_MODE = 0 PAINT_MODE = 1 IMAGE_MODE = 2 BRUSH_MODE = 3 def hold_canvas(): pass def prepare_canvas(width, height, canvas) -> Context2d: ctx = canvas.getContext("2d") canvas.style.width = f"{width}px" canvas.style.height = f"{height}px" canvas.width = width canvas.height = height ctx.clearRect(0, 0, width, height) return ctx # class MultiCanvas: # def init(self,layer,width=800, height=600) -> None: # pass def multi_canvas(layer, width=800, height=600): lst = [ CanvasProxy(document.querySelector(f"#canvas{i}"), width, height) for i in range(layer) ] return lst class CanvasProxy: def init(self, canvas, width=800, height=600) -> None: self.canvas = canvas self.ctx = prepare_canvas(width, height, canvas) self.width = width self.height = height def clear_rect(self, x, y, w, h): self.ctx.clearRect(x, y, w, h) def clear(self,): self.clear_rect(0, 0, self.canvas.width, self.canvas.height) def stroke_rect(self, x, y, w, h): self.ctx.strokeRect(x, y, w, h) def fill_rect(self, x, y, w, h): self.ctx.fillRect(x, y, w, h) def put_image_data(self, image, x, y): data = Uint8ClampedArray.new(to_js(image.tobytes())) height, width, _ = image.shape image_data = ImageData.new(data, width, height) self.ctx.putImageData(image_data, x, y) del image_data # def draw_image(self,canvas, x, y, w, h): # self.ctx.drawImage(canvas,x,y,w,h) def draw_image(self,canvas, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight): self.ctx.drawImage(canvas, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) @Property def stroke_style(self): return self.ctx.strokeStyle @stroke_style.setter def stroke_style(self, value): self.ctx.strokeStyle = value @Property def fill_style(self): return self.ctx.strokeStyle @fill_style.setter def fill_style(self, value): self.ctx.fillStyle = value # RGBA for masking class InfCanvas: def init( self, width, height, selection_size=256, grid_size=64, patch_size=4096, test_mode=False, ) -> None: assert selection_size < min(height, width) self.width = width self.height = height self.display_width = width self.display_height = height self.canvas = multi_canvas(5, width=width, height=height) setup_overlay(width,height) # place at center self.view_pos = [patch_size//2-width//2, patch_size//2-height//2] self.cursor = [ width // 2 - selection_size // 2, height // 2 - selection_size // 2, ] self.data = {} self.grid_size = grid_size self.selection_size_w = selection_size self.selection_size_h = selection_size self.patch_size = patch_size # note that for image data, the height comes before width self.buffer = np.zeros((height, width, 4), dtype=np.uint8) self.sel_buffer = np.zeros((selection_size, selection_size, 4), dtype=np.uint8) self.sel_buffer_bak = np.zeros( (selection_size, selection_size, 4), dtype=np.uint8 ) self.sel_dirty = False self.buffer_dirty = False self.mouse_pos = [-1, -1] self.mouse_state = 0 # self.output = widgets.Output() self.test_mode = test_mode self.buffer_updated = False self.image_move_freq = 1 self.show_brush = False self.scale=1.0 self.eraser_size=32 def reset_large_buffer(self): self.canvas[2].canvas.width=self.width self.canvas[2].canvas.height=self.height # self.canvas[2].canvas.style.width=f"{self.display_width}px" # self.canvas[2].canvas.style.height=f"{self.display_height}px" self.canvas[2].canvas.style.display="block" self.canvas[2].clear() def draw_eraser(self, x, y): self.canvas[-2].clear() self.canvas[-2].fill_style = "#ffffff" self.canvas[-2].fill_rect(x-self.eraser_size//2,y-self.eraser_size//2,self.eraser_size,self.eraser_size) self.canvas[-2].stroke_rect(x-self.eraser_size//2,y-self.eraser_size//2,self.eraser_size,self.eraser_size) def use_eraser(self,x,y): if self.sel_dirty: self.write_selection_to_buffer() self.draw_buffer() self.canvas[2].clear() self.buffer_dirty=True bx0,by0=int(x)-self.eraser_size//2,int(y)-self.eraser_size//2 bx1,by1=bx0+self.eraser_size,by0+self.eraser_size bx0,by0=max(0,bx0),max(0,by0) bx1,by1=min(self.width,bx1),min(self.height,by1) self.buffer[by0:by1,bx0:bx1,:]=0 self.draw_buffer() self.draw_selection_box() def setup_mouse(self): self.image_move_cnt = 0 def get_mouse_mode(): mode = document.querySelector("#mode").value if mode == PAINT_SELECTION: return PAINT_MODE elif mode == IMAGE_SELECTION: return IMAGE_MODE return BRUSH_MODE def get_event_pos(event): canvas = self.canvas[-1].canvas rect = canvas.getBoundingClientRect() x = (canvas.width * (event.clientX - rect.left)) / rect.width y = (canvas.height * (event.clientY - rect.top)) / rect.height return x, y def handle_mouse_down(event): self.mouse_state = get_mouse_mode() if self.mouse_state==BRUSH_MODE: x,y=get_event_pos(event) self.use_eraser(x,y) def handle_mouse_out(event): last_state = self.mouse_state self.mouse_state = NOP_MODE self.image_move_cnt = 0 if last_state == IMAGE_MODE: self.update_view_pos(0, 0) if True: self.clear_background() self.draw_buffer() self.reset_large_buffer() self.draw_selection_box() gc.collect() if self.show_brush: self.canvas[-2].clear() self.show_brush = False def handle_mouse_up(event): last_state = self.mouse_state self.mouse_state = NOP_MODE self.image_move_cnt = 0 if last_state == IMAGE_MODE: self.update_view_pos(0, 0) if True: self.clear_background() self.draw_buffer() self.reset_large_buffer() self.draw_selection_box() gc.collect() async def handle_mouse_move(event): x, y = get_event_pos(event) x0, y0 = self.mouse_pos xo = x - x0 yo = y - y0 if self.mouse_state == PAINT_MODE: self.update_cursor(int(xo), int(yo)) if True: # self.clear_background() # console.log(self.buffer_updated) if self.buffer_updated: self.draw_buffer() self.buffer_updated = False self.draw_selection_box() elif self.mouse_state == IMAGE_MODE: self.image_move_cnt += 1 if self.image_move_cnt == self.image_move_freq: self.draw_buffer() self.canvas[2].clear() self.draw_selection_box() self.update_view_pos(int(xo), int(yo)) self.cached_view_pos=tuple(self.view_pos) self.canvas[2].canvas.style.display="none" large_buffer=self.data2array(self.view_pos[0]-self.width//2,self.view_pos[1]-self.height//2,min(self.width2,self.patch_size),min(self.height2,self.patch_size)) self.canvas[2].canvas.width=large_buffer.shape[1] self.canvas[2].canvas.height=large_buffer.shape[0] # self.canvas[2].canvas.style.width="" # self.canvas[2].canvas.style.height="" self.canvas[2].put_image_data(large_buffer,0,0) else: self.update_view_pos(int(xo), int(yo), False) self.canvas[1].clear() self.canvas[1].draw_image(self.canvas[2].canvas, self.width//2+(self.view_pos[0]-self.cached_view_pos[0]),self.height//2+(self.view_pos[1]-self.cached_view_pos[1]), self.width,self.height, 0,0,self.width,self.height ) self.clear_background() # self.image_move_cnt = 0 elif self.mouse_state == BRUSH_MODE: self.use_eraser(x,y) mode = document.querySelector("#mode").value if mode == BRUSH_SELECTION: self.draw_eraser(x,y) self.show_brush = True elif self.show_brush: self.canvas[-2].clear() self.show_brush = False self.mouse_pos[0] = x self.mouse_pos[1] = y self.canvas[-1].canvas.addEventListener( "mousedown", create_proxy(handle_mouse_down) ) self.canvas[-1].canvas.addEventListener( "mousemove", create_proxy(handle_mouse_move) ) self.canvas[-1].canvas.addEventListener( "mouseup", create_proxy(handle_mouse_up) ) self.canvas[-1].canvas.addEventListener( "mouseout", create_proxy(handle_mouse_out) ) async def handle_mouse_wheel(event): x, y = get_event_pos(event) self.mouse_pos[0] = x self.mouse_pos[1] = y console.log(to_js(self.mouse_pos)) if event.deltaY>10: window.postMessage(to_js(["click","zoom_out", self.mouse_pos[0], self.mouse_pos[1]]),"") elif event.deltaY<-10: window.postMessage(to_js(["click","zoom_in", self.mouse_pos[0], self.mouse_pos[1]]),"") return False self.canvas[-1].canvas.addEventListener( "wheel", create_proxy(handle_mouse_wheel), False ) def clear_background(self): # fake transparent background h, w, step = self.height, self.width, self.grid_size stride = step * 2 x0, y0 = self.view_pos x0 = (-x0) % stride y0 = (-y0) % stride if y0>=step: val0,val1=stride,step else: val0,val1=step,stride # self.canvas.clear() self.canvas[0].fill_style = "#ffffff" self.canvas[0].fill_rect(0, 0, w, h) self.canvas[0].fill_style = "#aaaaaa" for y in range(y0-stride, h + step, step): start = (x0 - val0) if y // step % 2 == 0 else (x0 - val1) for x in range(start, w + step, stride): self.canvas[0].fill_rect(x, y, step, step) self.canvas[0].stroke_rect(0, 0, w, h) def refine_selection(self): h,w=self.selection_size_h,self.selection_size_w h=min(h,self.height) w=min(w,self.width) self.selection_size_h=h8//8 self.selection_size_w=w8//8 self.update_cursor(1,0) def update_scale(self, scale, mx=-1, my=-1): self.sync_to_data() scaled_width=int(self.display_widthscale) scaled_height=int(self.display_heightscale) if max(scaled_height,scaled_width)>=self.patch_size2-128: return if scaled_height<=self.selection_size_h or scaled_width<=self.selection_size_w: return if mx>=0 and my>=0: scaled_mx=mx/self.scalescale scaled_my=my/self.scalescale self.view_pos[0]+=int(mx-scaled_mx) self.view_pos[1]+=int(my-scaled_my) self.scale=scale for item in self.canvas: item.canvas.width=scaled_width item.canvas.height=scaled_height item.clear() update_overlay(scaled_width,scaled_height) self.width=scaled_width self.height=scaled_height self.data2buffer() self.clear_background() self.draw_buffer() self.update_cursor(1,0) self.draw_selection_box() def update_view_pos(self, xo, yo, update=True): # if abs(xo) + abs(yo) == 0: # return if self.sel_dirty: self.write_selection_to_buffer() if self.buffer_dirty: self.buffer2data() self.view_pos[0] -= xo self.view_pos[1] -= yo if update: self.data2buffer() # self.read_selection_from_buffer() def update_cursor(self, xo, yo): if abs(xo) + abs(yo) == 0: return if self.sel_dirty: self.write_selection_to_buffer() self.cursor[0] += xo self.cursor[1] += yo self.cursor[0] = max(min(self.width - self.selection_size_w, self.cursor[0]), 0) self.cursor[1] = max(min(self.height - self.selection_size_h, self.cursor[1]), 0) # self.read_selection_from_buffer() def data2buffer(self): x, y = self.view_pos h, w = self.height, self.width if h!=self.buffer.shape[0] or w!=self.buffer.shape[1]: self.buffer=np.zeros((self.height, self.width, 4), dtype=np.uint8) # fill four parts for i in range(4): pos_src, pos_dst, data = self.select(x, y, i) xs0, xs1 = pos_src[0] ys0, ys1 = pos_src[1] xd0, xd1 = pos_dst[0] yd0, yd1 = pos_dst[1] self.buffer[yd0:yd1, xd0:xd1, :] = data[ys0:ys1, xs0:xs1, :] def data2array(self, x, y, w, h): # x, y = self.view_pos # h, w = self.height, self.width ret=np.zeros((h, w, 4), dtype=np.uint8) # fill four parts for i in range(4): pos_src, pos_dst, data = self.select(x, y, i, w, h) xs0, xs1 = pos_src[0] ys0, ys1 = pos_src[1] xd0, xd1 = pos_dst[0] yd0, yd1 = pos_dst[1] ret[yd0:yd1, xd0:xd1, :] = data[ys0:ys1, xs0:xs1, :] return ret def buffer2data(self): x, y = self.view_pos h, w = self.height, self.width # fill four parts for i in range(4): pos_src, pos_dst, data = self.select(x, y, i) xs0, xs1 = pos_src[0] ys0, ys1 = pos_src[1] xd0, xd1 = pos_dst[0] yd0, yd1 = pos_dst[1] data[ys0:ys1, xs0:xs1, :] = self.buffer[yd0:yd1, xd0:xd1, :] self.buffer_dirty = False def select(self, x, y, idx, width=0, height=0): if width==0: w, h = self.width, self.height else: w, h = width, height lst = [(0, 0), (0, h), (w, 0), (w, h)] if idx == 0: x0, y0 = x % self.patch_size, y % self.patch_size x1 = min(x0 + w, self.patch_size) y1 = min(y0 + h, self.patch_size) elif idx == 1: y += h x0, y0 = x % self.patch_size, y % self.patch_size x1 = min(x0 + w, self.patch_size) y1 = max(y0 - h, 0) elif idx == 2: x += w x0, y0 = x % self.patch_size, y % self.patch_size x1 = max(x0 - w, 0) y1 = min(y0 + h, self.patch_size) else: x += w y += h x0, y0 = x % self.patch_size, y % self.patch_size x1 = max(x0 - w, 0) y1 = max(y0 - h, 0) xi, yi = x // self.patch_size, y // self.patch_size cur = self.data.setdefault( (xi, yi), np.zeros((self.patch_size, self.patch_size, 4), dtype=np.uint8) ) x0_img, y0_img = lst[idx] x1_img = x0_img + x1 - x0 y1_img = y0_img + y1 - y0 sort = lambda a, b: ((a, b) if a < b else (b, a)) return ( (sort(x0, x1), sort(y0, y1)), (sort(x0_img, x1_img), sort(y0_img, y1_img)), cur, ) def draw_buffer(self): self.canvas[1].clear() self.canvas[1].put_image_data(self.buffer, 0, 0) def fill_selection(self, img): self.sel_buffer = img self.sel_dirty = True def draw_selection_box(self): x0, y0 = self.cursor w, h = self.selection_size_w, self.selection_size_h if self.sel_dirty: self.canvas[2].clear() self.canvas[2].put_image_data(self.sel_buffer, x0, y0) self.canvas[-1].clear() self.canvas[-1].stroke_style = "#0a0a0a" self.canvas[-1].stroke_rect(x0, y0, w, h) self.canvas[-1].stroke_style = "#ffffff" offset=round(self.scale) if self.scale>1.0 else 1 self.canvas[-1].stroke_rect(x0 - offset, y0 - offset, w + offset2, h + offset2) self.canvas[-1].stroke_style = "#000000" self.canvas[-1].stroke_rect(x0 - offset2, y0 - offset2, w + offset4, h + offset4) def write_selection_to_buffer(self): x0, y0 = self.cursor x1, y1 = x0 + self.selection_size_w, y0 + self.selection_size_h self.buffer[y0:y1, x0:x1] = self.sel_buffer self.sel_dirty = False self.sel_buffer = np.zeros( (self.selection_size_h, self.selection_size_w, 4), dtype=np.uint8 ) self.buffer_dirty = True self.buffer_updated = True # self.canvas[2].clear() def read_selection_from_buffer(self): x0, y0 = self.cursor x1, y1 = x0 + self.selection_size_w, y0 + self.selection_size_h self.sel_buffer = self.buffer[y0:y1, x0:x1] self.sel_dirty = False def base64_to_numpy(self, base64_str): try: data = base64.b64decode(str(base64_str)) pil = Image.open(io.BytesIO(data)) arr = np.array(pil) ret = arr except: ret = np.tile( np.array([255, 0, 0, 255], dtype=np.uint8), (self.selection_size_h, self.selection_size_w, 1), ) return ret def numpy_to_base64(self, arr): out_pil = Image.fromarray(arr) out_buffer = io.BytesIO() out_pil.save(out_buffer, format="PNG") out_buffer.seek(0) base64_bytes = base64.b64encode(out_buffer.read()) base64_str = base64_bytes.decode("ascii") return base64_str def sync_to_data(self): if self.sel_dirty: self.write_selection_to_buffer() self.canvas[2].clear() self.draw_buffer() if self.buffer_dirty: self.buffer2data() def sync_to_buffer(self): if self.sel_dirty: self.canvas[2].clear() self.write_selection_to_buffer() self.draw_buffer() def resize(self,width,height,scale=None,kwargs): self.display_width=width self.display_height=height for canvas in self.canvas: prepare_canvas(width=width,height=height,canvas=canvas.canvas) setup_overlay(width,height) if scale is None: scale=1 self.update_scale(scale) def save(self): self.sync_to_data() state={} state["width"]=self.display_width state["height"]=self.display_height state["selection_width"]=self.selection_size_w state["selection_height"]=self.selection_size_h state["view_pos"]=self.view_pos[:] state["cursor"]=self.cursor[:] state["scale"]=self.scale keys=list(self.data.keys()) data={} for key in keys: if self.data[key].sum()>0: data[f"{key[0]},{key[1]}"]=self.numpy_to_base64(self.data[key]) state["data"]=data return json.dumps(state) def load(self, state_json): self.reset() state=json.loads(state_json) self.display_width=state["width"] self.display_height=state["height"] self.selection_size_w=state["selection_width"] self.selection_size_h=state["selection_height"] self.view_pos=state["view_pos"][:] self.cursor=state["cursor"][:] self.scale=state["scale"] self.resize(state["width"],state["height"],scale=state["scale"]) for k,v in state["data"].items(): key=tuple(map(int,k.split(","))) self.data[key]=self.base64_to_numpy(v) self.data2buffer() self.display() def display(self): self.clear_background() self.draw_buffer() self.draw_selection_box() def reset(self): self.data.clear() self.buffer=0 self.buffer_dirty=False self.buffer_updated=False self.sel_buffer=0 self.sel_dirty=False self.view_pos = [0, 0] self.clear_background() for i in range(1,len(self.canvas)-1): self.canvas[i].clear() def export(self): self.sync_to_data() xmin, xmax, ymin, ymax = 0, 0, 0, 0 if len(self.data.keys()) == 0: return np.zeros( (self.selection_size_h, self.selection_size_w, 4), dtype=np.uint8 ) for xi, yi in self.data.keys(): buf = self.data[(xi, yi)] if buf.sum() > 0: xmin = min(xi, xmin) xmax = max(xi, xmax) ymin = min(yi, ymin) ymax = max(yi, ymax) yn = ymax - ymin + 1 xn = xmax - xmin + 1 image = np.zeros( (yn * self.patch_size, xn * self.patch_size, 4), dtype=np.uint8 ) for xi, yi in self.data.keys(): buf = self.data[(xi, yi)] if buf.sum() > 0: y0 = (yi - ymin) * self.patch_size x0 = (xi - xmin) * self.patch_size image[y0 : y0 + self.patch_size, x0 : x0 + self.patch_size] = buf ylst, xlst = image[:, :, -1].nonzero() if len(ylst) > 0: yt, xt = ylst.min(), xlst.min() yb, xb = ylst.max(), xlst.max() image = image[yt : yb + 1, xt : xb + 1] return image else: return np.zeros( (self.selection_size_h, self.selection_size_w, 4), dtype=np.uint8 ) base_lst = [None] async def draw_canvas() -> None: width=1024 height=600 canvas=InfCanvas(1024,600) update_eraser(canvas.eraser_size,min(canvas.selection_size_h,canvas.selection_size_w)) document.querySelector("#container").style.height= f"{height}px" document.querySelector("#container").style.width = f"{width}px" canvas.setup_mouse() canvas.clear_background() canvas.draw_buffer() canvas.draw_selection_box() base_lst[0]=canvas async def draw_canvas_func(): width=1500 height=600 selection_size=256 document.querySelector("#container").style.width = f"{width}px" document.querySelector("#container").style.height= f"{height}px" canvas=InfCanvas(int(width),int(height),selection_size=int(selection_size)) canvas.setup_mouse() canvas.clear_background() canvas.draw_buffer() canvas.draw_selection_box() base_lst[0]=canvas async def export_func(event): base=base_lst[0] arr=base.export() base.draw_buffer() base.canvas[2].clear() base64_str = base.numpy_to_base64(arr) time_str = time.strftime("%Y%m%d_%H%M%S") link = document.createElement("a") if len(event.data)>2 and event.data[2]: filename = event.data[2] else: filename = f"outpaint_{time_str}" # link.download = f"sdinf_state_{time_str}.json" link.download = f"{filename}.png" # link.download = f"outpaint_{time_str}.png" link.href = "data:image/png;base64,"+base64_str link.click() console.log(f"Canvas saved to {filename}.png") img_candidate_lst=[None,0] async def outpaint_func(event): base=base_lst[0] if len(event.data)==2: app=parent.document.querySelector("gradio-app") if app.shadowRoot: app=app.shadowRoot base64_str_raw=app.querySelector("#output textarea").value base64_str_lst=base64_str_raw.split(",") img_candidate_lst[0]=base64_str_lst img_candidate_lst[1]=0 elif event.data[2]=="next": img_candidate_lst[1]+=1 elif event.data[2]=="prev": img_candidate_lst[1]-=1 enable_result_lst() if img_candidate_lst[0] is None: return lst=img_candidate_lst[0] idx=img_candidate_lst[1] update_count(idx%len(lst)+1,len(lst)) arr=base.base64_to_numpy(lst[idx%len(lst)]) base.fill_selection(arr) base.draw_selection_box() async def undo_func(event): base=base_lst[0] img_candidate_lst[0]=None if base.sel_dirty: base.sel_buffer = np.zeros((base.selection_size_h, base.selection_size_w, 4), dtype=np.uint8) base.sel_dirty = False base.canvas[2].clear() async def commit_func(event): base=base_lst[0] img_candidate_lst[0]=None if base.sel_dirty: base.write_selection_to_buffer() base.draw_buffer() base.canvas[2].clear() async def transfer_func(event): base=base_lst[0] base.read_selection_from_buffer() sel_buffer=base.sel_buffer sel_buffer_str=base.numpy_to_base64(sel_buffer) app=parent.document.querySelector("gradio-app") if app.shadowRoot: app=app.shadowRoot app.querySelector("#input textarea").value=sel_buffer_str app.querySelector("#proceed").click() async def upload_func(event): base=base_lst[0] # base64_str=event.data[1] base64_str=document.querySelector("#upload_content").value base64_str=base64_str.split(",")[-1] # base64_str=parent.document.querySelector("gradio-app").shadowRoot.querySelector("#upload textarea").value arr=base.base64_to_numpy(base64_str) h,w,c=base.buffer.shape base.sync_to_buffer() base.buffer_dirty=True mask=arr[:,:,3:4].repeat(4,axis=2) base.buffer[mask>0]=0 # in case mismatch base.buffer[0:h,0:w,:]+=arr #base.buffer[yo:yo+h,xo:xo+w,0:3]=arr[:,:,0:3] #base.buffer[yo:yo+h,xo:xo+w,-1]=arr[:,:,-1] base.draw_buffer() async def setup_shortcut_func(event): setup_shortcut(event.data[1]) document.querySelector("#export").addEventListener("click",create_proxy(export_func)) document.querySelector("#undo").addEventListener("click",create_proxy(undo_func)) document.querySelector("#commit").addEventListener("click",create_proxy(commit_func)) document.querySelector("#outpaint").addEventListener("click",create_proxy(outpaint_func)) document.querySelector("#upload").addEventListener("click",create_proxy(upload_func)) document.querySelector("#transfer").addEventListener("click",create_proxy(transfer_func)) document.querySelector("#draw").addEventListener("click",create_proxy(draw_canvas_func)) async def setup_func(): document.querySelector("#setup").value="1" async def reset_func(event): base=base_lst[0] base.reset() async def load_func(event): base=base_lst[0] base.load(event.data[1]) async def save_func(event): base=base_lst[0] json_str=base.save() time_str = time.strftime("%Y%m%d_%H%M%S") link = document.createElement("a") if len(event.data)>2 and event.data[2]: filename = str(event.data[2]).strip() else: filename = f"outpaint_{time_str}" # link.download = f"sdinf_state_{time_str}.json" link.download = f"{filename}.sdinf" link.href = "data:text/json;charset=utf-8,"+encodeURIComponent(json_str) link.click() async def prev_result_func(event): base=base_lst[0] base.reset() async def next_result_func(event): base=base_lst[0] base.reset() async def zoom_in_func(event): base=base_lst[0] scale=base.scale if scale>=0.2: scale-=0.1 if len(event.data)>2: base.update_scale(scale,int(event.data[2]),int(event.data[3])) else: base.update_scale(scale) scale=base.scale update_scale(f"{base.width}x{base.height} ({round(100/scale)}%)") async def zoom_out_func(event): base=base_lst[0] scale=base.scale if scale<10: scale+=0.1 console.log(len(event.data)) if len(event.data)>2: base.update_scale(scale,int(event.data[2]),int(event.data[3])) else: base.update_scale(scale) scale=base.scale update_scale(f"{base.width}x{base.height} ({round(100/scale)}%)") async def sync_func(event): base=base_lst[0] base.sync_to_buffer() base.canvas[2].clear() async def eraser_size_func(event): base=base_lst[0] eraser_size=min(int(event.data[1]),min(base.selection_size_h,base.selection_size_w)) eraser_size=max(8,eraser_size) base.eraser_size=eraser_size async def resize_selection_func(event): base=base_lst[0] cursor=base.cursor if len(event.data)>3: console.log(event.data) base.cursor[0]=int(event.data[1]) base.cursor[1]=int(event.data[2]) base.selection_size_w=int(event.data[3])//88 base.selection_size_h=int(event.data[4])//88 base.refine_selection() base.draw_selection_box() elif len(event.data)>2: base.draw_selection_box() else: base.canvas[-1].clear() adjust_selection(cursor[0],cursor[1],base.selection_size_w,base.selection_size_h) async def eraser_func(event): base=base_lst[0] if event.data[1]!="eraser": base.canvas[-2].clear() else: x,y=base.mouse_pos base.draw_eraser(x,y) async def resize_func(event): base=base_lst[0] width=int(event.data[1]) height=int(event.data[2]) if width>=256 and height>=256: if max(base.selection_size_h,base.selection_size_w)>min(width,height): base.selection_size_h=256 base.selection_size_w=256 base.resize(width,height) async def message_func(event): if event.data[0]=="click": if event.data[1]=="clear": await reset_func(event) elif event.data[1]=="save": await save_func(event) elif event.data[1]=="export": await export_func(event) elif event.data[1]=="accept": await commit_func(event) elif event.data[1]=="cancel": await undo_func(event) elif event.data[1]=="zoom_in": await zoom_in_func(event) elif event.data[1]=="zoom_out": await zoom_out_func(event) elif event.data[0]=="sync": await sync_func(event) elif event.data[0]=="load": await load_func(event) elif event.data[0]=="upload": await upload_func(event) elif event.data[0]=="outpaint": await outpaint_func(event) elif event.data[0]=="mode": if event.data[1]!="selection": await sync_func(event) await eraser_func(event) document.querySelector("#mode").value=event.data[1] elif event.data[0]=="transfer": await transfer_func(event) elif event.data[0]=="setup": await draw_canvas_func(event) elif event.data[0]=="eraser_size": await eraser_size_func(event) elif event.data[0]=="resize_selection": await resize_selection_func(event) elif event.data[0]=="shortcut": await setup_shortcut_func(event) elif event.data[0]=="resize": await resize_func(event) window.addEventListener("message",create_proxy(message_func)) import asyncio _ = await asyncio.gather( setup_func(),draw_canvas_func() )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant