mirror of
https://github.com/wassname/scikit-image.git
synced 2026-08-12 12:30:16 +08:00
Merge branch 'io' of git://github.com/sccolbert/scikits.image
This commit is contained in:
@@ -4,6 +4,8 @@
|
||||
*egg-info
|
||||
*.so
|
||||
*.bak
|
||||
*.c
|
||||
.gitignore
|
||||
doc/source/api
|
||||
doc/build
|
||||
source/api
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
"""Utilities to read and write images in various formats."""
|
||||
|
||||
import pil_plugin
|
||||
import matplotlib_plugin
|
||||
import qt_plugin
|
||||
from _plugins import load as load_plugin
|
||||
from _plugins import use as use_plugin
|
||||
from _plugins import available as plugins
|
||||
|
||||
from plugin import register as register_plugin
|
||||
# Add this plugin so that we can read images by default
|
||||
load_plugin('pil')
|
||||
|
||||
from sift import *
|
||||
from collection import *
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
import numpy as np
|
||||
|
||||
# utilities to make life easier for plugin writers.
|
||||
|
||||
|
||||
def prepare_for_display(npy_img):
|
||||
'''Convert a 2D or 3D numpy array of any dtype into a
|
||||
3D numpy array with dtype uint8. This array will
|
||||
be suitable for use in passing to gui toolkits for
|
||||
image display purposes.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
npy_img : ndarray, 2D or 3D
|
||||
The image to convert for display
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : ndarray, 3D dtype=np.uint8
|
||||
The converted image. This is guaranteed to be a contiguous array.
|
||||
|
||||
Notes
|
||||
-----
|
||||
If the input image is floating point, it is assumed that the data
|
||||
is in the range of 0.0 - 1.0. No check is made to assert this
|
||||
condition. The image is then scaled to be in the range 0 - 255
|
||||
and then cast to np.uint8
|
||||
|
||||
For all other dtypes, the array is simply cast to np.uint8
|
||||
|
||||
If a 2D array is passed, the single channel is replicated
|
||||
to the 2nd and 3rd channels.
|
||||
|
||||
If the array contains an alpha channel, this channel is
|
||||
ignored.
|
||||
|
||||
'''
|
||||
if len(npy_img.shape) < 2:
|
||||
raise ValueError('Image must be 2D or 3D array')
|
||||
|
||||
height = npy_img.shape[0]
|
||||
width = npy_img.shape[1]
|
||||
|
||||
out = np.empty((height, width, 3), dtype=np.uint8)
|
||||
|
||||
if len(npy_img.shape) == 2 or \
|
||||
(len(npy_img.shape) == 3 and npy_img.shape[2] == 1):
|
||||
if npy_img.dtype in [np.float32, np.float64]:
|
||||
out[:,:,0] = npy_img*255
|
||||
out[:,:,1] = out[:,:,0]
|
||||
out[:,:,2] = out[:,:,0]
|
||||
else:
|
||||
out[:,:,0] = npy_img
|
||||
out[:,:,1] = npy_img
|
||||
out[:,:,2] = npy_img
|
||||
|
||||
elif len(npy_img.shape) == 3:
|
||||
if npy_img.shape[2] == 3 or npy_img.shape[2] == 4:
|
||||
if npy_img.dtype in [np.float32, np.float64]:
|
||||
out[:,:,:3] = (npy_img[:,:,:3])*255
|
||||
else:
|
||||
out[:,:,:3] = npy_img[:,:,:3]
|
||||
else:
|
||||
raise ValueError('Image must have 1, 3, or 4 channels')
|
||||
|
||||
else:
|
||||
raise ValueError('Image must have 2 or 3 dimensions')
|
||||
|
||||
return out
|
||||
@@ -0,0 +1 @@
|
||||
from plugin import *
|
||||
@@ -0,0 +1,61 @@
|
||||
from util import prepare_for_display, window_manager, GuiLockError
|
||||
import plugin
|
||||
|
||||
try:
|
||||
# we try to aquire the gui lock first
|
||||
# or else the gui import might trample another
|
||||
# gui's pyos_inputhook.
|
||||
window_manager.acquire('gtk')
|
||||
except GuiLockError, gle:
|
||||
print gle
|
||||
else:
|
||||
try:
|
||||
import gtk
|
||||
except ImportError:
|
||||
print 'pygtk libraries not installed.'
|
||||
print 'plugin not loaded.'
|
||||
window_manager._release('gtk')
|
||||
else:
|
||||
|
||||
class ImageWindow(gtk.Window):
|
||||
def __init__(self, arr, mgr):
|
||||
gtk.Window.__init__(self)
|
||||
self.mgr = mgr
|
||||
self.mgr.add_window(self)
|
||||
|
||||
self.connect("destroy", self.destroy)
|
||||
|
||||
width = arr.shape[1]
|
||||
height = arr.shape[0]
|
||||
rstride = arr.strides[0]
|
||||
pb = gtk.gdk.pixbuf_new_from_data(arr.data,
|
||||
gtk.gdk.COLORSPACE_RGB,
|
||||
False, 8, width, height,
|
||||
rstride)
|
||||
self.img = gtk.Image()
|
||||
self.img.set_from_pixbuf(pb)
|
||||
|
||||
self.add(self.img)
|
||||
self.img.show()
|
||||
|
||||
def destroy(self, widget, data=None):
|
||||
self.mgr.remove_window(self)
|
||||
|
||||
def gtk_imshow(arr):
|
||||
arr = prepare_for_display(arr)
|
||||
|
||||
iw = ImageWindow(arr, window_manager)
|
||||
iw.show()
|
||||
|
||||
def gtk_show():
|
||||
if window_manager.has_images():
|
||||
window_manager.register_callback(gtk.main_quit)
|
||||
gtk.main()
|
||||
else:
|
||||
print 'no images to display'
|
||||
|
||||
|
||||
plugin.register('gtk', show=gtk_imshow, appshow=gtk_show)
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@ import plugin
|
||||
|
||||
try:
|
||||
import matplotlib.pyplot as plt
|
||||
except ImportError:
|
||||
pass
|
||||
except ImportError, e:
|
||||
print e
|
||||
else:
|
||||
plugin.register('matplotlib', show=plt.imshow, save=plt.imsave)
|
||||
@@ -1,7 +1,7 @@
|
||||
__all__ = ['imread']
|
||||
|
||||
import numpy as np
|
||||
import plugin
|
||||
import numpy as np
|
||||
|
||||
try:
|
||||
from PIL import Image
|
||||
@@ -51,4 +51,4 @@ def palette_is_grayscale(pil_image):
|
||||
|
||||
|
||||
if has_pil:
|
||||
plugin.register('PIL', read=imread)
|
||||
plugin.register('pil', read=imread)
|
||||
@@ -2,13 +2,14 @@
|
||||
|
||||
"""
|
||||
|
||||
__all__ = ['register', 'use']
|
||||
__all__ = ['register', 'use', 'load', 'available', 'call']
|
||||
|
||||
import warnings
|
||||
|
||||
plugin_store = {'read': [],
|
||||
'save': [],
|
||||
'show': []}
|
||||
'show': [],
|
||||
'appshow': []}
|
||||
|
||||
def register(name, **kwds):
|
||||
"""Register an image I/O plugin.
|
||||
@@ -38,7 +39,7 @@ def register(name, **kwds):
|
||||
if not callable(func):
|
||||
raise ValueError('Can only register functions as plugins.')
|
||||
|
||||
plugin_store[kind].append((name, func))
|
||||
plugin_store[kind].insert(0, (name, func))
|
||||
|
||||
|
||||
def call(kind, *args, **kwargs):
|
||||
@@ -60,7 +61,11 @@ def call(kind, *args, **kwargs):
|
||||
|
||||
plugin_funcs = plugin_store[kind]
|
||||
if len(plugin_funcs) == 0:
|
||||
raise RuntimeError('No suitable plugin registered for %s' % kind)
|
||||
raise RuntimeError('''No suitable plugin registered for %s.
|
||||
|
||||
You may load I/O plugins with the `scikits.image.io.load_plugin`
|
||||
command. A list of all available plugins can be found using
|
||||
`scikits.image.io.plugins()`.''' % kind)
|
||||
|
||||
plugin = kwargs.pop('plugin', None)
|
||||
if plugin is None:
|
||||
@@ -123,8 +128,9 @@ def available(kind=None):
|
||||
Parameters
|
||||
----------
|
||||
kind : {'show', 'save', 'read'}, optional
|
||||
Display the plugin list for the given function type. If not specified,
|
||||
return a dictionary with the plugins for all functions.
|
||||
Display the plugin list for the given function type. If not
|
||||
specified, return a dictionary with the plugins for all
|
||||
functions.
|
||||
|
||||
"""
|
||||
if kind is None:
|
||||
@@ -141,3 +147,21 @@ def available(kind=None):
|
||||
d[k] = [name for (name, func) in plugin_store[k]]
|
||||
|
||||
return d
|
||||
|
||||
def load(plugin):
|
||||
"""Load the given plugin.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
plugin : str
|
||||
Name of plugin to load.
|
||||
|
||||
See Also
|
||||
--------
|
||||
plugins : List of available plugins
|
||||
|
||||
"""
|
||||
try:
|
||||
__import__('scikits.image.io._plugins.' + plugin + "_plugin")
|
||||
except ImportError:
|
||||
raise ValueError('Plugin %s not found.' % plugin)
|
||||
@@ -0,0 +1,73 @@
|
||||
import plugin
|
||||
from util import prepare_for_display, window_manager, GuiLockError
|
||||
|
||||
import numpy as np
|
||||
import sys
|
||||
|
||||
|
||||
try:
|
||||
# we try to aquire the gui lock first
|
||||
# or else the gui import might trample another
|
||||
# gui's pyos_inputhook.
|
||||
window_manager.acquire('qt')
|
||||
|
||||
except GuiLockError, gle:
|
||||
print gle
|
||||
|
||||
else:
|
||||
try:
|
||||
from PyQt4.QtGui import (QApplication, QMainWindow, QImage, QPixmap,
|
||||
QLabel)
|
||||
|
||||
except ImportError:
|
||||
print 'pyqt4 libraries not installed.'
|
||||
print 'plugin not loaded'
|
||||
window_manager._release('qt')
|
||||
|
||||
else:
|
||||
|
||||
app = None
|
||||
|
||||
class ImageWindow(QMainWindow):
|
||||
def __init__(self, arr, mgr):
|
||||
QMainWindow.__init__(self)
|
||||
self.mgr = mgr
|
||||
img = QImage(arr.data, arr.shape[1], arr.shape[0],
|
||||
QImage.Format_RGB888)
|
||||
pm = QPixmap.fromImage(img)
|
||||
|
||||
label = QLabel()
|
||||
label.setPixmap(pm)
|
||||
label.show()
|
||||
|
||||
self.label = label
|
||||
self.setCentralWidget(self.label)
|
||||
self.mgr.add_window(self)
|
||||
|
||||
def closeEvent(self, event):
|
||||
# Allow window to be destroyed by removing any
|
||||
# references to it
|
||||
self.mgr.remove_window(self)
|
||||
|
||||
def qt_imshow(arr):
|
||||
global app
|
||||
|
||||
if not app:
|
||||
app = QApplication([])
|
||||
|
||||
arr = prepare_for_display(arr)
|
||||
|
||||
iw = ImageWindow(arr, window_manager)
|
||||
iw.show()
|
||||
|
||||
def qt_show():
|
||||
global app
|
||||
if app and window_manager.has_images():
|
||||
app.exec_()
|
||||
else:
|
||||
print 'no images to show'
|
||||
|
||||
plugin.register('qt', show=qt_imshow, appshow=qt_show)
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
import plugin
|
||||
|
||||
def save(fname, arr):
|
||||
return fname, arr
|
||||
|
||||
plugin.register('test', save=save)
|
||||
@@ -0,0 +1,151 @@
|
||||
import numpy as np
|
||||
|
||||
# utilities to make life easier for plugin writers.
|
||||
|
||||
|
||||
class GuiLockError(Exception):
|
||||
def __init__(self, msg):
|
||||
self.msg = msg
|
||||
|
||||
def __str__(self):
|
||||
return self.msg
|
||||
|
||||
class WindowManager(object):
|
||||
''' A class to keep track of spawned windows,
|
||||
and make any needed callback once all the windows,
|
||||
are closed.'''
|
||||
def __init__(self):
|
||||
self._windows = []
|
||||
self._callback = None
|
||||
self._callback_args = ()
|
||||
self._callback_kwargs = {}
|
||||
self._gui_lock = False
|
||||
self._guikit = ''
|
||||
|
||||
def _check_locked(self):
|
||||
if not self._gui_lock:
|
||||
raise GuiLockError(\
|
||||
'Must first acquire the gui lock before using this image manager')
|
||||
|
||||
def _exec_callback(self):
|
||||
if self._callback:
|
||||
self._callback(*self._callback_args, **self._callback_kwargs)
|
||||
|
||||
def acquire(self, kit):
|
||||
if self._gui_lock:
|
||||
raise GuiLockError(\
|
||||
'The gui lock can only be acquired by one toolkit per session. \
|
||||
The lock is already aquired by %s' % self._guikit)
|
||||
else:
|
||||
self._gui_lock = True
|
||||
self._guikit = str(kit)
|
||||
|
||||
def _release(self, kit):
|
||||
# releaseing the lock will lose all references to currently
|
||||
# track images and callback.
|
||||
# this function is private for reason!
|
||||
self._check_locked()
|
||||
if str(kit) == self._guikit:
|
||||
self._windows = []
|
||||
self._callback = None
|
||||
self._callback_args = ()
|
||||
self._callback_kwargs = {}
|
||||
self._gui_lock = False
|
||||
self._guikit = ''
|
||||
else:
|
||||
raise RuntimeError('Only the toolkit that owns the lock may release it')
|
||||
|
||||
def add_window(self, win):
|
||||
self._check_locked()
|
||||
self._windows.append(win)
|
||||
|
||||
def remove_window(self, win):
|
||||
self._check_locked()
|
||||
try:
|
||||
self._windows.remove(win)
|
||||
except ValueError:
|
||||
print 'Unable to find referenced window in tracked windows.'
|
||||
print 'Ignoring...'
|
||||
else:
|
||||
if len(self._windows) == 0:
|
||||
self._exec_callback()
|
||||
|
||||
def register_callback(self, cb, *cbargs, **cbkwargs):
|
||||
self._check_locked()
|
||||
self._callback = cb
|
||||
self._callback_args = cbargs
|
||||
self._callback_kwargs = cbkwargs
|
||||
|
||||
def has_images(self):
|
||||
if len(self._windows) > 0:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
window_manager = WindowManager()
|
||||
|
||||
|
||||
def prepare_for_display(npy_img):
|
||||
'''Convert a 2D or 3D numpy array of any dtype into a
|
||||
3D numpy array with dtype uint8. This array will
|
||||
be suitable for use in passing to gui toolkits for
|
||||
image display purposes.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
npy_img : ndarray, 2D or 3D
|
||||
The image to convert for display
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : ndarray, 3D dtype=np.uint8
|
||||
The converted image. This is guaranteed to be a contiguous array.
|
||||
|
||||
Notes
|
||||
-----
|
||||
If the input image is floating point, it is assumed that the data
|
||||
is in the range of 0.0 - 1.0. No check is made to assert this
|
||||
condition. The image is then scaled to be in the range 0 - 255
|
||||
and then cast to np.uint8
|
||||
|
||||
For all other dtypes, the array is simply cast to np.uint8
|
||||
|
||||
If a 2D array is passed, the single channel is replicated
|
||||
to the 2nd and 3rd channels.
|
||||
|
||||
If the array contains an alpha channel, this channel is
|
||||
ignored.
|
||||
|
||||
'''
|
||||
if len(npy_img.shape) < 2:
|
||||
raise ValueError('Image must be 2D or 3D array')
|
||||
|
||||
height = npy_img.shape[0]
|
||||
width = npy_img.shape[1]
|
||||
|
||||
out = np.empty((height, width, 3), dtype=np.uint8)
|
||||
|
||||
if len(npy_img.shape) == 2 or \
|
||||
(len(npy_img.shape) == 3 and npy_img.shape[2] == 1):
|
||||
if npy_img.dtype in [np.float32, np.float64]:
|
||||
out[:,:,0] = npy_img*255
|
||||
out[:,:,1] = out[:,:,0]
|
||||
out[:,:,2] = out[:,:,0]
|
||||
else:
|
||||
out[:,:,0] = npy_img
|
||||
out[:,:,1] = npy_img
|
||||
out[:,:,2] = npy_img
|
||||
|
||||
elif len(npy_img.shape) == 3:
|
||||
if npy_img.shape[2] == 3 or npy_img.shape[2] == 4:
|
||||
if npy_img.dtype in [np.float32, np.float64]:
|
||||
out[:,:,:3] = (npy_img[:,:,:3])*255
|
||||
else:
|
||||
out[:,:,:3] = npy_img[:,:,:3]
|
||||
else:
|
||||
raise ValueError('Image must have 1, 3, or 4 channels')
|
||||
|
||||
else:
|
||||
raise ValueError('Image must have 2 or 3 dimensions')
|
||||
|
||||
return out
|
||||
+19
-6
@@ -1,6 +1,6 @@
|
||||
__all__ = ['imread', 'imsave', 'imshow']
|
||||
__all__ = ['imread', 'imsave', 'imshow', 'show']
|
||||
|
||||
from scikits.image.io import plugin as _plugin
|
||||
from scikits.image.io._plugins import call as call_plugin
|
||||
|
||||
def imread(fname, as_grey=False, dtype=None, plugin=None, flatten=None,
|
||||
**plugin_args):
|
||||
@@ -44,8 +44,8 @@ def imread(fname, as_grey=False, dtype=None, plugin=None, flatten=None,
|
||||
if flatten is not None:
|
||||
as_grey = flatten
|
||||
|
||||
return _plugin.call('read', fname, as_grey=as_grey, dtype=dtype,
|
||||
plugin=plugin, **plugin_args)
|
||||
return call_plugin('read', fname, as_grey=as_grey, dtype=dtype,
|
||||
plugin=plugin, **plugin_args)
|
||||
|
||||
def imsave(fname, arr, plugin=None, **plugin_args):
|
||||
"""Save an image to file.
|
||||
@@ -67,7 +67,7 @@ def imsave(fname, arr, plugin=None, **plugin_args):
|
||||
Passed to the given plugin.
|
||||
|
||||
"""
|
||||
return _plugin.call('save', fname, arr, plugin=plugin, **plugin_args)
|
||||
return call_plugin('save', fname, arr, plugin=plugin, **plugin_args)
|
||||
|
||||
def imshow(arr, plugin=None, **plugin_args):
|
||||
"""Display an image.
|
||||
@@ -87,4 +87,17 @@ def imshow(arr, plugin=None, **plugin_args):
|
||||
Passed to the given plugin.
|
||||
|
||||
"""
|
||||
return _plugin.call('show', arr, plugin=plugin, **plugin_args)
|
||||
return call_plugin('show', arr, plugin=plugin, **plugin_args)
|
||||
|
||||
def show():
|
||||
'''Launches the event loop of the current gui plugin,
|
||||
and displays all pending images. This is required,
|
||||
when using imshow() from a non-interactive script.
|
||||
Simply make all the calls to imshow() to queue up as many
|
||||
images as you need, then call show(). After the
|
||||
last window is closed, the gui event loop will exit,
|
||||
and you script will continue execution.
|
||||
|
||||
If this is called from the interactive terminal,
|
||||
it will block until all windows are closed.'''
|
||||
return call_plugin('appshow')
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
import plugin
|
||||
from _plugin_util import prepare_for_display
|
||||
|
||||
import numpy as np
|
||||
import sys
|
||||
|
||||
app = None
|
||||
windows = []
|
||||
|
||||
try:
|
||||
from PyQt4.QtGui import (QApplication, QMainWindow, QImage, QPixmap,
|
||||
QLabel)
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
|
||||
class ImageWindow(QMainWindow):
|
||||
def __init__(self, arr):
|
||||
QMainWindow.__init__(self)
|
||||
|
||||
img = QImage(arr.data, arr.shape[1], arr.shape[0],
|
||||
QImage.Format_RGB888)
|
||||
pm = QPixmap.fromImage(img)
|
||||
|
||||
label = QLabel()
|
||||
label.setPixmap(pm)
|
||||
label.show()
|
||||
|
||||
self.label = label
|
||||
self.setCentralWidget(self.label)
|
||||
|
||||
def closeEvent(self, event):
|
||||
# Allow window to be destroyed by removing any
|
||||
# references to it
|
||||
windows.remove(self)
|
||||
|
||||
def show(arr, block=True):
|
||||
global app
|
||||
|
||||
if not '-qt4thread' in sys.argv and app is None:
|
||||
app = QApplication([])
|
||||
|
||||
arr = prepare_for_display(arr)
|
||||
|
||||
iw = ImageWindow(arr)
|
||||
iw.show()
|
||||
|
||||
# Keep track of window so that it doesn't get destroyed
|
||||
windows.append(iw)
|
||||
|
||||
if app and block:
|
||||
app.exec_()
|
||||
|
||||
plugin.register('qt', show=show)
|
||||
|
||||
if __name__ == "__main__":
|
||||
import scikits.image.io as io
|
||||
|
||||
io.plugin.use('qt', 'show')
|
||||
|
||||
img = np.empty((200, 200, 3), dtype=np.uint8)
|
||||
img[:50, :50, 0] = 100
|
||||
img[25:100, 25:100, 1] = 200
|
||||
img[:, :, 2] = 155
|
||||
io.imshow(img, block=False)
|
||||
io.imshow(img)
|
||||
@@ -3,7 +3,7 @@ import numpy as np
|
||||
|
||||
from scikits.image import data_dir
|
||||
from scikits.image.io import imread
|
||||
from scikits.image.io.pil_plugin import palette_is_grayscale
|
||||
from scikits.image.io._plugins.pil_plugin import palette_is_grayscale
|
||||
|
||||
def test_imread_flatten():
|
||||
# a color image is flattened and returned as float32
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from numpy.testing import *
|
||||
|
||||
from scikits.image import io
|
||||
from scikits.image.io import plugin
|
||||
from scikits.image.io._plugins import plugin
|
||||
|
||||
from copy import deepcopy
|
||||
|
||||
@@ -23,7 +23,7 @@ def show_other(arr):
|
||||
|
||||
def setup_module(self):
|
||||
self.backup_plugin_store = deepcopy(plugin.plugin_store)
|
||||
plugin.register('test', read=read, save=save, show=show)
|
||||
plugin.register('testcase', read=read, save=save, show=show)
|
||||
plugin.register('other', show=show_other)
|
||||
|
||||
def teardown_module(self):
|
||||
@@ -31,13 +31,13 @@ def teardown_module(self):
|
||||
|
||||
class TestPlugin:
|
||||
def test_read(self):
|
||||
io.imread('test.png', as_grey=True, dtype='i4', plugin='test')
|
||||
io.imread('test.png', as_grey=True, dtype='i4', plugin='testcase')
|
||||
|
||||
def test_save(self):
|
||||
io.imsave('test.png', [1, 2, 3], plugin='test')
|
||||
io.imsave('test.png', [1, 2, 3], plugin='testcase')
|
||||
|
||||
def test_show(self):
|
||||
io.imshow([1, 2, 3], plugin_arg=(1, 2), plugin='test')
|
||||
io.imshow([1, 2, 3], plugin_arg=(1, 2), plugin='testcase')
|
||||
|
||||
def test_use(self):
|
||||
plugin.use('other', 'show')
|
||||
@@ -48,5 +48,12 @@ class TestPlugin:
|
||||
d = plugin.available('show')
|
||||
assert d['show'][0] == 'other'
|
||||
|
||||
def test_load(self):
|
||||
plugin.load('test')
|
||||
fname, arr = io.imsave('outfile', [1, 2, 3])
|
||||
assert_equal(fname, 'outfile')
|
||||
assert_equal(arr, [1, 2, 3])
|
||||
assert_equal(plugin.available('save')['save'][0], 'test')
|
||||
|
||||
if __name__ == "__main__":
|
||||
run_module_suite()
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
import numpy as np
|
||||
import plugin
|
||||
from _plugin_util import prepare_for_display
|
||||
|
||||
try:
|
||||
import wx
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
|
||||
# idea shamelessly taken from here:
|
||||
# http://wiki.wxpython.org/WorkingWithImages
|
||||
|
||||
class ImagePanel(wx.Panel):
|
||||
def __init__(self, parent, id):
|
||||
wx.Panel.__init__(self, parent, id)
|
||||
self.bitmap = None
|
||||
self.Bind(wx.EVT_PAINT, self.OnPaint)
|
||||
|
||||
def display(self, npy_img):
|
||||
self.bitmap = self.get_bitmap(npy_img)
|
||||
self.Refresh(True)
|
||||
|
||||
def OnPaint(self, evt):
|
||||
dc = wx.PaintDC(self)
|
||||
if self.bitmap:
|
||||
dc.DrawBitmap(self.bitmap, 0, 0)
|
||||
|
||||
def get_bitmap(self, npy_img):
|
||||
width = npy_img.shape[1]
|
||||
height = npy_img.shape[0]
|
||||
wx_img = wx.EmptyImage(width, height)
|
||||
wx_img.SetData(npy_img.data)
|
||||
return wx.BitmapFromImage(wx_img)
|
||||
|
||||
|
||||
class ImageFrame(wx.Frame):
|
||||
def __init__(self, img):
|
||||
self.img = img
|
||||
width = img.shape[1]
|
||||
height = img.shape[0]
|
||||
wx.Frame.__init__(self, None, -1, 'wx', wx.DefaultPosition,
|
||||
wx.Size(width, height))
|
||||
|
||||
self.iPanel = ImagePanel(self, -1)
|
||||
self.iPanel.display(self.img)
|
||||
|
||||
def wx_imshow(img):
|
||||
f = ImageFrame(prepare_for_display(img))
|
||||
f.CenterOnScreen()
|
||||
f.Show()
|
||||
|
||||
plugin.register('wx', show=wx_imshow)
|
||||
+1687
-2225
File diff suppressed because it is too large
Load Diff
+7840
-8017
File diff suppressed because it is too large
Load Diff
@@ -1,2 +1,2 @@
|
||||
version='unbuilt-dev'
|
||||
|
||||
# THIS FILE IS GENERATED FROM THE SCIKITS.IMAGE SETUP.PY
|
||||
version='0.2dev'
|
||||
|
||||
Reference in New Issue
Block a user