Start of crop widget

This commit is contained in:
2025-08-03 21:23:42 +02:00
parent a423ceb669
commit 447354266c
5 changed files with 229 additions and 99 deletions

View File

@ -13,7 +13,7 @@ from .layout_manager import LayoutManager
from .widgets.base_widget import BaseWidget
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
logging.basicConfig(level=logging.DEBUG, format="%(asctime)s %(levelname)s %(message)s")
logger = logging.getLogger(__name__)

View File

@ -0,0 +1,85 @@
import dearpygui.dearpygui as dpg
import numpy as np
from .stage_viewer_widget import PipelineStageViewer
class CropWidget(PipelineStageViewer):
name = "Crop Image"
register = True
has_pipeline_in = True
has_pipeline_out = True
def __init__(self, manager, logger):
super().__init__(manager, logger)
self.crop_start = None # (x, y)
self.crop_end = None # (x, y)
self.crop_active = False
self.manager.bus.subscribe("img_clicked", self.on_click)
self.manager.bus.subscribe("img_dragged", self.on_drag)
def create_pipeline_stage_content(self):
super().create_pipeline_stage_content()
# def on_full_res_pipeline_data(self, img):
# pass
def on_pipeline_data(self, img):
if img is None:
return
self.img = img
if self.crop_start and self.crop_end:
x0, y0 = self.crop_start
x1, y1 = self.crop_end
x0, x1 = sorted((int(x0), int(x1)))
y0, y1 = sorted((int(y0), int(y1)))
x0 = max(0, min(x0, img.shape[1]-1))
x1 = max(0, min(x1, img.shape[1]-1))
y0 = max(0, min(y0, img.shape[0]-1))
y1 = max(0, min(y1, img.shape[0]-1))
cropped = img[y0:y1, x0:x1, :]
self.publish_stage(cropped)
else:
self.publish_stage(img)
self.needs_update = True
def on_click(self, data):
if data["obj"] is not self:
return
if data["button"] == "left":
self.crop_start = data["pos"]
self.crop_end = data["pos"]
self.crop_active = True
self.needs_update = True
def on_drag(self, data):
if data["obj"] is not self or not self.crop_active:
return
self.crop_end = data["pos"]
self.needs_update = True
def update_texture(self, img):
super().update_texture(img)
if self.crop_start and self.crop_end:
# map image coords back to screen coords
x0, y0 = self.crop_start
x1, y1 = self.crop_end
h, w, _ = self.img.shape
img_x, img_y = self.image_position
img_w, img_h = self.scaled_size
p0 = (
img_x + x0 / w * img_w,
img_y + y0 / h * img_h
)
p1 = (
img_x + x1 / w * img_w,
img_y + y1 / h * img_h
)
dpg.draw_rectangle(pmin=p0, pmax=p1, color=(255, 255, 0, 255),
fill=(255, 255, 0, 50), thickness=2, parent=self.drawlist)

View File

@ -66,6 +66,7 @@ class PipelineStageViewer(PipelineStageWidget):
if app_data[0] == 0
else ("left" if app_data[0] == 1 else ("middle"))
),
"obj":self,
},
)
@ -93,7 +94,8 @@ class PipelineStageViewer(PipelineStageWidget):
"stage_id": self.pipeline_stage_in_id,
"pos": (x, y),
"button": data['button'],
"delta": data['delta']
"delta": data['delta'],
"obj":self,
},
)
@ -120,7 +122,8 @@ class PipelineStageViewer(PipelineStageWidget):
{
"stage_id": self.pipeline_stage_in_id,
"pos": (x, y),
"delta": data
"delta": data,
"obj":self,
},
)

View File

@ -112,7 +112,7 @@ DockId=0x00000013,1
[Window][###87]
Pos=272,646
Size=710,154
Size=684,154
Collapsed=0
DockId=0x00000046,0
@ -279,9 +279,9 @@ DockId=0x0000004A,0
[Window][###36]
Pos=272,19
Size=710,625
Size=684,625
Collapsed=0
DockId=0x00000014,0
DockId=0x00000014,1
[Window][###48]
Pos=0,714
@ -314,14 +314,16 @@ Collapsed=0
DockId=0x00000047,0
[Window][###109]
Pos=60,60
Size=216,263
Pos=958,19
Size=242,262
Collapsed=0
DockId=0x00000057,0
[Window][###131]
Pos=60,60
Size=141,100
Pos=958,653
Size=242,147
Collapsed=0
DockId=0x00000056,0
[Window][###128]
Pos=60,60
@ -358,9 +360,34 @@ Size=216,163
Collapsed=0
DockId=0x00000052,0
[Window][###170]
Pos=272,19
Size=710,625
Collapsed=0
DockId=0x00000014,1
[Window][###148]
Pos=272,19
Size=710,625
Collapsed=0
DockId=0x00000014,0
[Window][###169]
Pos=272,19
Size=684,625
Collapsed=0
DockId=0x00000014,0
[Window][###152]
Pos=958,283
Size=242,368
Collapsed=0
DockId=0x00000058,0
[Docking][Data]
DockSpace ID=0x7C6B3D9B Window=0xA87D555D Pos=0,19 Size=1200,781 Split=X
DockNode ID=0x00000037 Parent=0x7C6B3D9B SizeRef=982,781 Split=X
DockNode ID=0x00000053 Parent=0x7C6B3D9B SizeRef=956,781 Split=X
DockNode ID=0x00000037 Parent=0x00000053 SizeRef=982,781 Split=X
DockNode ID=0x0000002D Parent=0x00000037 SizeRef=970,781 Split=X
DockNode ID=0x0000002B Parent=0x0000002D SizeRef=937,781 Split=X
DockNode ID=0x00000027 Parent=0x0000002B SizeRef=982,781 Split=X
@ -380,7 +407,7 @@ DockSpace ID=0x7C6B3D9B Window=0xA87D555D Pos=0,19
DockNode ID=0x00000020 Parent=0x00000013 SizeRef=270,154 Selected=0x0531B3D5
DockNode ID=0x0000000E Parent=0x0000000B SizeRef=196,373 Selected=0x3BEDC6B0
DockNode ID=0x0000000C Parent=0x00000009 SizeRef=196,105 Selected=0x4F81AB74
DockNode ID=0x0000000A Parent=0x00000017 SizeRef=698,581 Split=X
DockNode ID=0x0000000A Parent=0x00000017 SizeRef=684,581 Split=X
DockNode ID=0x00000003 Parent=0x0000000A SizeRef=299,581 Split=Y Selected=0x52849BCC
DockNode ID=0x00000005 Parent=0x00000003 SizeRef=299,473 Split=Y Selected=0x52849BCC
DockNode ID=0x00000007 Parent=0x00000005 SizeRef=299,86 Selected=0x52849BCC
@ -439,7 +466,12 @@ DockSpace ID=0x7C6B3D9B Window=0xA87D555D Pos=0,19
DockNode ID=0x0000002E Parent=0x00000037 SizeRef=228,781 Split=Y Selected=0x4C2F06CB
DockNode ID=0x0000002F Parent=0x0000002E SizeRef=216,560 Selected=0x4C2F06CB
DockNode ID=0x00000030 Parent=0x0000002E SizeRef=216,219 Selected=0x04546B8A
DockNode ID=0x00000038 Parent=0x7C6B3D9B SizeRef=216,781 Split=Y Selected=0x88A8C2FF
DockNode ID=0x00000038 Parent=0x00000053 SizeRef=216,781 Split=Y Selected=0x88A8C2FF
DockNode ID=0x00000039 Parent=0x00000038 SizeRef=216,561 Selected=0x88A8C2FF
DockNode ID=0x0000003A Parent=0x00000038 SizeRef=216,218 Selected=0xC56063F4
DockNode ID=0x00000054 Parent=0x7C6B3D9B SizeRef=242,781 Split=Y Selected=0xA2A5002C
DockNode ID=0x00000055 Parent=0x00000054 SizeRef=158,632 Split=Y Selected=0xA2A5002C
DockNode ID=0x00000057 Parent=0x00000055 SizeRef=158,262 Selected=0x85B8A08E
DockNode ID=0x00000058 Parent=0x00000055 SizeRef=158,368 Selected=0xA2A5002C
DockNode ID=0x00000056 Parent=0x00000054 SizeRef=158,147 Selected=0x335C99E1

View File

@ -4,7 +4,8 @@
"1": "inverted_image",
"2": "opened_raw",
"3": "monochrome",
"4": "oriented_image"
"4": "oriented_image",
"5": "cropped_image"
},
"widgets": [
{
@ -20,7 +21,7 @@
"widget_type": "PipelineStageViewer",
"config": {
"pipeline_config": {
"stage_in": 4,
"stage_in": 5,
"stage_out": null
}
}
@ -73,7 +74,7 @@
"widget_type": "HistogramWidget",
"config": {
"pipeline_config": {
"stage_in": 4,
"stage_in": 5,
"stage_out": null
}
}
@ -82,7 +83,7 @@
"widget_type": "ExportStage",
"config": {
"pipeline_config": {
"stage_in": 4,
"stage_in": 5,
"stage_out": null
}
}
@ -95,11 +96,20 @@
"stage_out": 4
},
"orientation": {
"rotation": 0,
"rotation": 180,
"mirror_h": "False",
"mirror_v": "False"
}
}
},
{
"widget_type": "CropWidget",
"config": {
"pipeline_config": {
"stage_in": 4,
"stage_out": 5
}
}
}
]
}