Change command line program to accept face dimensions as arguments, not transparency.
authorPhilipp Spitzer <philipp@spitzer.priv.at>
Fri, 21 Jun 2019 21:42:07 +0000 (23:42 +0200)
committerPhilipp Spitzer <philipp@spitzer.priv.at>
Fri, 21 Jun 2019 21:42:07 +0000 (23:42 +0200)
gimp_passport.py
test_gimp_passport.py

index bbdd431..84a6b96 100644 (file)
@@ -12,17 +12,10 @@ def mm_to_pixel(mm: float, dpi: Integral) -> int:
     return int(round(mm / MM_PER_INCH * dpi))
 
 
-def make_passport(img_rgba: Image, fpr: float, width_mm: float, height_mm: float) -> Image:
+def make_passport(img: Image, bbox_head: Tuple[int,int,int,int], fpr: float, width_mm: float, height_mm: float) -> Image:
     """
     :param fpr: face to picture ratio, e.g. 2/3
     """
-    # get bounding box of head
-    bands = img_rgba.getbands()
-    if 'A' not in bands:
-        raise ValueError('Image has no transparency (needed for marking the head).')
-    alpha = img_rgba.getdata(bands.index('A'))
-    bbox_head = alpha.getbbox()  # bounding box of head
-
     # get bounding box of passport image ("pic")
     left, top, right, bottom = bbox_head
     height = bottom - top
@@ -36,7 +29,6 @@ def make_passport(img_rgba: Image, fpr: float, width_mm: float, height_mm: float
     bbox_pic = pic_left, pic_top, pic_right, pic_bottom
 
     # cut image
-    img = img_rgba.convert('RGB')  # drop alpha channel
     pic = img.crop(bbox_pic)
     dpi = int(round(pic_height / (height_mm / MM_PER_INCH)))
     pic.info['dpi'] = (dpi, dpi)
@@ -80,9 +72,9 @@ def line(img: Image, pos: int, axis: int) -> Image:
     draw = ImageDraw.ImageDraw(img)
     color = 'black'
     if axis == 0:
-        draw.line(((0, pos), (img.width, pos)), color=color)
+        draw.line(((0, pos), (img.width, pos)), fill=color)
     else:
-        draw.line(((pos, 0), (pos, img.height)), color=color)
+        draw.line(((pos, 0), (pos, img.height)), fill=color)
 
 
 def make_cut_lines(img: Image, count_x: int, count_y: int, width: int, margin: int, spacing: int, 
@@ -156,9 +148,10 @@ def tile(img: Image, paper_width_mm: float, paper_height_mm: float, margin_mm: f
 
 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],
          source_image: str, dest_image: str):
     img = Image.open(source_image)
-    photo = make_passport(img, 0.75, photo_width_mm, photo_height_mm)
+    photo = make_passport(img, bbox, 0.75, photo_width_mm, photo_height_mm)
     paper = tile(photo, paper_width_mm, paper_height_mm, paper_margin_mm, photo_spacing_mm)
     paper.save(dest_image, dpi=paper.info['dpi'])
 
@@ -172,8 +165,15 @@ if __name__ == '__main__':
     parser.add_argument('--photo-width', type=float, metavar='mm', default=35., help='passport photo width in mm (default: 35)')
     parser.add_argument('--photo-height', type=float, metavar='mm', default=45., help='passport photo height in mm (default: 45)')
     parser.add_argument('--photo-spacing', type=float, metavar='mm', default=0., help='space between passport photos in mm (default: 0)')
+    parser.add_argument('left', type=int, help='number of pixels from left image border to left face border (inclusive)')
+    parser.add_argument('top', type=int, help='number of pixels from top image border to top face border (inclusive)')
+    parser.add_argument('right', type=int, help='number of pixels from left image border to right face border (exclusive)')
+    parser.add_argument('bottom', type=int, help='number of pixels from top image border to bottom face border (exclusive)')
     parser.add_argument('source', help='sourse image')
     parser.add_argument('dest', help='destination image')
     args = parser.parse_args()
     main(args.paper_width, args.paper_height, args.paper_margin, args.photo_width, args.photo_height,
-         args.photo_spacing, args.source, args.dest)
+         args.photo_spacing,
+         (args.left, args.top, args.right, args.bottom),
+         args.source, args.dest)
+
index 582c308..3c79c1f 100644 (file)
@@ -13,11 +13,11 @@ class TestMakePassport(unittest.TestCase):
 
     def test_make_passport(self):
         dpi = 90
-        img = Image.new('RGBA', (mm_to_pixel(60, dpi), mm_to_pixel(80, dpi)), '#bbbbbb00')
+        img = Image.new('RGB', (mm_to_pixel(60, dpi), mm_to_pixel(80, dpi)), '#bbbbbb')
         img.info['dpi'] = (dpi, dpi)
         draw = ImageDraw.ImageDraw(img)
         draw.rectangle((50, 60, 150, 170), fill='#00bbbbff')
-        pic = make_passport(img, 0.75, 35., 45.)
+        pic = make_passport(img, (50, 60, 150, 170), 0.75, 35., 45.)
         self.assertIsInstance(pic, Image.Image)
 
     def test_num_tiles(self):
@@ -51,9 +51,9 @@ class TestMakePassport(unittest.TestCase):
         self.assertIsInstance(paper, Image.Image)
 
     def test_main(self):
-        source = 'test_image.png'
-        dest = 'test_image_result.png'
+        source = 'test_image.jpg'
+        dest = 'test_image_result.jpg'
         if os.path.exists(dest):
             os.remove(dest)
-        main(35., 45., 4., 100., 150., 0., source, dest)
+        main(35., 45., 4., 100., 150., 0., (1108, 280, 2180, 1620), source, dest)
         self.assertTrue(os.path.exists(dest))