Это дополнительный вопрос к Обрезка и изменение размера изображения вокруг пользовательской точки фокусировки , где я получил полезные ответы о том, какие части команд использовать для imagemagick для достижения того, чего я хочу: Масштабировать изображение вниз, но вместо того, чтобы использовать предопределенную гравитацию (например, «Центр» или «Север»), я хочу использовать пользовательскую точку фокусировки на изображении, которая должна быть новым центром масштабированного изображения, чтобы обеспечить «важную точку» изображение всегда видно при кадрировании / изменении его размера.
Это работает довольно хорошо, за исключением вычисления фактического размера. Я предполагаю, что что-то не так в моей математике, потому что в результате на выходе отсутствуют некоторые части, которые могли бы быть видны, если изображение уменьшено больше, чем я рассчитываю. Я не могу найти ошибку, которую я делаю, возможно, кто-то может дать мне подсказку в правильном направлении.
То, что я сейчас делаю:
# Example image from https://unsplash.com/photos/p-I9wV811qk
source_image = 'input.jpg'
source_image_size = [3008, 2000]
target_image_size = [295, 195]
# Focus point position, in percentages.
focus_point = {
x: 46.7087766,
y: 24.2
}
# Calculate the focus point in px on the source image.
source_focus_point = [
source_image_size[0] / 100.0 * focus_point[:x],
source_image_size[1] / 100.0 * focus_point[:y]
]
# Calculate the distances to the focus point in percentage,
# from all four image sides, and use the smalles value.
smallest_percentage_distance = [
focus_point[:x],
(100.0 - focus_point[:x]),
focus_point[:y],
(100.0 - focus_point[:y])
].min
# Scale image to reach smallest percentage distance.
scale_factor = smallest_percentage_distance / 100.0
# Calculate the focus point on the target image for the transformation,
# which will be on the center of the new image.
target_focus_point = [
target_image_size[0].to_f / 2.0,
target_image_size[1].to_f / 2.0
]
# Define how many degrees the image should be rotated.
rotation_degrees = 0
command = [
'convert',
source_image,
"-set option:distort:viewport #{target_image_size.join('x')}",
"-distort SRT '#{source_focus_point.join(',')} #{scale_factor} #{rotation_degrees} #{target_focus_point.join(',')}'",
'output2.jpg'
].join ' '
В результате получается следующая команда:
convert input.jpg -set option:distort:viewport 295x195 -distort SRT '1405.000000128,484.0 0.242 0 147.5,97.5' output.jpg
В моем понимании, второй аргумент SRT ImageMagick искажает (здесь, scale_factor
) определяет, насколько в%, изображение должно быть уменьшено. Моя идея состояла в том, чтобы рассчитать расстояния всех сторон до точки фокусировки, взять наименьшее расстояние, преобразовать его в подходящий аргумент и использовать его для определения величины масштабирования.
Цель - масштабировать изображение как можно больше, чтобы гарантировать, что выходное изображение не обрезается слишком сильно, чтобы показать как можно больше исходного изображения. Мой вывод сейчас обрезается слишком сильно.
Я попытался визуализировать его для лучшего понимания:
Исходное изображение можно найти здесь: https://unsplash.com/photos/p-I9wV811qk
Что я делаю не так? Как рассчитать значение для правильного масштабирования изображения, чтобы максимально увеличить видимое изображение?
Редактировать 1
В конце несколько вариантов изображение будет сгенерировано, имея другой формат rat ios. Рядом с указанным 295x195, другой будет 1440x560; Особенно в этом случае простая «обрезка под действием силы тяжести», скорее всего, обрезает среднюю или верхнюю часть изображения, таким образом, точка фокусировки гарантирует постоянную видимость жизненно важной части.
Отредактируйте 2 в ответ от fmw42
Код работает так далеко, что делает изменение размера и обрезку без использования SRT. К сожалению, результат гораздо дальше по сравнению с результатом, который у меня есть в настоящее время (но, возможно, я что-то сделал не так при адаптации скрипта).
То, что я сделал, было
- с использованием изображение из моего вопроса
- с заменой
px
и py
на значения точек фокусировки из моего вопроса - с сохранением вычисления
scale
, но с использованием wd=295
и ht=195
, как это желаемый целевой урожай
Полученный результат выглядит следующим образом: