HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Comparing image resolutions to ratios

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
resolutionsimageratioscomparing

Problem

I made this Python 3.6 program that generates a list of images that fail to compare against a given ratio. Each image has a resolution and with a bit of math, the program is supposed to calculate the width using the ratio and compare it with the actual width. If the calculated width falls from the range of (width-1, width+1), the image is outputted and considered "not respecting the ratio".

Important: The program uses the PIL library to get the resolutions. I used pip --user and it seems to work perfectly.

For example, an image with the resolution of 1920x1080 is in a directory. The program, imageres.py, takes the resolution, and uses this formula:

$$\text{cal_width} = \frac{\text{width_ratio} * \text{image_height}}{\text{height_ratio}}$$

If the ratio (default, actually) is 16:9, the formula turns out to be this:

$$\text{cal_width} = \frac{16 * 1080}{9}$$

Thus, the answer should be:

$$\text{cal_width} = 1920$$

The program does the above and compares the final result to the image's actual resolution. Because both of them are equal, the image is not outputted and moves on to the next one.

Do you have any suggestions or methods I can use to make my code more robust? I noticed PyLint kept telling me on structure, so if anyone has any suggestion to make the code more readable would be awesome.

My biggest concern, though, is the mathematics and floating-point numbers behind the program. If you understand what I'm trying to do, I would like to hear your opinions! I have some reservations about this, as it seems more of a hack than an actual solution.

imageres.py

(I hope I was able to keep the PyLint stuff on.)

```
"""
imgres.py

this is a simple python image resoultion ratio checker. quite loaded
sentence, but basically it gets an image's width and height and calculates
the width using the hardcoded default ratio of 16:9, which is what some
monitors have (like 1920x1080 is a equal ratio to 16:9)

so far it only spits out the images

Solution

Here are some of the notes about the code you've posted:

  • I think pillow project is a much more active player than PIL, consider switching. There is also a highly-optimized Pillow-SIMD that can bring dramatically better performance (some benchmarks).



  • variable naming - PARSER, ARGS, ONLYFILES are not constants (well, there are no constants in Python, it's just that it is recommended to name things that don't change in an upper case, PEP8 about constants) and should be defined in a lower case



-
you don't need to define ONLY_FILES list and then iterate over it, you can use a single loop and, moreover, use a glob pattern with glob.iglob():

import glob 

for filename in glob.iglob(args.directory + "/*.{jpg,png}", recursive=True):


-
when opening the image files, use the with context manager:

with Image.open(filename) as img:


-
when you check the calculated_width to be in a specified range, use comparison operators instead of creating a extra "range" (please check the following on the off-by-one errors):

if not(img_width - 1 <= calculated_width <= img_width):


-
you can have a custom argparse directory type

  • I don't see much sense in keeping a filename inside a "docstring" - the filename can change and you would easily forget to update it in the docstring



  • the "requires the PIL (Python Image Library) locally via pip or else where" should be better handled by requirements.txt file accompanied by a "README" file (typically README.md or README.rst) with installation, usage and license instructions



  • it might probably be a good idea to configure the --help of your CLI program, argparse would by default generate one, but adding more to the usage instructions and potential problems may be helpful



  • the commented "debug" section of the code, should be replaced by a proper logging



  • organize imports as per PEP8 recommendations

Code Snippets

import glob 

for filename in glob.iglob(args.directory + "/*.{jpg,png}", recursive=True):
with Image.open(filename) as img:
if not(img_width - 1 <= calculated_width <= img_width):

Context

StackExchange Code Review Q#155306, answer score: 5

Revisions (0)

No revisions yet.