def undo(self): for index, w in enumerate(self.main_window.eye_widgets()): w.image.transform.center = FractionalImagePos( *self.old_centers[index]) w.image.transform.rotation = self.old_rotations[index] for w in self.main_window.eye_widgets(): w.update()
def fract_from_image(self, pos: ImagePixelCoordinate) -> FractionalImagePos: img = self.image.image img_size = (1, 1) if img: img_size = (img.width, img.height) return FractionalImagePos.from_ImagePixelCoordinate(pos, img_size)
def image_from_canvas(self, pos: CanvasPos) -> ImagePixelCoordinate: fip = FractionalImagePos.from_CanvasPos(pos, self.image.transform) img = self.image.image img_size = (1, 1) if img: img_size = (img.width, img.height) ip = ImagePixelCoordinate.from_FractionalImagePos(fip, img_size) return ip
def state(self, data): self.left = data["left"] self.right = data["right"] self.top = data["top"] self.bottom = data["bottom"] self.camera.center = CanvasPos(*data["camera_center"]) for i, img in enumerate(self.images): img.transform.center = FractionalImagePos(*data["transforms"][i])
def size(self, value: ImagePixelCoordinate): ipc2 = ImagePixelCoordinate(0, 0) img_size = self.images[0].size() fips = [ FractionalImagePos.from_ImagePixelCoordinate(pos, img_size) for pos in (value, ipc2) ] xform = self.images[0].transform cps = [CanvasPos.from_FractionalImagePos(pos, xform) for pos in fips] width = abs(cps[1].x - cps[0].x) height = abs(cps[1].y - cps[0].y) self.right = 0.5 * width self.left = -self.right self.bottom = 0.5 * height self.top = -self.bottom
def size(self) -> ImagePixelCoordinate: cp1 = CanvasPos(self.left, self.top) cp2 = CanvasPos(self.right, self.bottom) xform = self.images[0].transform img_size = self.images[0].size() fips = [ FractionalImagePos.from_CanvasPos(pos, xform) for pos in (cp1, cp2) ] ipcs = [ ImagePixelCoordinate.from_FractionalImagePos(pos, img_size) for pos in fips ] width = int(round(abs(ipcs[1].x - ipcs[0].x)) + 0.1) height = int(round(abs(ipcs[1].y - ipcs[0].y)) + 0.1) return ImagePixelCoordinate(width, height)
def recenter(self): center_x = 0.5 * (self.right + self.left) center_y = 0.5 * (self.bottom + self.top) if center_x == 0 and center_y == 0: return self._dirty = True # 1) change clip box self.right -= center_x self.left = -self.right self.top -= center_y self.bottom = -self.top # 2) change camera(s) dcp = CanvasPos(center_x, center_y) self.camera.center -= CanvasPos(center_x, center_y) # 3) change image center(s) for img in self.images: fpc = img.transform.center cpc = CanvasPos.from_FractionalImagePos(fpc, img.transform) cpc += dcp fpc = FractionalImagePos.from_CanvasPos(cpc, img.transform) img.transform.center = fpc
def x_fract_from_canvas(self, pos: CanvasPos) -> FractionalImagePos: return FractionalImagePos.from_CanvasPos(pos, self.image.transform)
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.ui = uic.loadUi( uifile=pkg_resources.resource_stream("schmereo", "schmereo.ui"), baseinstance=self, ) # Platform-specific semantic keyboard shortcuts cannot be set in Qt Designer self.ui.actionNew.setShortcut(QKeySequence.New) self.ui.actionOpen.setShortcut(QKeySequence.Open) self.ui.actionQuit.setShortcut( QKeySequence.Quit) # no effect on Windows self.ui.actionSave.setShortcut(QKeySequence.Save) self.ui.actionSave_Project_As.setShortcut(QKeySequence.SaveAs) self.ui.actionZoom_In.setShortcuts( [QKeySequence.ZoomIn, "Ctrl+="]) # '=' so I don't need to press SHIFT self.ui.actionZoom_Out.setShortcut(QKeySequence.ZoomOut) # self.recent_files = RecentFileList( open_file_slot=self.load_file, settings_key="recent_files", menu=self.ui.menuRecent_Files, ) # Link views self.shared_camera = Camera() self.ui.leftImageWidget.camera = self.shared_camera self.ui.rightImageWidget.camera = self.shared_camera # self.ui.leftImageWidget.file_dropped.connect(self.load_left_file) self.ui.rightImageWidget.file_dropped.connect(self.load_right_file) # self.ui.leftImageWidget.image.transform.center = FractionalImagePos( -0.5, 0) self.ui.rightImageWidget.image.transform.center = FractionalImagePos( +0.5, 0) # for w in (self.ui.leftImageWidget, self.ui.rightImageWidget): w.messageSent.connect(self.ui.statusbar.showMessage) # self.marker_set = list() self.zoom_increment = 1.10 self.image_saver = ImageSaver(self.ui.leftImageWidget, self.ui.rightImageWidget) # TODO: object for AddMarker tool button tb = self.ui.addMarkerToolButton tb.setDefaultAction(self.ui.actionAdd_Marker) sz = 32 tb.setFixedSize(sz, sz) tb.setIconSize(QtCore.QSize(sz, sz)) hb = self.ui.handModeToolButton hb.setDefaultAction(self.ui.actionHand_Mode) hb.setFixedSize(sz, sz) hb.setIconSize(QtCore.QSize(sz, sz)) _set_action_icon( self.ui.actionAdd_Marker, "schmereo.marker", "crosshair64.png", "crosshair64blue.png", ) _set_action_icon(self.ui.actionHand_Mode, "schmereo", "cursor-openhand20.png") # tb.setDragEnabled(True) # TODO: drag tool button to place marker self.marker_manager = MarkerManager(self) self.aligner = Aligner(self) self.project_file_name = None # self.undo_stack = QUndoStack(self) undo_action = self.undo_stack.createUndoAction(self, '&Undo') undo_action.setShortcuts(QKeySequence.Undo) redo_action = self.undo_stack.createRedoAction(self, '&Redo') redo_action.setShortcuts(QKeySequence.Redo) self.undo_stack.cleanChanged.connect(self.on_undoStack_cleanChanged) # self.ui.menuEdit.insertAction(self.ui.actionAlign_Now, undo_action) self.ui.menuEdit.insertAction(self.ui.actionAlign_Now, redo_action) self.ui.menuEdit.insertSeparator(self.ui.actionAlign_Now) self.clip_box = ClipBox(parent=self, camera=self.shared_camera, images=[i.image for i in self.eye_widgets()]) self.ui.actionResolve_Clip_Box.triggered.connect( self.recenter_clip_box) for w in self.eye_widgets(): w.undo_stack = self.undo_stack w.clip_box = self.clip_box self.clip_box.changed.connect(w.update) self.project_folder = None