mirror of
https://github.com/wassname/scikit-image.git
synced 2026-07-05 02:47:08 +08:00
Merge pull request #233 from wilsaj:image-html-repr
Conflicts: skimage/io/tests/test_collection.py
This commit is contained in:
+49
-2
@@ -1,14 +1,61 @@
|
||||
__all__ = ['imread', 'imread_collection', 'imsave', 'imshow', 'show',
|
||||
__all__ = ['Image', 'imread', 'imread_collection', 'imsave', 'imshow', 'show',
|
||||
'push', 'pop']
|
||||
|
||||
from skimage.io._plugins import call as call_plugin
|
||||
from skimage.color import rgb2grey
|
||||
import numpy as np
|
||||
|
||||
try:
|
||||
import cStringIO as StringIO
|
||||
except ImportError:
|
||||
import StringIO
|
||||
|
||||
|
||||
# Shared image queue
|
||||
_image_stack = []
|
||||
|
||||
|
||||
class Image(np.ndarray):
|
||||
"""Class representing Image data.
|
||||
|
||||
These objects have tags for image metadata and IPython display protocol
|
||||
methods for image display.
|
||||
"""
|
||||
|
||||
tags = {'filename': '',
|
||||
'EXIF': {},
|
||||
'info': {}}
|
||||
|
||||
def __new__(cls, arr, **kwargs):
|
||||
"""Set the image data and tags according to given parameters.
|
||||
|
||||
Input:
|
||||
------
|
||||
arr : ndarray
|
||||
Image data.
|
||||
kwargs : Image tags as keywords
|
||||
Specified in the form ``tag0=value``, ``tag1=value``.
|
||||
|
||||
"""
|
||||
x = np.asarray(arr).view(cls)
|
||||
for tag, value in Image.tags.items():
|
||||
setattr(x, tag, kwargs.get(tag, getattr(arr, tag, value)))
|
||||
return x
|
||||
|
||||
def _repr_png_(self):
|
||||
return self._repr_image_format('png')
|
||||
|
||||
def _repr_jpeg_(self):
|
||||
return self._repr_image_format('jpeg')
|
||||
|
||||
def _repr_image_format(self, format_str):
|
||||
str_buffer = StringIO.StringIO()
|
||||
imsave(str_buffer, self, format_str=format_str)
|
||||
return_str = str_buffer.getvalue()
|
||||
str_buffer.close()
|
||||
return return_str
|
||||
|
||||
|
||||
def push(img):
|
||||
"""Push an image onto the shared image stack.
|
||||
|
||||
@@ -77,7 +124,7 @@ def imread(fname, as_grey=False, plugin=None, flatten=None,
|
||||
if as_grey and getattr(img, 'ndim', 0) >= 3:
|
||||
img = rgb2grey(img)
|
||||
|
||||
return img
|
||||
return Image(img)
|
||||
|
||||
|
||||
def imread_collection(load_pattern, conserve_memory=True,
|
||||
|
||||
@@ -59,17 +59,21 @@ def _palette_is_grayscale(pil_image):
|
||||
return np.allclose(np.diff(valid_palette), 0)
|
||||
|
||||
|
||||
def imsave(fname, arr):
|
||||
def imsave(fname, arr, format_str=None):
|
||||
"""Save an image to disk.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
fname : str
|
||||
fname : str or file-like object
|
||||
Name of destination file.
|
||||
arr : ndarray of uint8 or float
|
||||
Array (image) to save. Arrays of data-type uint8 should have
|
||||
values in [0, 255], whereas floating-point arrays must be
|
||||
in [0, 1].
|
||||
format_str: str
|
||||
Format to save as, this is required if using a file-like object;
|
||||
this is optional if fname is a string and the format can be
|
||||
derived from the extension.
|
||||
|
||||
Notes
|
||||
-----
|
||||
@@ -101,7 +105,7 @@ def imsave(fname, arr):
|
||||
arr = arr.astype(np.uint8)
|
||||
|
||||
img = Image.fromstring(mode, (arr.shape[1], arr.shape[0]), arr.tostring())
|
||||
img.save(fname)
|
||||
img.save(fname, format=format_str)
|
||||
|
||||
|
||||
def imshow(arr):
|
||||
|
||||
@@ -7,8 +7,8 @@ import sys
|
||||
window_manager.acquire('qt')
|
||||
|
||||
try:
|
||||
from PyQt4.QtGui import (QApplication, QMainWindow, QImage, QPixmap,
|
||||
QLabel, QWidget)
|
||||
from PyQt4.QtGui import (QApplication, QImage,
|
||||
QLabel, QMainWindow, QPixmap, QWidget)
|
||||
from PyQt4 import QtCore, QtGui
|
||||
import sip
|
||||
import warnings
|
||||
@@ -148,12 +148,21 @@ def _app_show():
|
||||
print 'No images to show. See `imshow`.'
|
||||
|
||||
|
||||
def imsave(filename, img):
|
||||
def imsave(filename, img, format_str=None):
|
||||
# we can add support for other than 3D uint8 here...
|
||||
img = prepare_for_display(img)
|
||||
qimg = QImage(img.data, img.shape[1], img.shape[0],
|
||||
img.strides[0], QImage.Format_RGB888)
|
||||
saved = qimg.save(filename)
|
||||
if _is_filelike(filename):
|
||||
byte_array = QtCore.QByteArray()
|
||||
qbuffer = QtCore.QBuffer(byte_array)
|
||||
qbuffer.open(QtCore.QIODevice.ReadWrite)
|
||||
saved = qimg.save(qbuffer, format_str.upper())
|
||||
qbuffer.seek(0)
|
||||
filename.write(qbuffer.readAll())
|
||||
qbuffer.close()
|
||||
else:
|
||||
saved = qimg.save(filename)
|
||||
if not saved:
|
||||
from textwrap import dedent
|
||||
msg = dedent(
|
||||
@@ -161,3 +170,7 @@ def imsave(filename, img):
|
||||
for the QT imsave plugin are:
|
||||
BMP, JPG, JPEG, PNG, PPM, TIFF, XBM, XPM''')
|
||||
raise RuntimeError(msg)
|
||||
|
||||
|
||||
def _is_filelike(possible_filelike):
|
||||
return callable(getattr(possible_filelike, 'write', None))
|
||||
|
||||
@@ -8,6 +8,7 @@ from numpy.testing.decorators import skipif
|
||||
from skimage import data_dir
|
||||
from skimage.io import ImageCollection, MultiImage
|
||||
from skimage.io.collection import alphanumeric_key
|
||||
from skimage.io import Image as ioImage
|
||||
|
||||
|
||||
try:
|
||||
@@ -54,7 +55,7 @@ class TestImageCollection():
|
||||
def test_getitem(self):
|
||||
num = len(self.collection)
|
||||
for i in range(-num, num):
|
||||
assert type(self.collection[i]) is np.ndarray
|
||||
assert type(self.collection[i]) is ioImage
|
||||
assert_array_almost_equal(self.collection[0],
|
||||
self.collection[-num])
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ def setup_module(self):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
@skipif(not PIL_available)
|
||||
def test_imread_flatten():
|
||||
# a color image is flattened
|
||||
@@ -78,6 +79,20 @@ def test_imread_uint16():
|
||||
assert_array_almost_equal(img, expected)
|
||||
|
||||
|
||||
@skipif(not PIL_available)
|
||||
def test_repr_png():
|
||||
img_path = os.path.join(data_dir, 'camera.png')
|
||||
original_img = imread(img_path)
|
||||
original_img_str = original_img._repr_png_()
|
||||
|
||||
with NamedTemporaryFile(suffix='.png', mode='r+') as temp_png:
|
||||
temp_png.write(original_img_str)
|
||||
temp_png.seek(0)
|
||||
round_trip = imread(temp_png)
|
||||
|
||||
assert np.all(original_img == round_trip)
|
||||
|
||||
|
||||
# Big endian images not correctly loaded for PIL < 1.1.7
|
||||
# Renable test when PIL 1.1.7 is more common.
|
||||
@skipif(True)
|
||||
|
||||
Reference in New Issue
Block a user