Adding image_display widget
This commit is contained in:
@@ -12,16 +12,15 @@ from PySide6.QtWidgets import (
|
||||
QPushButton,
|
||||
QFileDialog,
|
||||
QMessageBox,
|
||||
QScrollArea,
|
||||
)
|
||||
from PySide6.QtGui import QPixmap, QImage
|
||||
from PySide6.QtCore import Qt
|
||||
from PySide6.QtCore import Qt, QSettings
|
||||
from pathlib import Path
|
||||
|
||||
from src.database.db_manager import DatabaseManager
|
||||
from src.utils.config_manager import ConfigManager
|
||||
from src.utils.image import Image, ImageLoadError
|
||||
from src.utils.logger import get_logger
|
||||
from src.gui.widgets import ImageDisplayWidget
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
@@ -68,20 +67,10 @@ class AnnotationTab(QWidget):
|
||||
display_group = QGroupBox("Image Display")
|
||||
display_layout = QVBoxLayout()
|
||||
|
||||
# Scroll area for image
|
||||
scroll_area = QScrollArea()
|
||||
scroll_area.setWidgetResizable(True)
|
||||
scroll_area.setMinimumHeight(400)
|
||||
|
||||
self.image_label = QLabel("No image loaded")
|
||||
self.image_label.setAlignment(Qt.AlignCenter)
|
||||
self.image_label.setStyleSheet(
|
||||
"QLabel { background-color: #2b2b2b; color: #888; }"
|
||||
)
|
||||
self.image_label.setScaledContents(False)
|
||||
|
||||
scroll_area.setWidget(self.image_label)
|
||||
display_layout.addWidget(scroll_area)
|
||||
# Use the reusable ImageDisplayWidget
|
||||
self.image_display_widget = ImageDisplayWidget()
|
||||
self.image_display_widget.zoom_changed.connect(self._on_zoom_changed)
|
||||
display_layout.addWidget(self.image_display_widget)
|
||||
|
||||
display_group.setLayout(display_layout)
|
||||
layout.addWidget(display_group)
|
||||
@@ -101,13 +90,26 @@ class AnnotationTab(QWidget):
|
||||
info_group.setLayout(info_layout)
|
||||
|
||||
layout.addWidget(info_group)
|
||||
|
||||
# Zoom controls info
|
||||
zoom_info = QLabel("Zoom: Mouse wheel or +/- keys to zoom in/out")
|
||||
zoom_info.setStyleSheet("QLabel { color: #888; font-style: italic; }")
|
||||
layout.addWidget(zoom_info)
|
||||
|
||||
self.setLayout(layout)
|
||||
|
||||
def _load_image(self):
|
||||
"""Load and display an image file."""
|
||||
# Get image repository path or use home directory
|
||||
repo_path = self.config_manager.get_image_repository_path()
|
||||
start_dir = repo_path if repo_path else str(Path.home())
|
||||
# Get last opened directory from QSettings
|
||||
settings = QSettings("microscopy_app", "object_detection")
|
||||
last_dir = settings.value("annotation_tab/last_directory", None)
|
||||
|
||||
# Fallback to image repository path or home directory
|
||||
if last_dir and Path(last_dir).exists():
|
||||
start_dir = last_dir
|
||||
else:
|
||||
repo_path = self.config_manager.get_image_repository_path()
|
||||
start_dir = repo_path if repo_path else str(Path.home())
|
||||
|
||||
# Open file dialog
|
||||
file_path, _ = QFileDialog.getOpenFileName(
|
||||
@@ -125,18 +127,16 @@ class AnnotationTab(QWidget):
|
||||
self.current_image = Image(file_path)
|
||||
self.current_image_path = file_path
|
||||
|
||||
# Update info label
|
||||
info_text = (
|
||||
f"File: {Path(file_path).name}\n"
|
||||
f"Size: {self.current_image.width}x{self.current_image.height} pixels\n"
|
||||
f"Channels: {self.current_image.channels}\n"
|
||||
f"Format: {self.current_image.format.upper()}\n"
|
||||
f"File size: {self.current_image.size_mb:.2f} MB"
|
||||
# Store the directory for next time
|
||||
settings.setValue(
|
||||
"annotation_tab/last_directory", str(Path(file_path).parent)
|
||||
)
|
||||
self.image_info_label.setText(info_text)
|
||||
|
||||
# Convert to QPixmap and display
|
||||
self._display_image()
|
||||
# Display image using the ImageDisplayWidget
|
||||
self.image_display_widget.load_image(self.current_image)
|
||||
|
||||
# Update info label
|
||||
self._update_image_info()
|
||||
|
||||
logger.info(f"Loaded image: {file_path}")
|
||||
|
||||
@@ -149,59 +149,27 @@ class AnnotationTab(QWidget):
|
||||
logger.error(f"Unexpected error loading image: {e}")
|
||||
QMessageBox.critical(self, "Error", f"Unexpected error:\n{str(e)}")
|
||||
|
||||
def _display_image(self):
|
||||
"""Display the current image in the image label."""
|
||||
def _update_image_info(self):
|
||||
"""Update the image info label with current image details."""
|
||||
if self.current_image is None:
|
||||
self.image_info_label.setText("No image loaded")
|
||||
return
|
||||
|
||||
try:
|
||||
# Get RGB image data
|
||||
rgb_data = self.current_image.get_rgb()
|
||||
zoom_percentage = self.image_display_widget.get_zoom_percentage()
|
||||
info_text = (
|
||||
f"File: {Path(self.current_image_path).name}\n"
|
||||
f"Size: {self.current_image.width}x{self.current_image.height} pixels\n"
|
||||
f"Channels: {self.current_image.channels}\n"
|
||||
f"Data type: {self.current_image.dtype}\n"
|
||||
f"Format: {self.current_image.format.upper()}\n"
|
||||
f"File size: {self.current_image.size_mb:.2f} MB\n"
|
||||
f"Zoom: {zoom_percentage}%"
|
||||
)
|
||||
self.image_info_label.setText(info_text)
|
||||
|
||||
# Convert numpy array to QImage
|
||||
height, width, channels = rgb_data.shape
|
||||
bytes_per_line = channels * width
|
||||
|
||||
if channels == 3:
|
||||
qimage = QImage(
|
||||
rgb_data.data,
|
||||
width,
|
||||
height,
|
||||
bytes_per_line,
|
||||
QImage.Format_RGB888,
|
||||
)
|
||||
else:
|
||||
# Grayscale
|
||||
qimage = QImage(
|
||||
rgb_data.data,
|
||||
width,
|
||||
height,
|
||||
bytes_per_line,
|
||||
QImage.Format_Grayscale8,
|
||||
)
|
||||
|
||||
# Convert to pixmap
|
||||
pixmap = QPixmap.fromImage(qimage)
|
||||
|
||||
# Scale to fit display (max 800px width or height)
|
||||
max_size = 800
|
||||
if pixmap.width() > max_size or pixmap.height() > max_size:
|
||||
pixmap = pixmap.scaled(
|
||||
max_size,
|
||||
max_size,
|
||||
Qt.KeepAspectRatio,
|
||||
Qt.SmoothTransformation,
|
||||
)
|
||||
|
||||
# Display in label
|
||||
self.image_label.setPixmap(pixmap)
|
||||
self.image_label.setScaledContents(False)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error displaying image: {e}")
|
||||
QMessageBox.warning(
|
||||
self, "Display Error", f"Failed to display image:\n{str(e)}"
|
||||
)
|
||||
def _on_zoom_changed(self, zoom_scale: float):
|
||||
"""Handle zoom level changes from the image display widget."""
|
||||
self._update_image_info()
|
||||
|
||||
def refresh(self):
|
||||
"""Refresh the tab."""
|
||||
|
||||
Reference in New Issue
Block a user