Я использую PIL для проекта uni, и у нас есть одна задача, когда мы должны темнее или ярче изображения без использования каких-либо функций PIL для этого. Функция принимает исходное имя файла, действие ( "светить" или "затемнить" ) и степень (в процентах - от интервала между 0 и 100). Вот что я до сих пор придумал:
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')
Когда я запускаю это, новое изображение не изменяется от оригинала (кроме некоторых новых артефактов jpg). Я пробовал brightness_multiplier
с явным значением (1.1 для lighten и 0.9 для darken), и он работал, поэтому я понятия не имею, почему он не работает, когда у меня есть значение из аргумента extent
.
Если кто-то может пролить некоторый свет, мы будем очень благодарны!
Это проблема целочисленного деления в выражении (extent/100)
. Чтобы исправить это, вы можете:
extent/100.0
Удобно, если термин является литералом.
float(extent)/a_hundred
Если ни один из слов не является литералом.
/
floating- деление точкиfrom __future__ import division
Вставьте это в начале исходного файла, как и все инструкции __future__
.
python -Qnew
Если используется python2, в противном случае
Во всех случаях //
остается целочисленным делением.
100
в(extent/100)
на поплавок, и это сработало! Я пока не могу ответить на свой вопрос, поэтому ставлю его здесьnew_pixel
. Рассмотримnew_pixel= [max(min(channel, 255), 0) for channel in new_pixel]
. Вероятно, более эффективным способом «облегчения» было бы уменьшение разницы между значением канала и 255, а не умножение самого значения канала, поскольку оно будет насыщаться быстрее. Еще лучше было бы преобразовать в цветовое пространство HSL, изменить значение Lightness, а затем преобразовать обратно. Бонусные баллы за размышления о гамме.