Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fill_area parameter / --fill-area CLI option #9

Merged
merged 2 commits into from
Apr 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,6 @@ Installation

pip install pictureshow

Third-party dependencies:

- `Pillow <https://pypi.org/project/Pillow/>`__
- `reportlab <https://pypi.org/project/reportlab/>`__


Usage
=====
Expand All @@ -38,6 +33,8 @@ As a command line tool

options:
-h, --help show this help message and exit
-a, --fill-area fill drawing area with picture, ignoring the picture's
aspect ratio
-f, --force-overwrite
save to output filename even if file exists
-L, --landscape set landscape orientation of page; default is portrait
Expand Down Expand Up @@ -119,6 +116,7 @@ correspond to the above shown command line options:
margin=72,
layout=(1, 1),
stretch_small=False,
fill_area=False,
force_overwrite=False
)

Expand Down Expand Up @@ -151,6 +149,7 @@ default values correspond to the above shown command line options:
margin=72,
layout=(1, 1),
stretch_small=False,
fill_area=False,
force_overwrite=False
)

Expand Down
4 changes: 4 additions & 0 deletions pictureshow/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
def get_args(parser):
parser.add_argument('pictures', nargs='+', metavar='PICTURE',
help='one or more picture paths or URLs')
parser.add_argument('-a', '--fill-area', action='store_true',
help="fill drawing area with picture, ignoring the picture's"
" aspect ratio")
parser.add_argument('-f', '--force-overwrite', action='store_true',
help='save to output filename even if file exists')
parser.add_argument('-L', '--landscape', action='store_true',
Expand Down Expand Up @@ -92,6 +95,7 @@ def main():
margin=args.margin,
layout=args.layout,
stretch_small=args.stretch_small,
fill_area=args.fill_area,
force_overwrite=args.force_overwrite
)
except Exception as err:
Expand Down
21 changes: 13 additions & 8 deletions pictureshow/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ def __init__(self, *pic_files):
self.errors = []

def save_pdf(self, output_file, page_size='A4', landscape=False, margin=72,
layout=(1, 1), stretch_small=False, force_overwrite=False):
layout=(1, 1), stretch_small=False, fill_area=False,
force_overwrite=False):
"""Save pictures stored in `self.pic_files` to a PDF document.

Return a named tuple of three values:
Expand All @@ -43,10 +44,11 @@ def save_pdf(self, output_file, page_size='A4', landscape=False, margin=72,
layout = self._validate_layout(layout)

return self._save_pdf(
output_file, page_size, margin, layout, stretch_small
output_file, page_size, margin, layout, stretch_small, fill_area
)

def _save_pdf(self, output_file, page_size, margin, layout, stretch_small):
def _save_pdf(self, output_file, page_size, margin, layout, stretch_small,
fill_area):
pdf_canvas = Canvas(output_file, pagesize=page_size)
valid_pics = self._valid_pictures()
num_ok = 0
Expand All @@ -66,7 +68,8 @@ def _save_pdf(self, output_file, page_size, margin, layout, stretch_small):
x, y, pic_width, pic_height = self._position_and_size(
picture.getSize(),
area[2:], # short for (area.width, area.height)
stretch_small
stretch_small,
fill_area
)
pdf_canvas.drawImage(
picture, area.x + x, area.y + y, pic_width, pic_height,
Expand Down Expand Up @@ -138,11 +141,13 @@ def _valid_pictures(self):
yield picture

@staticmethod
def _position_and_size(pic_size, area_size, stretch_small):
def _position_and_size(pic_size, area_size, stretch_small, fill_area):
"""Calculate position and size of the picture in the area."""
pic_width, pic_height = pic_size
area_width, area_height = area_size
if fill_area:
return 0, 0, area_width, area_height

pic_width, pic_height = pic_size
pic_is_big = pic_width > area_width or pic_height > area_height
pic_is_wide = pic_width / pic_height > area_width / area_height

Expand Down Expand Up @@ -183,7 +188,7 @@ def _areas(layout, page_size, margin):


def pictures_to_pdf(*pic_files, output_file, page_size='A4', landscape=False,
margin=72, layout=(1, 1), stretch_small=False,
margin=72, layout=(1, 1), stretch_small=False, fill_area=False,
force_overwrite=False):
"""Save one or more pictures to a PDF document.

Expand All @@ -195,6 +200,6 @@ def pictures_to_pdf(*pic_files, output_file, page_size='A4', landscape=False,
pic_show = PictureShow(*pic_files)

return pic_show.save_pdf(
output_file, page_size, landscape, margin, layout, stretch_small,
output_file, page_size, landscape, margin, layout, stretch_small, fill_area,
force_overwrite
)
31 changes: 25 additions & 6 deletions tests/unit_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
A4 = A4_WIDTH, A4_LENGTH
A4_LANDSCAPE = A4_LENGTH, A4_WIDTH

DEFAULTS = dict(page_size=A4, margin=72, layout=(1, 1), stretch_small=False)
DEFAULTS = dict(
page_size=A4, margin=72, layout=(1, 1), stretch_small=False, fill_area=False
)


def picture():
Expand Down Expand Up @@ -377,7 +379,7 @@ class TestPositionAndSize:
def test_big_wide_picture_fills_area_x(self, pic_size, area_size):
original_aspect = pic_size[0] / pic_size[1]
x, y, new_width, new_height = PictureShow()._position_and_size(
pic_size, area_size, stretch_small=False
pic_size, area_size, False, False
)
assert x == 0
assert new_width == area_size[0]
Expand All @@ -393,7 +395,7 @@ def test_big_wide_picture_fills_area_x(self, pic_size, area_size):
def test_big_tall_picture_fills_area_y(self, pic_size, area_size):
original_aspect = pic_size[0] / pic_size[1]
x, y, new_width, new_height = PictureShow()._position_and_size(
pic_size, area_size, stretch_small=False
pic_size, area_size, False, False
)
assert y == 0
assert new_height == area_size[1]
Expand All @@ -402,7 +404,7 @@ def test_big_tall_picture_fills_area_y(self, pic_size, area_size):
def test_small_picture_not_resized(self):
pic_size = (320, 200)
x, y, new_width, new_height = PictureShow()._position_and_size(
pic_size, A4_PORTRAIT_MARGIN_72, stretch_small=False
pic_size, A4_PORTRAIT_MARGIN_72, False, False
)
assert (new_width, new_height) == pic_size

Expand All @@ -416,7 +418,7 @@ def test_small_picture_not_resized(self):
def test_small_wide_picture_stretch_small(self, pic_size, area_size):
original_aspect = pic_size[0] / pic_size[1]
x, y, new_width, new_height = PictureShow()._position_and_size(
pic_size, area_size, stretch_small=True
pic_size, area_size, stretch_small=True, fill_area=False
)
assert x == 0
assert new_width == area_size[0]
Expand All @@ -432,12 +434,29 @@ def test_small_wide_picture_stretch_small(self, pic_size, area_size):
def test_small_tall_picture_stretch_small(self, pic_size, area_size):
original_aspect = pic_size[0] / pic_size[1]
x, y, new_width, new_height = PictureShow()._position_and_size(
pic_size, area_size, stretch_small=True
pic_size, area_size, stretch_small=True, fill_area=False
)
assert y == 0
assert new_height == area_size[1]
assert new_width / new_height == pytest.approx(original_aspect)

@pytest.mark.parametrize(
'pic_size, area_size',
(
pytest.param((800, 387), A4_PORTRAIT_MARGIN_72, id='big wide picture'),
pytest.param((400, 3260), A4_PORTRAIT_MARGIN_72, id='big tall picture'),
pytest.param((320, 200), A4_PORTRAIT_MARGIN_72, id='small picture'),
)
)
def test_fill_area(self, pic_size, area_size):
x, y, new_width, new_height = PictureShow()._position_and_size(
pic_size, area_size, stretch_small=False, fill_area=True
)
assert x == 0
assert y == 0
assert new_width == area_size[0]
assert new_height == area_size[1]


class TestAreas:
"""Test core.PictureShow._areas"""
Expand Down