Merge pull request #1634 from JDWarner/imsave_no_squeeze

FIX/STY: Remove magic and enforce PEP8 in plugins.
This commit is contained in:
Stefan van der Walt
2015-08-15 15:53:16 -07:00
6 changed files with 207 additions and 178 deletions
+4 -3
View File
@@ -8,7 +8,8 @@ except ImportError:
try:
import pyfits
except ImportError:
raise ImportError("PyFITS could not be found. Please refer to\n"
raise ImportError(
"PyFITS could not be found. Please refer to\n"
"http://www.stsci.edu/resources/software_hardware/pyfits\n"
"for further instructions.")
@@ -144,7 +145,7 @@ def FITSFactory(image_ext):
hdulist.close()
if data is None:
raise RuntimeError("Extension %d of %s has no data" %
(extnum, filename))
raise RuntimeError(
"Extension %d of %s has no data" % (extnum, filename))
return data
+183 -157
View File
@@ -28,8 +28,8 @@ def _generate_candidate_libs():
for lib_name in lib_names:
files = os.listdir(lib_dir)
lib_paths += [os.path.join(lib_dir, lib) for lib in files
if lib.lower().startswith(lib_name) and not
os.path.splitext(lib)[1] in ('.py', '.pyc', '.ini')]
if lib.lower().startswith(lib_name) and not
os.path.splitext(lib)[1] in ('.py', '.pyc', '.ini')]
lib_paths = [lp for lp in lib_paths if os.path.exists(lp)]
return lib_dirs, lib_paths
@@ -41,6 +41,7 @@ else:
LOADER = ctypes.cdll
FUNCTYPE = ctypes.CFUNCTYPE
def handle_errors():
global FT_ERROR_STR
if FT_ERROR_STR:
@@ -48,7 +49,10 @@ def handle_errors():
FT_ERROR_STR = None
raise RuntimeError(tmp)
FT_ERROR_STR = None
# This MUST happen in module scope, or the function pointer is garbage
# collected, leading to a segfault when error_handler is called.
@FUNCTYPE(None, ctypes.c_int, ctypes.c_char_p)
@@ -56,6 +60,7 @@ def c_error_handler(fif, message):
global FT_ERROR_STR
FT_ERROR_STR = 'FreeImage error: %s' % message
def load_freeimage():
freeimage = None
errors = []
@@ -63,7 +68,7 @@ def load_freeimage():
# in the default locations for each platform. Win DLL names don't need the
# extension, but other platforms do.
bare_libs = ['FreeImage', 'libfreeimage.dylib', 'libfreeimage.so',
'libfreeimage.so.3']
'libfreeimage.so.3']
lib_dirs, lib_paths = _generate_candidate_libs()
lib_paths = bare_libs + lib_paths
for lib in lib_paths:
@@ -86,13 +91,13 @@ def load_freeimage():
# No freeimage library loaded, and load-errors reported for some
# candidate libs
err_txt = ['%s:\n%s' % (l, str(e)) for l, e in errors]
raise RuntimeError('One or more FreeImage libraries were found, but '
'could not be loaded due to the following errors:\n'
'\n\n'.join(err_txt))
raise RuntimeError('One or more FreeImage libraries were found, '
'but could not be loaded due to the following '
'errors:\n\n\n'.join(err_txt))
else:
# No errors, because no potential libraries found at all!
raise RuntimeError('Could not find a FreeImage library in any of:\n' +
'\n'.join(lib_dirs))
raise RuntimeError('Could not find a FreeImage library in any of:'
'\n\n'.join(lib_dirs))
# FreeImage found
freeimage.FreeImage_SetOutputMessage(c_error_handler)
@@ -121,7 +126,7 @@ API = {
'FreeImage_Load': (ctypes.c_void_p, None),
'FreeImage_LockPage': (ctypes.c_void_p, None),
'FreeImage_OpenMultiBitmap': (ctypes.c_void_p, None)
}
}
# Albert's ctypes pattern
@@ -135,7 +140,7 @@ def register_api(lib, api):
register_api(_FI, API)
class FI_TYPES(object):
class FiTypes(object):
FIT_UNKNOWN = 0
FIT_BITMAP = 1
FIT_UINT16 = 2
@@ -150,51 +155,48 @@ class FI_TYPES(object):
FIT_RGBF = 11
FIT_RGBAF = 12
dtypes = {
FIT_BITMAP: numpy.uint8,
FIT_UINT16: numpy.uint16,
FIT_INT16: numpy.int16,
FIT_UINT32: numpy.uint32,
FIT_INT32: numpy.int32,
FIT_FLOAT: numpy.float32,
FIT_DOUBLE: numpy.float64,
FIT_COMPLEX: numpy.complex128,
FIT_RGB16: numpy.uint16,
FIT_RGBA16: numpy.uint16,
FIT_RGBF: numpy.float32,
FIT_RGBAF: numpy.float32
}
dtypes = {FIT_BITMAP: numpy.uint8,
FIT_UINT16: numpy.uint16,
FIT_INT16: numpy.int16,
FIT_UINT32: numpy.uint32,
FIT_INT32: numpy.int32,
FIT_FLOAT: numpy.float32,
FIT_DOUBLE: numpy.float64,
FIT_COMPLEX: numpy.complex128,
FIT_RGB16: numpy.uint16,
FIT_RGBA16: numpy.uint16,
FIT_RGBF: numpy.float32,
FIT_RGBAF: numpy.float32,
}
fi_types = {
(numpy.dtype('uint8'), 1): FIT_BITMAP,
(numpy.dtype('uint8'), 3): FIT_BITMAP,
(numpy.dtype('uint8'), 4): FIT_BITMAP,
(numpy.dtype('uint16'), 1): FIT_UINT16,
(numpy.dtype('int16'), 1): FIT_INT16,
(numpy.dtype('uint32'), 1): FIT_UINT32,
(numpy.dtype('int32'), 1): FIT_INT32,
(numpy.dtype('float32'), 1): FIT_FLOAT,
(numpy.dtype('float64'), 1): FIT_DOUBLE,
(numpy.dtype('complex128'), 1): FIT_COMPLEX,
(numpy.dtype('uint16'), 3): FIT_RGB16,
(numpy.dtype('uint16'), 4): FIT_RGBA16,
(numpy.dtype('float32'), 3): FIT_RGBF,
(numpy.dtype('float32'), 4): FIT_RGBAF
}
fi_types = {(numpy.dtype('uint8'), 1): FIT_BITMAP,
(numpy.dtype('uint8'), 3): FIT_BITMAP,
(numpy.dtype('uint8'), 4): FIT_BITMAP,
(numpy.dtype('uint16'), 1): FIT_UINT16,
(numpy.dtype('int16'), 1): FIT_INT16,
(numpy.dtype('uint32'), 1): FIT_UINT32,
(numpy.dtype('int32'), 1): FIT_INT32,
(numpy.dtype('float32'), 1): FIT_FLOAT,
(numpy.dtype('float64'), 1): FIT_DOUBLE,
(numpy.dtype('complex128'), 1): FIT_COMPLEX,
(numpy.dtype('uint16'), 3): FIT_RGB16,
(numpy.dtype('uint16'), 4): FIT_RGBA16,
(numpy.dtype('float32'), 3): FIT_RGBF,
(numpy.dtype('float32'), 4): FIT_RGBAF,
}
extra_dims = {
FIT_UINT16: [],
FIT_INT16: [],
FIT_UINT32: [],
FIT_INT32: [],
FIT_FLOAT: [],
FIT_DOUBLE: [],
FIT_COMPLEX: [],
FIT_RGB16: [3],
FIT_RGBA16: [4],
FIT_RGBF: [3],
FIT_RGBAF: [4]
}
extra_dims = {FIT_UINT16: [],
FIT_INT16: [],
FIT_UINT32: [],
FIT_INT32: [],
FIT_FLOAT: [],
FIT_DOUBLE: [],
FIT_COMPLEX: [],
FIT_RGB16: [3],
FIT_RGBA16: [4],
FIT_RGBF: [3],
FIT_RGBAF: [4],
}
@classmethod
def get_type_and_shape(cls, bitmap):
@@ -223,62 +225,79 @@ class FI_TYPES(object):
return numpy.dtype(dtype), extra_dims + [w, h]
class IO_FLAGS(object):
FIF_LOAD_NOPIXELS = 0x8000 # loading: load the image header only
# (not supported by all plugins)
class IoFlags(object):
# loading: load the image header only (not supported by all plugins)
FIF_LOAD_NOPIXELS = 0x8000
BMP_DEFAULT = 0
BMP_SAVE_RLE = 1
CUT_DEFAULT = 0
DDS_DEFAULT = 0
EXR_DEFAULT = 0 # save data as half with piz-based wavelet compression
EXR_FLOAT = 0x0001 # save data as float instead of as half (not recommended)
EXR_FLOAT = 0x0001 # save data as float instead of half (not recommended)
EXR_NONE = 0x0002 # save with no compression
EXR_ZIP = 0x0004 # save with zlib compression, in blocks of 16 scan lines
EXR_PIZ = 0x0008 # save with piz-based wavelet compression
EXR_PXR24 = 0x0010 # save with lossy 24-bit float compression
EXR_B44 = 0x0020 # save with lossy 44% float compression
# - goes to 22% when combined with EXR_LC
EXR_LC = 0x0040 # save images with one luminance and two chroma channels,
# rather than as RGB (lossy compression)
# save with lossy 44% float compression (22% when combined with EXR_LC)
EXR_B44 = 0x0020
# one luminance and two chroma channels rather than as RGB (lossy)
EXR_LC = 0x0040
FAXG3_DEFAULT = 0
GIF_DEFAULT = 0
GIF_LOAD256 = 1 # Load the image as a 256 color image with ununsed
# palette entries, if it's 16 or 2 color
GIF_PLAYBACK = 2 # 'Play' the GIF to generate each frame (as 32bpp)
# instead of returning raw frame data when loading
# Load as 256 color image with ununsed palette entries if 16 or 2 color
GIF_LOAD256 = 1
# 'Play' the GIF generating each frame (as 32bpp) instead of raw frame data
GIF_PLAYBACK = 2
HDR_DEFAULT = 0
ICO_DEFAULT = 0
ICO_MAKEALPHA = 1 # convert to 32bpp and create an alpha channel from the
# AND-mask when loading
# convert to 32bpp then add an alpha channel from the AND-mask when loading
ICO_MAKEALPHA = 1
IFF_DEFAULT = 0
J2K_DEFAULT = 0 # save with a 16:1 rate
JP2_DEFAULT = 0 # save with a 16:1 rate
JPEG_DEFAULT = 0 # loading (see JPEG_FAST);
# saving (see JPEG_QUALITYGOOD|JPEG_SUBSAMPLING_420)
JPEG_FAST = 0x0001 # load the file as fast as possible,
# sacrificing some quality
JPEG_ACCURATE = 0x0002 # load the file with the best quality,
# sacrificing some speed
JPEG_CMYK = 0x0004 # load separated CMYK "as is"
# (use | to combine with other load flags)
JPEG_EXIFROTATE = 0x0008 # load and rotate according to
# Exif 'Orientation' tag if available
# loading (see JPEG_FAST)
# saving (see JPEG_QUALITYGOOD|JPEG_SUBSAMPLING_420)
JPEG_DEFAULT = 0
# load the file as fast as possible, sacrificing some quality
JPEG_FAST = 0x0001
# load the file with the best quality, sacrificing some speed
JPEG_ACCURATE = 0x0002
# load separated CMYK "as is" (use | to combine with other load flags)
JPEG_CMYK = 0x0004
# load and rotate according to Exif 'Orientation' tag if available
JPEG_EXIFROTATE = 0x0008
JPEG_QUALITYSUPERB = 0x80 # save with superb quality (100:1)
JPEG_QUALITYGOOD = 0x0100 # save with good quality (75:1)
JPEG_QUALITYNORMAL = 0x0200 # save with normal quality (50:1)
JPEG_QUALITYAVERAGE = 0x0400 # save with average quality (25:1)
JPEG_QUALITYBAD = 0x0800 # save with bad quality (10:1)
JPEG_PROGRESSIVE = 0x2000 # save as a progressive-JPEG
# (use | to combine with other save flags)
JPEG_SUBSAMPLING_411 = 0x1000 # save with high 4x1 chroma
# subsampling (4:1:1)
JPEG_SUBSAMPLING_420 = 0x4000 # save with medium 2x2 medium chroma
# subsampling (4:2:0) - default value
JPEG_SUBSAMPLING_422 = 0x8000 # save with low 2x1 chroma subsampling (4:2:2)
# save as a progressive-JPEG (use | to combine with other save flags)
JPEG_PROGRESSIVE = 0x2000
# save with high 4x1 chroma subsampling (4:1:1)
JPEG_SUBSAMPLING_411 = 0x1000
# save with medium 2x2 medium chroma subsampling (4:2:0) - default value
JPEG_SUBSAMPLING_420 = 0x4000
# save with low 2x1 chroma subsampling (4:2:2)
JPEG_SUBSAMPLING_422 = 0x8000
JPEG_SUBSAMPLING_444 = 0x10000 # save with no chroma subsampling (4:4:4)
JPEG_OPTIMIZE = 0x20000 # on saving, compute optimal Huffman coding tables
# (can reduce a few percent of file size)
# compute optimal Huffman coding tables (can reduce file size a few %)
JPEG_OPTIMIZE = 0x20000 # on saving,
JPEG_BASELINE = 0x40000 # save basic JPEG, without metadata or any markers
KOALA_DEFAULT = 0
LBM_DEFAULT = 0
@@ -292,33 +311,40 @@ class IO_FLAGS(object):
PICT_DEFAULT = 0
PNG_DEFAULT = 0
PNG_IGNOREGAMMA = 1 # loading: avoid gamma correction
PNG_Z_BEST_SPEED = 0x0001 # save using ZLib level 1 compression flag
# (default value is 6)
PNG_Z_DEFAULT_COMPRESSION = 0x0006 # save using ZLib level 6 compression
# flag (default recommended value)
PNG_Z_BEST_COMPRESSION = 0x0009 # save using ZLib level 9 compression flag
# (default value is 6)
# save using ZLib level 1 compression flag (default value is 6)
PNG_Z_BEST_SPEED = 0x0001
# save using ZLib level 6 compression flag (default recommended value)
PNG_Z_DEFAULT_COMPRESSION = 0x0006
# save using ZLib level 9 compression flag (default value is 6)
PNG_Z_BEST_COMPRESSION = 0x0009
PNG_Z_NO_COMPRESSION = 0x0100 # save without ZLib compression
PNG_INTERLACED = 0x0200 # save using Adam7 interlacing (use | to combine
# with other save flags)
# save using Adam7 interlacing (use | to combine with other save flags)
PNG_INTERLACED = 0x0200
PNM_DEFAULT = 0
PNM_SAVE_RAW = 0 # Writer saves in RAW format (i.e. P4, P5 or P6)
PNM_SAVE_ASCII = 1 # Writer saves in ASCII format (i.e. P1, P2 or P3)
PSD_DEFAULT = 0
PSD_CMYK = 1 # reads tags for separated CMYK (default is conversion to RGB)
PSD_CMYK = 1 # reads tags for separated CMYK (default converts to RGB)
PSD_LAB = 2 # reads tags for CIELab (default is conversion to RGB)
RAS_DEFAULT = 0
RAW_DEFAULT = 0 # load the file as linear RGB 48-bit
RAW_PREVIEW = 1 # try to load the embedded JPEG preview with included
# Exif Data or default to RGB 24-bit
# try to load embedded JPEG preview from Exif Data or default to RGB 24-bit
RAW_PREVIEW = 1
RAW_DISPLAY = 2 # load the file as RGB 24-bit
SGI_DEFAULT = 0
TARGA_DEFAULT = 0
TARGA_LOAD_RGB888 = 1 # Convert RGB555 and ARGB8888 -> RGB888.
TARGA_SAVE_RLE = 2 # Save with RLE compression
TIFF_DEFAULT = 0
TIFF_CMYK = 0x0001 # reads/stores tags for separated CMYK
# (use | to combine with compression flags)
# reads/stores tags for separated CMYK
# (use | to combine with compression flags)
TIFF_CMYK = 0x0001
TIFF_PACKBITS = 0x0100 # save using PACKBITS compression
TIFF_DEFLATE = 0x0200 # save using DEFLATE (a.k.a. ZLIB) compression
TIFF_ADOBE_DEFLATE = 0x0400 # save using ADOBE DEFLATE compression
@@ -333,7 +359,7 @@ class IO_FLAGS(object):
XPM_DEFAULT = 0
class METADATA_MODELS(object):
class MetadataModels(object):
FIMD_COMMENTS = 0
FIMD_EXIF_MAIN = 1
FIMD_EXIF_EXIF = 2
@@ -346,7 +372,7 @@ class METADATA_MODELS(object):
FIMD_ANIMATION = 9
class METADATA_DATATYPE(object):
class MetadataDatatype(object):
FIDT_BYTE = 1 # 8-bit unsigned integer
FIDT_ASCII = 2 # 8-bit bytes w/ last byte null
FIDT_SHORT = 3 # 16-bit unsigned integer
@@ -365,27 +391,26 @@ class METADATA_DATATYPE(object):
FIDT_SLONG8 = 17 # 64-bit signed integer
FIDT_IFD8 = 18 # 64-bit unsigned integer (offset)
dtypes = {
FIDT_BYTE: numpy.uint8,
FIDT_SHORT: numpy.uint16,
FIDT_LONG: numpy.uint32,
FIDT_RATIONAL: [('numerator', numpy.uint32),
('denominator', numpy.uint32)],
FIDT_SBYTE: numpy.int8,
FIDT_UNDEFINED: numpy.uint8,
FIDT_SSHORT: numpy.int16,
FIDT_SLONG: numpy.int32,
FIDT_SRATIONAL: [('numerator', numpy.int32),
('denominator', numpy.int32)],
FIDT_FLOAT: numpy.float32,
FIDT_DOUBLE: numpy.float64,
FIDT_IFD: numpy.uint32,
FIDT_PALETTE: [('R', numpy.uint8), ('G', numpy.uint8),
('B', numpy.uint8), ('A', numpy.uint8)],
FIDT_LONG8: numpy.uint64,
FIDT_SLONG8: numpy.int64,
FIDT_IFD8: numpy.uint64
}
dtypes = {FIDT_BYTE: numpy.uint8,
FIDT_SHORT: numpy.uint16,
FIDT_LONG: numpy.uint32,
FIDT_RATIONAL: [('numerator', numpy.uint32),
('denominator', numpy.uint32)],
FIDT_SBYTE: numpy.int8,
FIDT_UNDEFINED: numpy.uint8,
FIDT_SSHORT: numpy.int16,
FIDT_SLONG: numpy.int32,
FIDT_SRATIONAL: [('numerator', numpy.int32),
('denominator', numpy.int32)],
FIDT_FLOAT: numpy.float32,
FIDT_DOUBLE: numpy.float64,
FIDT_IFD: numpy.uint32,
FIDT_PALETTE: [('R', numpy.uint8), ('G', numpy.uint8),
('B', numpy.uint8), ('A', numpy.uint8)],
FIDT_LONG8: numpy.uint64,
FIDT_SLONG8: numpy.int64,
FIDT_IFD8: numpy.uint64,
}
def _process_bitmap(filename, flags, process_func):
@@ -410,7 +435,7 @@ def read(filename, flags=0):
"""Read an image to a numpy array of shape (height, width) for
greyscale images, or shape (height, width, nchannels) for RGB or
RGBA images.
The `flags` parameter should be one or more values from the IO_FLAGS
The `flags` parameter should be one or more values from the IoFlags
class defined in this module, or-ed together with | as appropriate.
(See the source-code comments for more details.)
"""
@@ -422,9 +447,9 @@ def read_metadata(filename):
Returned dict maps (metadata_model, tag_name) keys to tag values, where
metadata_model is a string name based on the FreeImage "metadata models"
defined in the class METADATA_MODELS.
defined in the class MetadataModels.
"""
flags = IO_FLAGS.FIF_LOAD_NOPIXELS
flags = IoFlags.FIF_LOAD_NOPIXELS
return _process_bitmap(filename, flags, _read_metadata)
@@ -437,9 +462,8 @@ def _process_multipage(filename, flags, process_func):
create_new = False
read_only = True
keep_cache_in_memory = True
multibitmap = _FI.FreeImage_OpenMultiBitmap(ftype, filename, create_new,
read_only, keep_cache_in_memory,
flags)
multibitmap = _FI.FreeImage_OpenMultiBitmap(
ftype, filename, create_new, read_only, keep_cache_in_memory, flags)
handle_errors()
multibitmap = ctypes.c_void_p(multibitmap)
if not multibitmap:
@@ -454,7 +478,7 @@ def _process_multipage(filename, flags, process_func):
bitmap = ctypes.c_void_p(bitmap)
if not bitmap:
raise ValueError('Could not open %s as a multi-page image.'
% filename)
% filename)
try:
out.append(process_func(bitmap))
finally:
@@ -470,7 +494,7 @@ def read_multipage(filename, flags=0):
"""Read a multipage image to a list of numpy arrays, where each
array is of shape (height, width) for greyscale images, or shape
(height, width, nchannels) for RGB or RGBA images.
The `flags` parameter should be one or more values from the IO_FLAGS
The `flags` parameter should be one or more values from the IoFlags
class defined in this module, or-ed together with | as appropriate.
(See the source-code comments for more details.)
"""
@@ -481,7 +505,7 @@ def read_multipage_metadata(filename):
"""Read a multipage image to a list of metadata dicts, one dict for each
page. The dict format is as in read_metadata().
"""
flags = IO_FLAGS.FIF_LOAD_NOPIXELS
flags = IoFlags.FIF_LOAD_NOPIXELS
return _process_multipage(filename, flags, _read_metadata)
@@ -503,9 +527,9 @@ def _wrap_bitmap_bits_in_array(bitmap, shape, dtype):
strides = (itemsize, pitch)
bits = _FI.FreeImage_GetBits(bitmap)
handle_errors()
array = numpy.ndarray(shape, dtype=dtype,
buffer=(ctypes.c_char * byte_size).from_address(bits),
strides=strides)
array = numpy.ndarray(
shape, dtype=dtype,
buffer=(ctypes.c_char * byte_size).from_address(bits), strides=strides)
return array
@@ -513,8 +537,9 @@ def _array_from_bitmap(bitmap):
"""Convert a FreeImage bitmap pointer to a numpy array.
"""
dtype, shape = FI_TYPES.get_type_and_shape(bitmap)
dtype, shape = FiTypes.get_type_and_shape(bitmap)
array = _wrap_bitmap_bits_in_array(bitmap, shape, dtype)
# swizzle the color components and flip the scanlines to go from
# FreeImage's BGR[A] and upside-down internal memory format to something
# more normal
@@ -542,7 +567,7 @@ def _array_from_bitmap(bitmap):
def _read_metadata(bitmap):
metadata = {}
models = [(name[5:], number) for name, number in
METADATA_MODELS.__dict__.items() if name.startswith('FIMD_')]
MetadataModels.__dict__.items() if name.startswith('FIMD_')]
tag = ctypes.c_void_p()
for model_name, number in models:
@@ -560,15 +585,16 @@ def _read_metadata(bitmap):
char_ptr = ctypes.c_char * byte_size
tag_str = char_ptr.from_address(_FI.FreeImage_GetTagValue(tag))
handle_errors()
if tag_type == METADATA_DATATYPE.FIDT_ASCII:
if tag_type == MetadataDatatype.FIDT_ASCII:
tag_val = asstr(tag_str.value)
else:
tag_val = numpy.fromstring(tag_str,
dtype=METADATA_DATATYPE.dtypes[tag_type])
tag_val = numpy.fromstring(
tag_str, dtype=MetadataDatatype.dtypes[tag_type])
if len(tag_val) == 1:
tag_val = tag_val[0]
metadata[(model_name, tag_name)] = tag_val
more = _FI.FreeImage_FindNextMetadata(mdhandle, ctypes.byref(tag))
more = _FI.FreeImage_FindNextMetadata(mdhandle,
ctypes.byref(tag))
handle_errors()
_FI.FreeImage_FindCloseMetadata(mdhandle)
handle_errors()
@@ -579,7 +605,7 @@ def write(array, filename, flags=0):
"""Write a (height, width) or (height, width, nchannels) array to
a greyscale, RGB, or RGBA image, with file type deduced from the
filename.
The `flags` parameter should be one or more values from the IO_FLAGS
The `flags` parameter should be one or more values from the IoFlags
class defined in this module, or-ed together with | as appropriate.
(See the source-code comments for more details.)
"""
@@ -591,9 +617,9 @@ def write(array, filename, flags=0):
raise ValueError('Cannot determine type for %s' % filename)
bitmap, fi_type = _array_to_bitmap(array)
try:
if fi_type == FI_TYPES.FIT_BITMAP:
can_write = _FI.FreeImage_FIFSupportsExportBPP(ftype,
_FI.FreeImage_GetBPP(bitmap))
if fi_type == FiTypes.FIT_BITMAP:
can_write = _FI.FreeImage_FIFSupportsExportBPP(
ftype, _FI.FreeImage_GetBPP(bitmap))
handle_errors()
else:
can_write = _FI.FreeImage_FIFSupportsExportType(ftype, fi_type)
@@ -614,7 +640,7 @@ def write_multipage(arrays, filename, flags=0):
"""Write a list of (height, width) or (height, width, nchannels)
arrays to a multipage greyscale, RGB, or RGBA image, with file type
deduced from the filename.
The `flags` parameter should be one or more values from the IO_FLAGS
The `flags` parameter should be one or more values from the IoFlags
class defined in this module, or-ed together with | as appropriate.
(See the source-code comments for more details.)
"""
@@ -660,7 +686,7 @@ def _array_to_bitmap(array):
else:
n_channels = shape[0]
try:
fi_type = FI_TYPES.fi_types[(dtype, n_channels)]
fi_type = FiTypes.fi_types[(dtype, n_channels)]
except KeyError:
raise ValueError('Cannot write arrays of given type and shape.')
@@ -678,22 +704,22 @@ def _array_to_bitmap(array):
# swizzle the color components and flip the scanlines to go to
# FreeImage's BGR[A] and upside-down internal memory format
if len(shape) == 3 and _FI.FreeImage_IsLittleEndian():
R = array[:, :, 0]
G = array[:, :, 1]
B = array[:, :, 2]
r = array[:, :, 0]
g = array[:, :, 1]
b = array[:, :, 2]
if dtype.type == numpy.uint8:
wrapped_array[0] = n(B)
wrapped_array[1] = n(G)
wrapped_array[2] = n(R)
wrapped_array[0] = n(b)
wrapped_array[1] = n(g)
wrapped_array[2] = n(r)
elif dtype.type == numpy.uint16:
wrapped_array[0] = n(R)
wrapped_array[1] = n(G)
wrapped_array[2] = n(B)
wrapped_array[0] = n(r)
wrapped_array[1] = n(g)
wrapped_array[2] = n(b)
if shape[2] == 4:
A = array[:, :, 3]
wrapped_array[3] = n(A)
a = array[:, :, 3]
wrapped_array[3] = n(a)
else:
wrapped_array[:] = n(array)
if len(shape) == 2 and dtype.type == numpy.uint8:
+2 -1
View File
@@ -9,6 +9,7 @@ except ImportError:
"Please refer to http://pypi.python.org/pypi/imread/ "
"for further instructions.")
def imread(fname, dtype=None):
"""Load an image from file.
@@ -23,6 +24,7 @@ def imread(fname, dtype=None):
im = convert(im, dtype)
return im
def imsave(fname, arr, format_str=None):
"""Save an image to disk.
@@ -40,4 +42,3 @@ def imsave(fname, arr, format_str=None):
Currently, only 8-bit precision is supported.
"""
return _imread.imsave(fname, arr, formatstr=format_str)
+7 -7
View File
@@ -26,8 +26,8 @@ def imread(fname, dtype=None, img_num=None, **kwargs):
Notes
-----
Tiff files are handled by Christophe Golhke's tifffile.py [1]_, and support many
advanced image types including multi-page and floating point.
Tiff files are handled by Christophe Golhke's tifffile.py [1]_, and support
many advanced image types including multi-page and floating point.
All other files are read using the Python Imaging Libary.
See PIL docs [2]_ for a list of supported formats.
@@ -67,9 +67,9 @@ def pil_to_ndarray(im, dtype=None, img_num=None):
site = "http://pillow.readthedocs.org/en/latest/installation.html#external-libraries"
pillow_error_message = str(e)
error_message = ('Could not load "%s" \n'
'Reason: "%s"\n'
'Please see documentation at: %s'
% (im.filename, pillow_error_message, site))
'Reason: "%s"\n'
'Please see documentation at: %s'
% (im.filename, pillow_error_message, site))
raise ValueError(error_message)
frames = []
grayscale = None
@@ -255,7 +255,7 @@ def imsave(fname, arr, format_str=None, **kwargs):
and fname.lower().endswith(".png")):
format_str = "PNG"
arr = np.asanyarray(arr).squeeze()
arr = np.asanyarray(arr)
if arr.dtype.kind == 'b':
arr = arr.astype(np.uint8)
@@ -264,7 +264,7 @@ def imsave(fname, arr, format_str=None, **kwargs):
if hasattr(fname, 'lower'):
if fname.lower().endswith(('.tiff', '.tif')):
use_tif = True
if not format_str is None:
if format_str is not None:
if format_str.lower() in ['tiff', 'tif']:
use_tif = True
+9 -9
View File
@@ -94,23 +94,23 @@ def imread_qt(filename):
arrayptr = qtimg.bits()
# QT may pad the image, so we need to use bytesPerLine, not width for
# the conversion to a numpy array
bytesPerPixel = qtimg.depth() // 8
pixelsPerLine = qtimg.bytesPerLine() // bytesPerPixel
img_size = pixelsPerLine * qtimg.height() * bytesPerPixel
bytes_per_pixel = qtimg.depth() // 8
pixels_per_line = qtimg.bytesPerLine() // bytes_per_pixel
img_size = pixels_per_line * qtimg.height() * bytes_per_pixel
arrayptr.setsize(img_size)
img = np.array(arrayptr)
# Reshape and trim down to correct dimensions
if bytesPerPixel > 1:
img = img.reshape((qtimg.height(), pixelsPerLine, bytesPerPixel))
if bytes_per_pixel > 1:
img = img.reshape((qtimg.height(), pixels_per_line, bytes_per_pixel))
img = img[:, :qtimg.width(), :]
else:
img = img.reshape((qtimg.height(), pixelsPerLine))
img = img.reshape((qtimg.height(), pixels_per_line))
img = img[:, :qtimg.width()]
# Strip qt's false alpha channel if needed
# and reorder color axes as required
if bytesPerPixel == 4 and not qtimg.hasAlphaChannel():
if bytes_per_pixel == 4 and not qtimg.hasAlphaChannel():
img = img[:, :, 2::-1]
elif bytesPerPixel == 4:
elif bytes_per_pixel == 4:
img[:, :, 0:3] = img[:, :, 2::-1]
return img
@@ -151,7 +151,7 @@ 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)
img.strides[0], QImage.Format_RGB888)
if _is_filelike(filename):
byte_array = QtCore.QByteArray()
qbuffer = QtCore.QBuffer(byte_array)
+2 -1
View File
@@ -11,7 +11,8 @@ def imread(fname, dtype=None, **kwargs):
dtype : numpy dtype object or string specifier
Specifies data type of array elements (Not currently used).
kwargs : keyword pairs, optional
Addition keyword arguments to pass through (see `tifffile`'s `imread` function).
Additional keyword arguments to pass through (see ``tifffile``'s
``imread`` function).
Notes
-----