Skip to content

Commit

Permalink
ENH Partial support for reading gray+alpha PNGs
Browse files Browse the repository at this point in the history
Currently, reading gray+alpha PNGs is only possible by throwing away the
alpha channel.
  • Loading branch information
luispedro committed Sep 13, 2016
1 parent 2476c5b commit 8d000d0
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 7 deletions.
1 change: 1 addition & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ Version 0.5.1+
* Add `supports_format` function
* Make png compression level tunable when calling imsave
* Add imsave_multi
* Add partial support for reading PNG files in Gray+alpha format

Version 0.5.1 2014-11-06 by luispedro
* Improve tests to work after installation
Expand Down
5 changes: 3 additions & 2 deletions imread/_imread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,12 @@ PyObject* py_supports_format(PyObject* self, PyObject* args) {
PyObject* py_imread_may_multi(PyObject* self, PyObject* args, bool is_multi, bool is_blob) {
PyObject* filename_or_blob_object;
const char* formatstr;
if (!PyArg_ParseTuple(args, "Os", &filename_or_blob_object, &formatstr)) {
PyObject* optsDict;
if (!PyArg_ParseTuple(args, "OsO", &filename_or_blob_object, &formatstr, &optsDict)) {
PyErr_SetString(PyExc_RuntimeError,TypeErrorMsg);
return NULL;
}
options_map opts;
options_map opts = parse_options(optsDict);

try {
std::auto_ptr<ImageFormat> format(get_format(formatstr));
Expand Down
22 changes: 18 additions & 4 deletions imread/imread.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def _as_grey(im, as_grey):
transform = np.array([ 0.30, 0.59, 0.11])
return np.dot(im, transform)

def imread(filename, as_grey=False, formatstr=None, return_metadata=False):
def imread(filename, as_grey=False, formatstr=None, return_metadata=False, opts=None):
'''
im = imread(filename, as_grey=False, formatstr={filename extension}, return_metadata=False)
im,meta = imread(filename, as_grey=False, formatstr={filename extension}, return_metadata=True)
Expand All @@ -45,6 +45,11 @@ def imread(filename, as_grey=False, formatstr=None, return_metadata=False):
does not correspond to the format, you can pass it explicitly.
return_metadata : bool, optional
Whether to return metadata (default: False)
opts : dict, optional
Other options. Support will depend on the backend. Currently used
strip_alpha: bool
Whether to strip the alpha channel.
Returns
-------
Expand All @@ -60,9 +65,11 @@ def imread(filename, as_grey=False, formatstr=None, return_metadata=False):
imread_from_blob : function
Read from a in-memory string
'''
if opts is None:
opts = {}
formatstr = _parse_formatstr(filename, formatstr, 'imread')
reader = special.get(formatstr, _imread.imread)
imdata,meta = reader(filename, formatstr)
imdata,meta = reader(filename, formatstr, opts)
imdata = _as_grey(imdata, as_grey)
if return_metadata:
return imdata, meta
Expand All @@ -71,7 +78,7 @@ def imread(filename, as_grey=False, formatstr=None, return_metadata=False):
imload = imread


def imread_from_blob(blob, formatstr=None, as_grey=False, return_metadata=False):
def imread_from_blob(blob, formatstr=None, as_grey=False, return_metadata=False, opts=None):
'''
imdata = imread_from_blob(blob, formatstr=None, as_grey=False, return_metadata={True})
imdata,metadata = imread_from_blob(blob, formatstr=None, as_grey={False}, return_metadata=True)
Expand All @@ -93,6 +100,11 @@ def imread_from_blob(blob, formatstr=None, as_grey=False, return_metadata=False)
Whether to convert to grey scale image (default: no)
return_metadata : bool, optional
Whether to return metadata (default: False)
opts : dict, optional
Other options. Support will depend on the backend. Currently used
strip_alpha: bool
Whether to strip the alpha channel.
Returns
-------
Expand All @@ -108,10 +120,12 @@ def imread_from_blob(blob, formatstr=None, as_grey=False, return_metadata=False)
imread : function
Read from a file on disk
'''
if opts is None:
opts = {}
reader = _imread.imread_from_blob
if formatstr is None:
formatstr = detect_format(blob, is_blob=True)
imdata,meta = reader(blob, formatstr)
imdata,meta = reader(blob, formatstr, opts)
imdata = _as_grey(imdata, as_grey)
if return_metadata:
return imdata,meta
Expand Down
12 changes: 11 additions & 1 deletion imread/lib/_png.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2012-2014 Luis Pedro Coelho <[email protected]>
// Copyright 2012-2016 Luis Pedro Coelho <[email protected]>
// License: MIT (see COPYING.MIT file)

#include "base.h"
Expand Down Expand Up @@ -109,6 +109,10 @@ std::auto_ptr<Image> PNGFormat::read(byte_source* src, ImageFactory* factory, co
// PNGs are in "network" order (ie., big-endian)
if (bit_depth == 16 && !is_big_endian()) png_set_swap(p.png_ptr);

const bool strip_alpha = get_optional_bool(opts, "strip_alpha", false);
if (strip_alpha) {
png_set_strip_alpha(p.png_ptr);
}
int d = -1;
switch (png_get_color_type(p.png_ptr, p.png_info)) {
case PNG_COLOR_TYPE_PALETTE:
Expand All @@ -122,6 +126,12 @@ std::auto_ptr<Image> PNGFormat::read(byte_source* src, ImageFactory* factory, co
case PNG_COLOR_TYPE_GRAY:
d = -1;
break;
case PNG_COLOR_TYPE_GRAY_ALPHA:
if (!strip_alpha) {
throw CannotReadError("imread.png: Color type (4: grayscale with alpha channel) can only be read when strip_alpha is set to true.");
}
d = -1;
break;
default: {
std::ostringstream out;
out << "imread.png: Color type ("
Expand Down

0 comments on commit 8d000d0

Please sign in to comment.