def test_load_pixbuf_size_dimensions(self): # Use both: # - a format with support for resizing at the decoding stage: JPEG # - a format that does not support resizing at the decoding stage: PNG for name in ( 'pattern.jpg', 'pattern-opaque-rgba.png', ): image = get_test_image(name) image_path = get_image_path(image.name) # Check image is unchanged if smaller than target dimensions. target_size = 2 * image.size[0], 2 * image.size[1] expected = Image.open(image_path).convert(image.mode) result = image_tools.load_pixbuf_size(image_path, *target_size) msg = ( 'load_pixbuf_size("%s", %dx%d) failed; ' 'result %%(diff_type)s differs: %%(diff)s' % ((name,) + target_size) ) self.assertImagesEqual(result, expected, msg=msg) # Check image is scaled down if bigger than target dimensions, # and that aspect ratio is kept. target_size = image.size[0], image.size[1] / 2 result = image_tools.load_pixbuf_size(image_path, *target_size) msg = ( 'load_pixbuf_size("%s", %dx%d) failed; ' 'result %%(diff_type)s differs: %%(diff)s' % ((name,) + target_size) ) self.assertEqual((result.get_width(), result.get_height()), (image.size[0] / 2, image.size[1] / 2))
def test_load_pixbuf_size_dimensions(self): # Use both: # - a format with support for resizing at the decoding stage: JPEG # - a format that does not support resizing at the decoding stage: PNG for name in ( 'pattern.jpg', 'pattern-opaque-rgba.png', ): image = get_test_image(name) image_path = get_image_path(image.name) # Check image is unchanged if smaller than target dimensions. target_size = 2 * image.size[0], 2 * image.size[1] expected = Image.open(image_path).convert(image.mode) result = image_tools.load_pixbuf_size(image_path, *target_size) msg = ('load_pixbuf_size("%s", %dx%d) failed; ' 'result %%(diff_type)s differs: %%(diff)s' % ((name, ) + target_size)) self.assertImagesEqual(result, expected, msg=msg) # Check image is scaled down if bigger than target dimensions, # and that aspect ratio is kept. target_size = image.size[0], image.size[1] / 2 result = image_tools.load_pixbuf_size(image_path, *target_size) msg = ('load_pixbuf_size("%s", %dx%d) failed; ' 'result %%(diff_type)s differs: %%(diff)s' % ((name, ) + target_size)) self.assertEqual((result.get_width(), result.get_height()), (image.size[0] / 2, image.size[1] / 2))
def _create_thumbnail_pixbuf(self, filepath): """ Creates a thumbnail pixbuf from <filepath>, and returns it as a tuple along with a file metadata dictionary: (pixbuf, tEXt_data) """ if archive_tools.archive_mime_type(filepath) is not None: extractor = archive_extractor.Extractor() tmpdir = tempfile.mkdtemp(prefix=u'mcomix_archive_thumb.') condition = extractor.setup(filepath, tmpdir) files = extractor.get_files() wanted = self._guess_cover(files) if wanted: extractor.set_files([wanted]) extractor.extract() image_path = os.path.join(tmpdir, wanted) condition.acquire() while not extractor.is_ready(wanted): condition.wait() condition.release() if not os.path.isfile(image_path): return None, None pixbuf = image_tools.load_pixbuf_size(image_path, self.width, self.height) tEXt_data = self._get_text_data(image_path) # Use the archive's mTime instead of the extracted file's mtime tEXt_data['tEXt::Thumb::MTime'] = str(long(os.stat(filepath).st_mtime)) shutil.rmtree(tmpdir, True) return pixbuf, tEXt_data else: # Then check for subarchives by file extension and # extract only the first... subs = filter(constants.SUPPORTED_ARCHIVE_REGEX.search, files) if subs: extractor.set_files([subs[0]]) extractor.extract() condition.acquire() while not extractor.is_ready(subs[0]): condition.wait() condition.release() subpath = os.path.join(tmpdir, subs[0]) # Recursively try to find an image to use as cover return self._create_thumbnail_pixbuf(subpath) shutil.rmtree(tmpdir, True) return None, None elif image_tools.is_image_file(filepath): pixbuf = image_tools.load_pixbuf_size(filepath, self.width, self.height) tEXt_data = self._get_text_data(filepath) return pixbuf, tEXt_data else: return None, None
def _create_thumbnail_pixbuf(self, filepath): """ Creates a thumbnail pixbuf from <filepath>, and returns it as a tuple along with a file metadata dictionary: (pixbuf, tEXt_data) """ if self.archive_support: mime = archive_tools.archive_mime_type(filepath) else: mime = None if mime is not None: cleanup = [] try: tmpdir = tempfile.mkdtemp(prefix=u'mcomix_archive_thumb.') cleanup.append(lambda: shutil.rmtree(tmpdir, True)) archive = archive_tools.get_recursive_archive_handler( filepath, tmpdir, type=mime) if archive is None: return None, None cleanup.append(archive.close) files = archive.list_contents() wanted = self._guess_cover(files) if wanted is None: return None, None archive.extract(wanted, tmpdir) image_path = os.path.join(tmpdir, wanted) if not os.path.isfile(image_path): return None, None pixbuf = image_tools.load_pixbuf_size(image_path, self.width, self.height) if self.store_on_disk: tEXt_data = self._get_text_data(image_path) # Use the archive's mTime instead of the extracted file's mtime tEXt_data['tEXt::Thumb::MTime'] = str( long(os.stat(filepath).st_mtime)) else: tEXt_data = None return pixbuf, tEXt_data finally: for fn in reversed(cleanup): fn() elif image_tools.is_image_file(filepath): pixbuf = image_tools.load_pixbuf_size(filepath, self.width, self.height) if self.store_on_disk: tEXt_data = self._get_text_data(filepath) else: tEXt_data = None return pixbuf, tEXt_data else: return None, None
def _create_thumbnail_pixbuf(self, filepath): """ Creates a thumbnail pixbuf from <filepath>, and returns it as a tuple along with a file metadata dictionary: (pixbuf, tEXt_data) """ if self.archive_support: mime = archive_tools.archive_mime_type(filepath) else: mime = None if mime is not None: cleanup = [] try: tmpdir = tempfile.mkdtemp(prefix=u'mcomix_archive_thumb.') cleanup.append(lambda: shutil.rmtree(tmpdir, True)) archive = archive_tools.get_recursive_archive_handler(filepath, tmpdir, type=mime) if archive is None: return None, None cleanup.append(archive.close) files = archive.list_contents() wanted = self._guess_cover(files) if wanted is None: return None, None archive.extract(wanted, tmpdir) image_path = os.path.join(tmpdir, wanted) if not os.path.isfile(image_path): return None, None pixbuf = image_tools.load_pixbuf_size(image_path, self.width, self.height) if self.store_on_disk: tEXt_data = self._get_text_data(image_path) # Use the archive's mTime instead of the extracted file's mtime tEXt_data['tEXt::Thumb::MTime'] = str(long(os.stat(filepath).st_mtime)) else: tEXt_data = None return pixbuf, tEXt_data finally: for fn in reversed(cleanup): fn() elif image_tools.is_image_file(filepath): pixbuf = image_tools.load_pixbuf_size(filepath, self.width, self.height) if self.store_on_disk: tEXt_data = self._get_text_data(filepath) else: tEXt_data = None return pixbuf, tEXt_data else: return None, None
def _create_thumbnail_pixbuf(self, filepath): ''' Creates a thumbnail pixbuf from <filepath>, and returns it as a tuple along with a file metadata dictionary: (pixbuf, tEXt_data) ''' if self.archive_support: mime = archive_tools.archive_mime_type(filepath) else: mime = None if mime is not None: if not archive_tools.is_archive_file(filepath): return None, None with archive_tools.get_recursive_archive_handler( filepath, type=mime, prefix='mcomix_archive_thumb.') as archive: if archive is None: return None, None if archive.is_encrypted: image_path = tools.pkg_path('images', 'encrypted-book.png') else: files = archive.list_contents(decrypt=False) wanted = self._guess_cover(files) if wanted is None: return None, None image_path = archive.extract(wanted) if not os.path.isfile(image_path): return None, None pixbuf = image_tools.load_pixbuf_size(image_path, self.width, self.height) if self.store_on_disk: tEXt_data = self._get_text_data(image_path) # Use the archive's mTime instead of the extracted file's mtime tEXt_data['tEXt::Thumb::MTime'] = str( os.stat(filepath).st_mtime) else: tEXt_data = None return pixbuf, tEXt_data elif image_tools.is_image_file(filepath, check_mimetype=True): pixbuf = image_tools.load_pixbuf_size(filepath, self.width, self.height) if self.store_on_disk: tEXt_data = self._get_text_data(filepath) else: tEXt_data = None return pixbuf, tEXt_data else: return None, None
def _create_thumbnail_pixbuf(self, filepath): """ Creates a thumbnail pixbuf from <filepath>, and returns it as a tuple along with a file metadata dictionary: (pixbuf, tEXt_data) """ if self.archive_support: mime = archive_tools.archive_mime_type(filepath) else: mime = None if mime is not None: with tempfile.TemporaryDirectory( prefix='mcomix_archive_thumb.') as tmpdir: archive = archive_tools.get_recursive_archive_handler( filepath, tmpdir, type=mime) if archive is None: return None, None files = archive.list_contents() wanted = self._guess_cover(files) if wanted is None: return None, None archive.extract(wanted, tmpdir) image_path = os.path.join(tmpdir, wanted) if not os.path.isfile(image_path): return None, None pixbuf = image_tools.load_pixbuf_size(image_path, self.width, self.height) if self.store_on_disk: tEXt_data = self._get_text_data(image_path) # Use the archive's mTime instead of the extracted file's mtime tEXt_data['tEXt::Thumb::MTime'] = str( os.stat(filepath).st_mtime) else: tEXt_data = None return pixbuf, tEXt_data elif image_tools.is_image_file(filepath): pixbuf = image_tools.load_pixbuf_size(filepath, self.width, self.height) if self.store_on_disk: tEXt_data = self._get_text_data(filepath) else: tEXt_data = None return pixbuf, tEXt_data else: return None, None
def test_load_pixbuf_size_basic(self): # Same as test_load_pixbuf_basic: # load bunch of images at their # normal resolution. prefs['checkered bg for transparent images'] = False for image in _TEST_IMAGES: if image.name in ( 'transparent.png', 'transparent-indexed.png', ): # Avoid complex transparent image, since PIL # and GdkPixbuf may yield different results. continue image_path = get_image_path(image.name) if self.use_pil: # When using PIL, indexed formats will be # converted to RGBA by pixbuf_to_pil. expected_mode = pil_mode_to_gdk_mode(image.mode) else: expected_mode = 'RGBA' if image.has_alpha else 'RGB' expected = Image.open(image_path).convert(expected_mode) if image.has_alpha: background = Image.new('RGBA', image.size, color='white') expected = Image.alpha_composite(background, expected) result = image_tools.load_pixbuf_size(image_path, image.size[0], image.size[1]) msg = ('load_pixbuf("%s") failed; ' 'result %%(diff_type)s differs: %%(diff)s' % (image.name, )) self.assertImagesEqual(result, expected, msg=msg)
def test_load_pixbuf_size_basic(self): # Same as test_load_pixbuf_basic: # load bunch of images at their # normal resolution. prefs['checkered bg for transparent images'] = False for image in _TEST_IMAGES: if image.name in ( 'transparent.png', 'transparent-indexed.png', ): # Avoid complex transparent image, since PIL # and GdkPixbuf may yield different results. continue image_path = get_image_path(image.name) if self.use_pil: # When using PIL, indexed formats will be # converted to RGBA by pixbuf_to_pil. expected_mode = pil_mode_to_gdk_mode(image.mode) else: expected_mode = 'RGBA' if image.has_alpha else 'RGB' expected = Image.open(image_path).convert(expected_mode) if image.has_alpha: background = Image.new('RGBA', image.size, color='white') expected = Image.alpha_composite(background, expected) result = image_tools.load_pixbuf_size(image_path, image.size[0], image.size[1]) msg = ( 'load_pixbuf("%s") failed; ' 'result %%(diff_type)s differs: %%(diff)s' % (image.name,) ) self.assertImagesEqual(result, expected, msg=msg)
def test_load_pixbuf_rounding_error(self): image_size = (2063, 3131) target_size = (500, 500) expected_size = (329, 500) tmp_file = tempfile.NamedTemporaryFile(prefix=u'image.', suffix=u'.png', delete=False) tmp_file.close() im = Image.new('RGB', image_size) im.save(tmp_file.name) pixbuf = image_tools.load_pixbuf_size(tmp_file.name, *target_size) self.assertEqual((pixbuf.get_width(), pixbuf.get_height()), expected_size)