I’m using PIL for a uni project and we have one task where we have to darken or brighten an image without using any of PIL’s functions to do so. The function takes the original filename, the action (‘lighten’ or ‘darken’) and the extent (in percent – an int between 0 and 100). Here’s what I’ve come up with so far:
from PIL import Image
def change_brightness(filename, action, extent):
"""
This function either increases or decreases the brightness of an image
by altering each pixel in each band
"""
#load the original image into a list
original_image = Image.open(filename, 'r')
pixels = original_image.getdata()
#initialise the new image
new_image = Image.new('RGB', original_image.size)
new_image_list = []
brightness_multiplier = 1.0
if action == 'lighten':
brightness_multiplier += (extent/100)
else:
brightness_multiplier -= (extent/100)
#for each pixel, append the brightened or darkened version to the new image list
for pixel in pixels:
new_pixel = (int(pixel[0] * brightness_multiplier),
int(pixel[1] * brightness_multiplier),
int(pixel[2] * brightness_multiplier))
#check the new pixel values are within rgb range
for pixel in new_pixel:
if pixel > 255:
pixel = 255
elif pixel < 0:
pixel = 0
new_image_list.append(new_pixel)
#save the new image
new_image.putdata(new_image_list)
new_image.save('colour_brightness.jpg')
When I run this, the new image is not modified from the original (save from some new jpg artefacts). I tried brightness_multiplier with an explicit value (1.1 for lighten, and 0.9 for darken) and it worked, so I have no idea why it isn’t working when I have it taking the value from the extent argument.
If anyone could shed some light it would be greatly appreciated!
It’s an issue of integer division in the
(extent/100)expression. To rectify this, you can:use a floating point literal
Handy if a term is a literal.
convert either the numerator or the denominator into float
If no term is a literal.
make sure that
/is floating-point divisionInsert that at the beginning of your source file, like all
__future__statements.invoke python with -Qnew
If using python2, otherwise
use python3 🙂
In all cases,
//remains integer division.