mirror of
https://github.com/sd-webui/stable-diffusion-webui.git
synced 2024-12-15 07:12:58 +03:00
added preview to properties
This commit is contained in:
parent
eefb4de6ce
commit
6368d1edfe
@ -171,28 +171,28 @@ asset_manager = AssetManager(
|
|||||||
content = ft.Row(
|
content = ft.Row(
|
||||||
controls = [
|
controls = [
|
||||||
ft.Column(
|
ft.Column(
|
||||||
controls = [
|
controls = [
|
||||||
ft.Tabs(
|
ft.Tabs(
|
||||||
selected_index = 0,
|
selected_index = 0,
|
||||||
animation_duration = 300,
|
animation_duration = 300,
|
||||||
tabs = [
|
tabs = [
|
||||||
ft.Tab(
|
ft.Tab(
|
||||||
content = layer_panel,
|
content = layer_panel,
|
||||||
tab_content = ft.Text(
|
tab_content = ft.Text(
|
||||||
value = "Layers",
|
value = "Layers",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ft.Tab(
|
ft.Tab(
|
||||||
content = asset_panel,
|
content = asset_panel,
|
||||||
tab_content = ft.Text(
|
tab_content = ft.Text(
|
||||||
value = "Assets",
|
value = "Assets",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
alignment = 'start',
|
alignment = 'start',
|
||||||
expand = True
|
expand = True
|
||||||
),
|
),
|
||||||
asset_manager_dragbar,
|
asset_manager_dragbar,
|
||||||
],
|
],
|
||||||
|
@ -17,17 +17,18 @@ class Canvas(ft.Container):
|
|||||||
self.overlay.tools.zoom_in = self.page.icon_size
|
self.overlay.tools.zoom_in = self.page.icon_size
|
||||||
self.overlay.tools.zoom_out = self.page.icon_size
|
self.overlay.tools.zoom_out = self.page.icon_size
|
||||||
|
|
||||||
self.overlay.canvas_size.content.color = self.page.text_color
|
self.overlay.size_display.content.color = self.page.text_color
|
||||||
self.overlay.canvas_size.content.size = self.page.text_size
|
self.overlay.size_display.content.size = self.page.text_size
|
||||||
self.add_canvas_background()
|
self.add_canvas_background()
|
||||||
self.center_canvas(self)
|
self.center_canvas(self)
|
||||||
self.refresh_canvas()
|
self.refresh_canvas()
|
||||||
|
self.update()
|
||||||
|
|
||||||
def lock_canvas(self):
|
def lock_canvas(self):
|
||||||
self.overlay.canvas_cover.lock_canvas()
|
self.overlay.cover.lock_canvas()
|
||||||
|
|
||||||
def unlock_canvas(self):
|
def unlock_canvas(self):
|
||||||
self.overlay.canvas_cover.unlock_canvas()
|
self.overlay.cover.unlock_canvas()
|
||||||
|
|
||||||
def refresh_canvas(self):
|
def refresh_canvas(self):
|
||||||
self.overlay.refresh_canvas_overlay()
|
self.overlay.refresh_canvas_overlay()
|
||||||
@ -42,18 +43,25 @@ class Canvas(ft.Container):
|
|||||||
self.image_stack.add_layer_image(image)
|
self.image_stack.add_layer_image(image)
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
|
def get_image_stack_preview(self):
|
||||||
|
return self.image_stack.get_preview()
|
||||||
|
|
||||||
def center_canvas(self, e):
|
def center_canvas(self, e):
|
||||||
width, height = self.page.get_viewport_size()
|
width, height = self.page.get_viewport_size()
|
||||||
self.image_stack.offset_x = 0
|
self.image_stack.offset_x = 0
|
||||||
self.image_stack.offset_y = 0
|
self.image_stack.offset_y = 0
|
||||||
self.image_stack.left = (width * 0.5) - (self.image_stack.width * 0.5)
|
self.image_stack.left = (width * 0.5) - (self.image_stack.width * 0.5)
|
||||||
self.image_stack.top = (height * 0.5) - (self.image_stack.height * 0.5)
|
self.image_stack.top = (height * 0.5) - (self.image_stack.height * 0.5)
|
||||||
|
self.overlay.preview.left = self.image_stack.left
|
||||||
|
self.overlay.preview.top = self.image_stack.top
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
def align_canvas(self, e):
|
def align_canvas(self, e):
|
||||||
width, height = self.page.get_viewport_size()
|
width, height = self.page.get_viewport_size()
|
||||||
self.image_stack.left = (width * 0.5) - (self.image_stack.width * 0.5) + self.image_stack.offset_x
|
self.image_stack.left = (width * 0.5) - (self.image_stack.width * 0.5) + self.image_stack.offset_x
|
||||||
self.image_stack.top = (height * 0.5) - (self.image_stack.height * 0.5) + self.image_stack.offset_y
|
self.image_stack.top = (height * 0.5) - (self.image_stack.height * 0.5) + self.image_stack.offset_y
|
||||||
|
self.overlay.preview.left = self.image_stack.left
|
||||||
|
self.overlay.preview.top = self.image_stack.top
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
def pan_canvas(self, e: ft.DragUpdateEvent):
|
def pan_canvas(self, e: ft.DragUpdateEvent):
|
||||||
@ -72,6 +80,7 @@ class Canvas(ft.Container):
|
|||||||
else:
|
else:
|
||||||
self.image_stack.scale += 0.05
|
self.image_stack.scale += 0.05
|
||||||
self.image_stack.get_scaled_size()
|
self.image_stack.get_scaled_size()
|
||||||
|
self.overlay.preview.scale = self.image_stack.scale
|
||||||
self.align_canvas(e)
|
self.align_canvas(e)
|
||||||
|
|
||||||
def zoom_out(self, e):
|
def zoom_out(self, e):
|
||||||
@ -79,6 +88,7 @@ class Canvas(ft.Container):
|
|||||||
self.image_stack.scale = 0.1
|
self.image_stack.scale = 0.1
|
||||||
else:
|
else:
|
||||||
self.image_stack.scale -= 0.05
|
self.image_stack.scale -= 0.05
|
||||||
|
self.overlay.preview.scale = self.image_stack.scale
|
||||||
self.image_stack.get_scaled_size()
|
self.image_stack.get_scaled_size()
|
||||||
self.align_canvas(e)
|
self.align_canvas(e)
|
||||||
|
|
||||||
@ -101,6 +111,7 @@ class ImageStack(ft.Container):
|
|||||||
gapless_playback = True,
|
gapless_playback = True,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
canvas_bg.image = image
|
||||||
self.canvas_bg = canvas_bg
|
self.canvas_bg = canvas_bg
|
||||||
self.content.controls.append(canvas_bg)
|
self.content.controls.append(canvas_bg)
|
||||||
|
|
||||||
@ -111,15 +122,22 @@ class ImageStack(ft.Container):
|
|||||||
width = image.width,
|
width = image.width,
|
||||||
height = image.height,
|
height = image.height,
|
||||||
content = ft.Image(
|
content = ft.Image(
|
||||||
src = f'assets/uploads/{image.filename}',
|
src = f'{image.path}',
|
||||||
width = image.width,
|
width = image.width,
|
||||||
height = image.height,
|
height = image.height,
|
||||||
gapless_playback = True,
|
gapless_playback = True,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
layer_image.image = image
|
||||||
self.center_layer(layer_image)
|
self.center_layer(layer_image)
|
||||||
self.content.controls.append(layer_image)
|
self.content.controls.append(layer_image)
|
||||||
canvas.layers.append(layer_image)
|
canvas.refresh_canvas()
|
||||||
|
|
||||||
|
def get_preview(self):
|
||||||
|
stack = []
|
||||||
|
for layer in self.content.controls:
|
||||||
|
stack.append(layer.image)
|
||||||
|
return flet_utils.get_preview_from_stack(self.page.canvas_size, stack)
|
||||||
|
|
||||||
def get_scaled_size(self):
|
def get_scaled_size(self):
|
||||||
self.scaled_width = self.width * self.scale
|
self.scaled_width = self.width * self.scale
|
||||||
@ -151,11 +169,20 @@ class LayerImage(ft.Container):
|
|||||||
class CanvasOverlay(ft.Stack):
|
class CanvasOverlay(ft.Stack):
|
||||||
def refresh_canvas_overlay(self):
|
def refresh_canvas_overlay(self):
|
||||||
self.refresh_canvas_size_display()
|
self.refresh_canvas_size_display()
|
||||||
|
self.refresh_canvas_preview()
|
||||||
|
|
||||||
def refresh_canvas_size_display(self):
|
def refresh_canvas_size_display(self):
|
||||||
self.canvas_size.content.value = str(self.page.canvas_size)
|
self.size_display.content.value = str(self.page.canvas_size)
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
|
def refresh_canvas_preview(self):
|
||||||
|
preview = canvas.get_image_stack_preview()
|
||||||
|
self.preview.content.src_base64 = flet_utils.convert_image_to_base64(preview)
|
||||||
|
self.preview.content.width = preview.width
|
||||||
|
self.preview.content.height = preview.height
|
||||||
|
self.preview.image = preview
|
||||||
|
self.page.property_manager.set_preview_image(preview)
|
||||||
|
|
||||||
|
|
||||||
def pan_canvas(e):
|
def pan_canvas(e):
|
||||||
canvas.pan_canvas(e)
|
canvas.pan_canvas(e)
|
||||||
@ -175,40 +202,33 @@ image_stack.scaled_width = image_stack.width
|
|||||||
image_stack.scaled_height = image_stack.height
|
image_stack.scaled_height = image_stack.height
|
||||||
|
|
||||||
|
|
||||||
class CanvasCover(ft.Container):
|
canvas_cover = ft.Container(
|
||||||
def lock_canvas(self):
|
content = None,
|
||||||
self.bgcolor = 'black'
|
expand = True,
|
||||||
self.opacity = 0.5,
|
bgcolor = 'black',
|
||||||
self.content = self.loading
|
opacity = 0.5,
|
||||||
|
)
|
||||||
|
|
||||||
def unlock_canvas(self):
|
canvas_preview = LayerImage(
|
||||||
self.bgcolor = None
|
width = 4096,
|
||||||
self.opacity = 1.0,
|
height = 4096,
|
||||||
self.content = self.detector
|
padding = 0,
|
||||||
|
margin = 0,
|
||||||
|
image_fit = ft.ImageFit.CONTAIN,
|
||||||
|
alignment = ft.alignment.center,
|
||||||
|
content = ft.Image(
|
||||||
|
src_base64 = None,
|
||||||
|
gapless_playback = True,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
gesture_detector = ft.GestureDetector(
|
|
||||||
|
canvas_gestures = ft.GestureDetector(
|
||||||
mouse_cursor = ft.MouseCursor.MOVE,
|
mouse_cursor = ft.MouseCursor.MOVE,
|
||||||
drag_interval = 10,
|
drag_interval = 10,
|
||||||
on_pan_update = pan_canvas,
|
on_pan_update = pan_canvas,
|
||||||
)
|
)
|
||||||
|
|
||||||
canvas_loading = ft.ProgressRing(
|
|
||||||
width = 50,
|
|
||||||
height = 50,
|
|
||||||
stroke_width = 4,
|
|
||||||
value = None,
|
|
||||||
)
|
|
||||||
|
|
||||||
canvas_cover = CanvasCover(
|
|
||||||
content = gesture_detector,
|
|
||||||
expand = True,
|
|
||||||
bgcolor = None,
|
|
||||||
opacity = 1.0,
|
|
||||||
)
|
|
||||||
|
|
||||||
canvas_cover.detector = gesture_detector
|
|
||||||
canvas_cover.loading = canvas_loading
|
|
||||||
|
|
||||||
canvas_size_display = ft.Container(
|
canvas_size_display = ft.Container(
|
||||||
content = ft.Text(
|
content = ft.Text(
|
||||||
value = "test",
|
value = "test",
|
||||||
@ -273,13 +293,16 @@ canvas_tools.zoom_out = zoom_out_button
|
|||||||
canvas_overlay = CanvasOverlay(
|
canvas_overlay = CanvasOverlay(
|
||||||
[
|
[
|
||||||
canvas_cover,
|
canvas_cover,
|
||||||
|
canvas_preview,
|
||||||
|
canvas_gestures,
|
||||||
canvas_size_display,
|
canvas_size_display,
|
||||||
canvas_tools,
|
canvas_tools,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
canvas_overlay.canvas_cover = canvas_cover
|
canvas_overlay.cover = canvas_cover
|
||||||
canvas_overlay.canvas_size = canvas_size_display
|
canvas_overlay.preview = canvas_preview
|
||||||
|
canvas_overlay.size_display = canvas_size_display
|
||||||
canvas_overlay.tools = canvas_tools
|
canvas_overlay.tools = canvas_tools
|
||||||
|
|
||||||
|
|
||||||
@ -298,4 +321,4 @@ canvas = Canvas(
|
|||||||
|
|
||||||
canvas.image_stack = image_stack
|
canvas.image_stack = image_stack
|
||||||
canvas.overlay = canvas_overlay
|
canvas.overlay = canvas_overlay
|
||||||
canvas.layers = []
|
|
||||||
|
@ -85,16 +85,22 @@ class GalleryDisplay(ft.Container):
|
|||||||
if 'info_path' in image[image_name]:
|
if 'info_path' in image[image_name]:
|
||||||
image_data = image[image_name]['info_path']
|
image_data = image[image_name]['info_path']
|
||||||
self.content.controls[0].controls.append(
|
self.content.controls[0].controls.append(
|
||||||
ft.Image(
|
ft.Container(
|
||||||
src = image_path,
|
content = ft.Image(
|
||||||
tooltip = image_name,
|
src = image_path,
|
||||||
gapless_playback = True,
|
tooltip = image_name,
|
||||||
|
gapless_playback = True,
|
||||||
|
),
|
||||||
|
image_fit = ft.ImageFit.CONTAIN,
|
||||||
|
padding = 0,
|
||||||
|
margin = 0,
|
||||||
|
on_click =
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def add_as_new_layer(e):
|
def add_as_new_layer(e):
|
||||||
pass
|
e.page.asset_manager.add_image_as_layer(gallery_window.selected_image)
|
||||||
|
|
||||||
def save_to_disk(e):
|
def save_to_disk(e):
|
||||||
pass
|
pass
|
||||||
@ -153,4 +159,4 @@ gallery_window = GalleryWindow(
|
|||||||
|
|
||||||
gallery_window.uploads_gallery = uploads_gallery
|
gallery_window.uploads_gallery = uploads_gallery
|
||||||
gallery_window.outputs_gallery = outputs_gallery
|
gallery_window.outputs_gallery = outputs_gallery
|
||||||
|
gallery_window.selected_image = None
|
||||||
|
@ -19,6 +19,9 @@ class PropertyManager(ft.Container):
|
|||||||
self.set_tab_margin(self.page.container_margin)
|
self.set_tab_margin(self.page.container_margin)
|
||||||
self.dragbar.content.width = self.page.vertical_divider_width
|
self.dragbar.content.width = self.page.vertical_divider_width
|
||||||
self.dragbar.content.color = self.page.tertiary_color
|
self.dragbar.content.color = self.page.tertiary_color
|
||||||
|
self.property_panel.preview.width = self.page.right_panel_width
|
||||||
|
self.property_panel.preview_dragbar.content.content.height = self.page.divider_height
|
||||||
|
self.property_panel.preview_dragbar.content.content.color = self.page.tertiary_color
|
||||||
|
|
||||||
def set_tab_text_size(self, size):
|
def set_tab_text_size(self, size):
|
||||||
for tab in self.tabs:
|
for tab in self.tabs:
|
||||||
@ -36,33 +39,69 @@ class PropertyManager(ft.Container):
|
|||||||
for tab in self.tabs:
|
for tab in self.tabs:
|
||||||
tab.content.margin = margin
|
tab.content.margin = margin
|
||||||
|
|
||||||
|
def set_preview_size(self, width):
|
||||||
|
self.property_panel.preview.width = width
|
||||||
|
|
||||||
|
def set_preview_image(self, image):
|
||||||
|
self.property_panel.preview.content.src_base64 = flet_utils.convert_image_to_base64(image)
|
||||||
|
self.property_panel.update()
|
||||||
|
|
||||||
class PropertyPanel(ft.Container):
|
class PropertyPanel(ft.Container):
|
||||||
pass
|
def resize_preview(self, e):
|
||||||
|
self.page.preview_height = max(200, self.page.preview_height + e.delta_y)
|
||||||
|
self.preview.height = self.page.preview_height
|
||||||
|
self.update()
|
||||||
|
|
||||||
|
preview_pane = ft.Container(
|
||||||
|
content = ft.Image(
|
||||||
|
src_base64 = None,
|
||||||
|
gapless_playback = True,
|
||||||
|
),
|
||||||
|
image_fit = ft.ImageFit.CONTAIN,
|
||||||
|
bgcolor = 'black',
|
||||||
|
height = 200,
|
||||||
|
padding = 0,
|
||||||
|
margin = 0,
|
||||||
|
)
|
||||||
|
|
||||||
|
def resize_preview(e):
|
||||||
|
property_panel.resize_preview(e)
|
||||||
|
|
||||||
|
preview_dragbar = ft.GestureDetector(
|
||||||
|
mouse_cursor = ft.MouseCursor.RESIZE_ROW,
|
||||||
|
drag_interval = 50,
|
||||||
|
on_pan_update = resize_preview,
|
||||||
|
content = ft.Container(
|
||||||
|
content = ft.Divider(),
|
||||||
|
margin = 0,
|
||||||
|
padding = 0,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
property_panel = PropertyPanel(
|
property_panel = PropertyPanel(
|
||||||
content = ft.Column(
|
content = ft.Column(
|
||||||
spacing = 0,
|
|
||||||
controls = [
|
controls = [
|
||||||
ft.Text("Under Construction"),
|
preview_pane,
|
||||||
|
preview_dragbar,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
clip_behavior = 'antiAlias',
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
property_panel.preview = preview_pane
|
||||||
|
property_panel.preview_dragbar = preview_dragbar
|
||||||
|
|
||||||
output_panel = PropertyPanel(
|
output_panel = PropertyPanel(
|
||||||
content = ft.Column(
|
content = ft.Column(
|
||||||
spacing = 0,
|
|
||||||
controls = [
|
controls = [
|
||||||
ft.Text("Under Construction."),
|
ft.Text("Under Construction."),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
clip_behavior = 'antiAlias',
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def resize_property_manager(e: ft.DragUpdateEvent):
|
def resize_property_manager(e: ft.DragUpdateEvent):
|
||||||
e.page.right_panel_width = max(250, e.page.right_panel_width - e.delta_x)
|
e.page.right_panel_width = max(250, e.page.right_panel_width - e.delta_x)
|
||||||
property_manager.width = e.page.right_panel_width
|
property_manager.width = e.page.right_panel_width
|
||||||
|
property_panel.preview.width = e.page.right_panel_width
|
||||||
e.page.update()
|
e.page.update()
|
||||||
|
|
||||||
property_manager_dragbar = ft.GestureDetector(
|
property_manager_dragbar = ft.GestureDetector(
|
||||||
@ -82,24 +121,28 @@ property_manager = PropertyManager(
|
|||||||
selected_index = 0,
|
selected_index = 0,
|
||||||
animation_duration = 300,
|
animation_duration = 300,
|
||||||
tabs = [
|
tabs = [
|
||||||
ft.Tab(
|
ft.Tab(
|
||||||
content = property_panel,
|
content = property_panel,
|
||||||
tab_content = ft.Text(
|
tab_content = ft.Text(
|
||||||
value = "Properties",
|
value = "Properties",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ft.Tab(
|
ft.Tab(
|
||||||
content = output_panel,
|
content = output_panel,
|
||||||
tab_content = ft.Text(
|
tab_content = ft.Text(
|
||||||
value = "Output",
|
value = "Output",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
alignment = 'start',
|
alignment = 'start',
|
||||||
expand = True
|
expand = True
|
||||||
),
|
),
|
||||||
|
ft.VerticalDivider(
|
||||||
|
width = 4,
|
||||||
|
opacity = 0,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
expand = True,
|
expand = True,
|
||||||
),
|
),
|
||||||
|
@ -85,6 +85,7 @@ def get_image_from_uploads(name):
|
|||||||
image = Image.open(path_to_image)
|
image = Image.open(path_to_image)
|
||||||
image = image.convert("RGBA")
|
image = image.convert("RGBA")
|
||||||
image.filename = name
|
image.filename = name
|
||||||
|
image.path = path_to_image
|
||||||
return image
|
return image
|
||||||
else:
|
else:
|
||||||
log_message(f'image not found: "{name}"')
|
log_message(f'image not found: "{name}"')
|
||||||
@ -97,16 +98,18 @@ def get_canvas_background(path):
|
|||||||
|
|
||||||
# takes list of Image(s) as arg
|
# takes list of Image(s) as arg
|
||||||
# returns single composite of all images
|
# returns single composite of all images
|
||||||
def get_visible_from_image_stack(image_list):
|
def get_preview_from_stack(size, images):
|
||||||
visible_image = create_blank_image()
|
preview = create_blank_image(size)
|
||||||
for image in image_list:
|
canvas_width = size[0]
|
||||||
|
canvas_height = size[1]
|
||||||
|
for image in images:
|
||||||
# need to crop images for composite
|
# need to crop images for composite
|
||||||
x0, y0 = (image.width * 0.5) - 256, (image.height * 0.5) - 256
|
x0, y0 = (image.width - canvas_width) * 0.5, (image.height - canvas_height) * 0.5
|
||||||
x1, y1 = x0 + 512, y0 + 512
|
x1, y1 = x0 + canvas_width, y0 + canvas_height
|
||||||
box = (x0, y0, x1, y1)
|
box = (x0, y0, x1, y1)
|
||||||
cropped_image = image.crop(box)
|
cropped_image = image.crop(box)
|
||||||
visible_image = Image.alpha_composite(visible_image,cropped_image)
|
preview = Image.alpha_composite(preview,cropped_image)
|
||||||
return visible_image
|
return preview
|
||||||
|
|
||||||
# converts Image to base64 string
|
# converts Image to base64 string
|
||||||
def convert_image_to_base64(image):
|
def convert_image_to_base64(image):
|
||||||
|
@ -7,7 +7,7 @@ from math import pi
|
|||||||
from typing import Optional
|
from typing import Optional
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
import logging
|
import logging
|
||||||
logging.basicConfig(level=logging.DEBUG)
|
#logging.basicConfig(level=logging.DEBUG)
|
||||||
|
|
||||||
# utils imports
|
# utils imports
|
||||||
from scripts import flet_utils
|
from scripts import flet_utils
|
||||||
@ -110,6 +110,7 @@ def main(page: ft.Page):
|
|||||||
|
|
||||||
# property manager
|
# property manager
|
||||||
page.property_manager = property_manager
|
page.property_manager = property_manager
|
||||||
|
page.preview_height = 200
|
||||||
|
|
||||||
# settings
|
# settings
|
||||||
def load_settings():
|
def load_settings():
|
||||||
|
Loading…
Reference in New Issue
Block a user