Implement function downsample_large() and corresponding test.
authorPhilipp Spitzer <philipp@spitzer.priv.at>
Thu, 27 Jun 2019 21:22:46 +0000 (23:22 +0200)
committerPhilipp Spitzer <philipp@spitzer.priv.at>
Thu, 27 Jun 2019 21:22:46 +0000 (23:22 +0200)
gimp_passport.py
test_gimp_passport.py

index 9583670..fe0b151 100644 (file)
@@ -1,7 +1,7 @@
 import argparse
 from itertools import count
 from numbers import Integral
-from typing import Tuple
+from typing import Tuple, Optional
 from PIL import Image, ImageDraw
 
 
@@ -145,6 +145,20 @@ def tile(img: Image, paper_width_mm: float, paper_height_mm: float, margin_mm: f
     return paper
 
 
+def downsample_large(img: Image, max_dpi: Optional[int]) -> Image:
+    """Downsamples the image to max_dpi (keeping dimensions) if (a) max_dpi is not None
+    and (b) the resolution is larger than max_dpi."""
+    if max_dpi is None:
+        return img
+    dpi = img.info['dpi'][0]
+    if dpi <= max_dpi:
+        return img
+    width, height = img.size
+    width = int(round(width * max_dpi / dpi))
+    height = int(round(height * max_dpi / dpi))
+    return img.resize((width, height))
+
+
 def main(paper_width_mm: float, paper_height_mm: float, paper_margin_mm: float,
          photo_width_mm: float, photo_height_mm: float, photo_spacing_mm: float,
          bbox: Tuple[int,int,int,int],
index c9e5acf..0d358c0 100644 (file)
@@ -1,7 +1,8 @@
 import os
 import unittest
 from PIL import Image, ImageDraw
-from gimp_passport import mm_to_pixel, num_tiles, num_tiles_xy, line, make_passport, tile, main
+from gimp_passport import mm_to_pixel, num_tiles, num_tiles_xy, line, make_passport, tile, \
+    downsample_large, main
 
 
 class TestMakePassport(unittest.TestCase):
@@ -50,6 +51,20 @@ class TestMakePassport(unittest.TestCase):
         paper = tile(img, 150, 100, 4, 2.)
         self.assertIsInstance(paper, Image.Image)
 
+    def test_downsample_large(self):
+        dpi = 90
+        source = Image.new('RGB', (mm_to_pixel(35, dpi), mm_to_pixel(45, dpi)), 'lightgray')
+        source.info['dpi'] = (dpi, dpi)
+        dest = downsample_large(source, None)
+        self.assertEqual(source.size, dest.size)
+        dest = downsample_large(source, 2 * dpi)
+        self.assertEqual(source.size, dest.size)
+        dest = downsample_large(source, dpi)
+        self.assertEqual(source.size, dest.size)
+        dest = downsample_large(source, 45)
+        self.assertEqual(int(round(source.width / 2)), dest.width)
+        self.assertEqual(int(round(source.height / 2)), dest.height)
+
     def test_main(self):
         source = 'test_image.jpg'
         dest = 'test_image_result.jpg'