patternpythonMinor
Comparing image resolutions to ratios
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
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
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:
-
you don't need to define
-
when opening the image files, use the
-
when you check the
-
you can have a custom
- I think
pillowproject is a much more active player thanPIL, consider switching. There is also a highly-optimizedPillow-SIMDthat can bring dramatically better performance (some benchmarks).
- variable naming -
PARSER,ARGS,ONLYFILESare 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,PEP8about 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.txtfile accompanied by a "README" file (typicallyREADME.mdorREADME.rst) with installation, usage and license instructions
- it might probably be a good idea to configure the
--helpof your CLI program,argparsewould 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
PEP8recommendations
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.