Я пишу сценарий для обработки нескольких изображений в высоком разрешении.Размеры этих изображений варьируются от 1000 до 5000 пикселей.Чтобы подготовить их к веб-загрузке (загрузить), мне нужно уменьшить их.
Меня не интересует реализация уменьшения (открыть изображение, масштабировать, сохранить и т. Д.).Меня интересует расчет новых уменьшенных размеров.
Допустим, у меня есть изображение с размерами 800x2000 пикселей, и я установил 2400x1200 в качестве максимальных размеров.Уменьшенные размеры изображения должны быть 480x1200 пикселей.Размеры изображения не могут превышать максимальные размеры.
Как рассчитать это?
При формировании вопроса в голове я тоже экспериментировал и придумал следующий алгоритм:
def scale(dim, max_dim):
new_dim = {"w" : 0, "h" : 0}
# no change if dim is lower than given max_dim
if dim["w"] <= max_dim["w"] and dim["h"] <= max_dim["h"]:
return dim
ratio = 0
# detect which side overflows
if dim["w"] > max_dim["w"]:
ratio = max_dim["w"] / dim["w"]
else:
ratio = max_dim["h"] / dim["h"]
# scale according to overflowing side
new_dim["w"] = dim["w"] * ratio
new_dim["h"] = dim["h"] * ratio
# now the other side might overflow after scaling
# check if that's true and scale again
if new_dim["h"] > max_dim["h"]:
ratio = max_dim["h"] / dim["h"]
if new_dim["w"] > max_dim["w"]:
ratio = max_dim["w"] / dim["w"]
new_dim["w"] = math.floor(dim["w"] * ratio)
new_dim["h"] = math.floor(dim["h"] * ratio)
return new_dim
Кажется, это дает правильные результаты, хотя я не уверен, что это предпочтительный подход.Например, я делаю две проверки;во-первых, чтобы обнаружить переполнение, а во-вторых, чтобы исправить (возможное) второе переполнение, которое возникает в результате первой шкалы.Возможно, я выполняю избыточные вычисления, поэтому мне также нужен совет по этому поводу.
Контрольные примеры:
max_dim = {"w" : 2400, "h" : 1200}
dim1 = {"w" : 800, "h" : 1000}
dim2 = {"w" : 800, "h" : 2000}
dim3 = {"w" : 800, "h" : 2500}
dim4 = {"w" : 2500, "h" : 800}
dim5 = {"w" : 2500, "h" : 3000}
dim6 = {"w" : 1800, "h" : 1500}
dim7 = {"w" : 2500, "h" : 1000}
dim8 = {"w" : 2500, "h" : 1400}
dim9 = {"w" : 2500, "h" : 2000}
print(scale(dim1, max_dim))
print(scale(dim2, max_dim))
print(scale(dim3, max_dim))
print(scale(dim4, max_dim))
print(scale(dim5, max_dim))
print(scale(dim6, max_dim))
print(scale(dim7, max_dim))
print(scale(dim8, max_dim))
print(scale(dim9, max_dim))
Выходы:
{'w': 800, 'h': 1000}
{'w': 480, 'h': 1200}
{'w': 384, 'h': 1200}
{'w': 2400, 'h': 768}
{'w': 1000, 'h': 1200}
{'w': 1440, 'h': 1200}
{'w': 2400, 'h': 960}
{'w': 2142, 'h': 1200}
{'w': 1500, 'h': 1200}
Эти выводы верны.Ни ширина, ни высота введенных размеров не превышают максимальные размеры.
Кроме того, я знаю, что в Python есть встроенные методы масштабирования изображения (resize
и thumbnail
), но я сделаю дальшеизменения (изменение соотношения сторон, установка прозрачных пикселей и пустых областей на белый и т. д.), поэтому мне нужно выполнить расчет вручную.