From d3edd350f9baa5d771b12492e3aba859ef7956e6 Mon Sep 17 00:00:00 2001 From: Tony S Yu Date: Sun, 23 Dec 2012 16:19:03 -0800 Subject: [PATCH] ENH: Add open and save menu actions --- skimage/viewer/utils/dialogs.py | 26 +++++++++++++++++++++++++ skimage/viewer/viewers/core.py | 32 ++++++++++++++++++++++++++++++- skimage/viewer/widgets/history.py | 10 +++------- 3 files changed, 60 insertions(+), 8 deletions(-) create mode 100644 skimage/viewer/utils/dialogs.py diff --git a/skimage/viewer/utils/dialogs.py b/skimage/viewer/utils/dialogs.py new file mode 100644 index 00000000..849fcad7 --- /dev/null +++ b/skimage/viewer/utils/dialogs.py @@ -0,0 +1,26 @@ +import os + +try: + from PyQt4 import QtGui +except ImportError: + print("Could not import PyQt4 -- skimage.viewer not available.") + + +def open_file_dialog(default_format='png'): + """Return user-selected file path.""" + filename = str(QtGui.QFileDialog.getOpenFileName()) + if len(filename) == 0: + return None + return filename + + +def save_file_dialog(default_format='png'): + """Return user-selected file path.""" + filename = str(QtGui.QFileDialog.getSaveFileName()) + if len(filename) == 0: + return None + #TODO: io plugins should assign default image formats + basename, ext = os.path.splitext(filename) + if not ext: + filename = '%s.%s' % (filename, default_format) + return filename diff --git a/skimage/viewer/viewers/core.py b/skimage/viewer/viewers/core.py index 1c369707..83ef65a3 100644 --- a/skimage/viewer/viewers/core.py +++ b/skimage/viewer/viewers/core.py @@ -8,9 +8,11 @@ except ImportError: QMainWindow = object # hack to prevent nosetest and autodoc errors print("Could not import PyQt4 -- skimage.viewer not available.") +from skimage import io from skimage.util.dtype import dtype_range from .. import utils from ..widgets import Slider +from ..utils import dialogs __all__ = ['ImageViewer', 'CollectionViewer'] @@ -58,7 +60,11 @@ class ImageViewer(QMainWindow): self.setWindowTitle("Image Viewer") self.file_menu = QtGui.QMenu('&File', self) - self.file_menu.addAction('&Quit', self.close, + self.file_menu.addAction('Open file', self.open_file, + QtCore.Qt.CTRL + QtCore.Qt.Key_O) + self.file_menu.addAction('Save to file', self.save_to_file, + QtCore.Qt.CTRL + QtCore.Qt.Key_S) + self.file_menu.addAction('Quit', self.close, QtCore.Qt.CTRL + QtCore.Qt.Key_Q) self.menuBar().addMenu(self.file_menu) @@ -101,6 +107,30 @@ class ImageViewer(QMainWindow): plugin.attach(self) return self + def open_file(self): + """Open image file and display in viewer.""" + filename = dialogs.open_file_dialog() + if filename is None: + return + image = io.imread(filename) + self.original_image = image # update saved image + self.image = image # update displayed image + + def save_to_file(self): + """Save current image to file. + + The current behavior is not ideal: It saves the image displayed on + screen, so all images will be converted to RGB, and the image size is + not preserved (resizing the viewer window will alter the size of the + saved image). + """ + filename = dialogs.save_file_dialog() + if filename is None: + return + extent = self.ax.get_window_extent() + extent = extent.transformed(self.fig.dpi_scale_trans.inverted()) + self.fig.savefig(filename, bbox_inches=extent) + def closeEvent(self, event): self.close() diff --git a/skimage/viewer/widgets/history.py b/skimage/viewer/widgets/history.py index ce87f9ac..e3aaa938 100644 --- a/skimage/viewer/widgets/history.py +++ b/skimage/viewer/widgets/history.py @@ -1,4 +1,3 @@ -import os from textwrap import dedent try: @@ -11,6 +10,7 @@ import numpy as np import skimage from skimage import io from .core import BaseWidget +from ..utils import dialogs __all__ = ['OKCancelButtons', 'SaveButtons'] @@ -84,13 +84,9 @@ class SaveButtons(BaseWidget): notify(msg) def save_to_file(self): - filename = str(QtGui.QFileDialog.getSaveFileName()) - if len(filename) == 0: + filename = dialogs.save_file_dialog() + if filename is None: return - #TODO: io plugins should assign default image formats - basename, ext = os.path.splitext(filename) - if not ext: - filename = '%s.%s' % (filename, self.default_format) image = self.plugin.filtered_image if image.dtype == np.bool: #TODO: This check/conversion should probably be in `imsave`.