From 61712442ebe79181e9ec8b1aff992243eaad4c0c Mon Sep 17 00:00:00 2001 From: jevans Date: Tue, 11 Jun 2013 19:07:44 -0400 Subject: [PATCH] Added reduce=-1 to get lowest resolution thumbnail. Closes #38. --- docs/source/how_do_i.rst | 12 ++++++++++++ glymur/jp2k.py | 19 +++++++++++++++++-- glymur/test/test_jp2k.py | 13 +++++++++++-- 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/docs/source/how_do_i.rst b/docs/source/how_do_i.rst index 82f03bd..5206f79 100644 --- a/docs/source/how_do_i.rst +++ b/docs/source/how_do_i.rst @@ -3,6 +3,18 @@ How do I...? ------------ +Read the lowest resolution thumbnail? +===================================== +Printing the Jp2k object should reveal the number of resolutions (look in the +COD segment section), but you can take a shortcut by supplying -1 as the reduce +level. + + >>> import pkg_resources + >>> import glymur + >>> file = pkg_resources.resource_filename(glymur.__name__, "data/nemo.jp2") + >>> j = glymur.Jp2k(file) + >>> thumbnail = j.read(reduce=-1) + Display metadata? ================= There are two ways. From the unix command line, the script *jp2dump* is diff --git a/glymur/jp2k.py b/glymur/jp2k.py index a42e291..adba2cc 100644 --- a/glymur/jp2k.py +++ b/glymur/jp2k.py @@ -407,7 +407,8 @@ class Jp2k(Jp2kBox): layer : int, optional Number of quality layer to decode. reduce : int, optional - Factor by which to reduce output resolution. + Factor by which to reduce output resolution. Use -1 to get the + lowest resolution thumbnail. area : tuple, optional Specifies decoding image area, (first_row, first_col, last_row, last_col) @@ -432,7 +433,15 @@ class Jp2k(Jp2kBox): >>> import pkg_resources as pkg >>> jfile = pkg.resource_filename(glymur.__name__, "data/nemo.jp2") >>> jp = glymur.Jp2k(jfile) - >>> data = jp.read(reduce=1) + >>> image = jp.read() + >>> image.shape + (1456, 2592, 3) + + Read the lowest resolution thumbnail. + + >>> thumbnail = jp.read(reduce=-1) + >>> thumbnail.shape + (46, 81, 3) """ # Check for differing subsample factors. codestream = self.get_codestream(header_only=True) @@ -490,6 +499,12 @@ class Jp2k(Jp2kBox): dparam.decod_format = self._codec_format dparam.cp_layer = layer + + if reduce == -1: + # Get the lowest resolution thumbnail. + codestream = self.get_codestream() + reduce = codestream.segment[2].SPcod[4] + dparam.cp_reduce = reduce if area is not None: if area[0] < 0 or area[1] < 0: diff --git a/glymur/test/test_jp2k.py b/glymur/test/test_jp2k.py index 5e9ab9b..249bc5e 100644 --- a/glymur/test/test_jp2k.py +++ b/glymur/test/test_jp2k.py @@ -53,7 +53,8 @@ class TestJp2k(unittest.TestCase): @classmethod def setUpClass(cls): - # Setup a JP2 file with a bad XML box. + # Setup a JP2 file with a bad XML box. We only need to do this once + # per class rather than once per test. jp2file = pkg_resources.resource_filename(glymur.__name__, "data/nemo.jp2") with tempfile.NamedTemporaryFile(suffix='.jp2', delete=False) as tfile: @@ -92,10 +93,18 @@ class TestJp2k(unittest.TestCase): "Uses features introduced in 3.2.") def test_invalid_xml_box_warning(self): # Should be able to recover from xml box with bad xml. - # Just verify that a warning is issued on 3.2+ + # Just verify that a warning is issued on 3.3+ with self.assertWarns(UserWarning) as cw: jp2k = Jp2k(self._bad_xml_file) + def test_reduce_max(self): + # Verify that reduce=-1 gets us the lowest resolution image + j = Jp2k(self.jp2file) + thumbnail1 = j.read(reduce=-1) + thumbnail2 = j.read(reduce=5) + np.testing.assert_array_equal(thumbnail1, thumbnail2) + self.assertEqual(thumbnail1.shape, (46, 81, 3)) + def test_invalid_xml_box(self): # Should be able to recover from xml box with bad xml. with warnings.catch_warnings():