Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Адаптация фрагмента изображения (https://javascript.ru/forum/dom-window/80706-adaptaciya-fragmenta-izobrazheniya.html)

headrush 18.07.2020 08:49

Адаптация фрагмента изображения
 
Уже не первый день мучаюсь, все никак не получается решить задачу. Оказалась нетривиальной. Пробовал искать, чтобы не велосипедить - не нашел. Подскажите готовое решение.

Есть изображение, на нём изображен объект. Известны размеры изображения и прямоугольная область объекта (левый верхний угол + ширина и высота). Задача состоит в том, чтобы отобразить объект изображения (минимизируя лишнее) в контейнере с произвольными размерами. Пробовал через канвас и через background на диве, слишком много получается расчетов и я в них тону.

Алгоритм такой: нужно изображение, масштабировать так, чтобы область с объектом на изображении влезла в контейнер/дисплей по центру.

Ну то есть это как:
{
background-size: cover;
background-position: center center;
}
только с применением не ко всему изображению, а к определенной области + без обрезки остатков.

Можно конечно сразу сделать трим изображения, чтобы область была тупо всем изображением и применить этот цсс, но тогда будут появляться пробелы по краям, если контейнер не пропорционален по размерам области.

По сути, если допустим делать через background, то мне нужно вычислить background-size в % (для width или height в зависимости от ситуации) и background-position (смещение по X и Y, чтобы центрировать объект)

Еще ситуация может усложняться тем, что объект на изображении может располагаться не по центру а ближе к какому-то краю, и тогда нужно центрировать так, чтобы не появлялись белые пробелы в контейнере, не смотря на то что сам объект будет не по-центру.

laimas 18.07.2020 08:55

Цитата:

Сообщение от headrush
Пробовал искать, чтобы не велосипедить - не нашел.

Плохо искали, уйма такого в сети - crop image js

headrush 19.07.2020 06:35

Цитата:

Сообщение от laimas (Сообщение 527123)
Плохо искали, уйма такого в сети - crop image js

Ну это не совсем то. Мне же нужно не обрезать картинку... или вернее я не знаю как вычислить область для вырезки.

laimas 19.07.2020 10:02

Цитата:

Сообщение от headrush
я не знаю как вычислить область для вырезки

А это уже интрига. О чем речь, искусственном интеллекте, который уже имеет чувства меры, прекрасного, знаний в различных областях, и который таки определит какое место и какого размера есть лакомый кусочек на изображении?

Alexandroppolus 19.07.2020 11:24

Вложений: 1
Правильно ли я понял суть задачи?
Есть url и размеры картинки, прямоугольник кропа, размеры некоего div.
Надо вычислить background-size и background-position, так чтобы если указать url в background-image, то кроп (зеленый) размещался примерно как на картинке, а по бокам (красное) - та часть изображения, которая за пределами кропа, но тем не менее видна в силу несовпадения пропорций?

headrush 20.07.2020 05:43

Цитата:

Сообщение от Alexandroppolus (Сообщение 527141)
Правильно ли я понял суть задачи?
Есть url и размеры картинки, прямоугольник кропа, размеры некоего div.
Надо вычислить background-size и background-position, так чтобы если указать url в background-image, то кроп (зеленый) размещался примерно как на картинке, а по бокам (красное) - та часть изображения, которая за пределами кропа, но тем не менее видна в силу несовпадения пропорций?

Да. И это (красное) может быть как по-горизонтали, так и по-вертикали. в зависимости от пропорций дива. То есть это кроп, но только не по моим размерам, а больше, чтобы заполнить div.

headrush 20.07.2020 05:48

Цитата:

Сообщение от laimas (Сообщение 527140)
А это уже интрига. О чем речь, искусственном интеллекте, который уже имеет чувства меры, прекрасного, знаний в различных областях, и который таки определит какое место и какого размера есть лакомый кусочек на изображении?

Там ИИ не нужен. Как я писал уже, объект на картинке выделен, просто нужно немного подкорректировать его размеры, чтобы он вошел в контейнер (область отображения). Если делать тупой кроп, то будут появляться белые поля.

laimas 20.07.2020 05:58

headrush,
не вгоняю я тогда, что такое "объект на изображении", который "может располагаться не по центру", но который "нужно центрировать".

headrush 20.07.2020 06:16

Вот пример. Я подогнал цифры руками. А нужно их вычислить исходя из размеров области-объекта на изображении (оно известно заранее), и контейнера в котором отображается картинка.
https://jsfiddle.net/headrush/2a1v9d6x/19/

headrush 20.07.2020 06:19

Цитата:

Сообщение от laimas (Сообщение 527155)
headrush,
не вгоняю я тогда, что такое "объект на изображении", который "может располагаться не по центру", но который "нужно центрировать".

На последнем примере, откройте исходник изображения, там подснежник это объект изображения и он расположен не по-центру. То есть при его масштабировании и подгонке под контейнер, может так получиться что поле слева будет меньше чем поле справа. То есть объект будет не по центру див-контейнера. Но это будет лучше чем если бы он был по-центру и с белыми полями.

laimas 20.07.2020 07:20

Ну так я и говорю, если вы хотите возложить все на css, то вы хотите ИИ, но вы же знаете и размер контейнера, и то что изображение может быть меньше контейнера, и самое главное то, что css не может "дорисовать" картинку.
Зная это, можно сделать только одно - масштабировать изображение, а уж в какую сторону его сдвинуть и на сколько, это только вам определять, ибо css уж точно не понимает, что на картинке есть объект.

headrush 20.07.2020 14:06

Цитата:

Сообщение от laimas (Сообщение 527160)
Ну так я и говорю, если вы хотите возложить все на css, то вы хотите ИИ, но вы же знаете и размер контейнера, и то что изображение может быть меньше контейнера, и самое главное то, что css не может "дорисовать" картинку.
Зная это, можно сделать только одно - масштабировать изображение, а уж в какую сторону его сдвинуть и на сколько, это только вам определять, ибо css уж точно не понимает, что на картинке есть объект.

Нет. Масштабирование и сдвиги делаются с помощью CSS, а все расчеты, циферек, уже в JS. Причем необязательно даже CSS это могут быть и методы canvas. Просто расчетов слишком много, одно от другого зависит, не получается все собрать. Если записать алгоритм действий человека, то будет выглядеть так:

1. Сначала подгоняем масштаб так, чтобы область с объектом входила полностью в див. Скорее всего область с объектом по высоте и ширине не войдет одновременно. То есть сначала допустим полностью войдет по ширине, потом по длине. И по ширине тогда будет открываться все то что находится возле области с объектом. С точки зрения программной, нужно рассчитать такой %, для background-size чтобы ширина и длина масштабируемой области (она масштабируется пропорционально всему изображению) не превышала div.

2. далее мы центруем изображение, чтобы объект был по центру div и если вдруг появились белые поля ту сдвигаем по мере возможности изображение, чтобы их скрыть. Тут как бы тоже все для расчетов есть. Размеры исходного изображения, размеры div, размер и координаты области с объектом и scale коэффициент масштабирования.

laimas 20.07.2020 15:28

Цитата:

Сообщение от headrush
далее мы центруем изображение, чтобы объект был по центру div и если вдруг появились белые поля ту сдвигаем по мере возможности изображение, чтобы их скрыть.

Интересно, кто этим будет заниматься, то есть "давать добро" и что самое интересное знать, что "некий объект" встал на место?

На то оно и масштабируется, чтобы заняло все, а далее либо центрируем, либо от любого из краев отсчет. А чтобы "объект" вошел, значит просто растянуть до заполнения, но это уже с искажениями.

Или я так и не понял чего вы там творите.

headrush 20.07.2020 15:37

Цитата:

Сообщение от laimas (Сообщение 527173)
Интересно, кто этим будет заниматься, то есть "давать добро" и что самое интересное знать, что "некий объект" встал на место?

На то оно и масштабируется, чтобы заняло все, а далее либо центрируем, либо от любого из краев отсчет. А чтобы "объект" вошел, значит просто растянуть до заполнения, но это уже с искажениями.

Или я так и не понял чего вы там творите.

После масштабирования исходного изображения, координаты и размеры области с объектом линейно изменяются. ну то есть тупо умножаются на scale. И далее можно рассчитать например, что от координаты левого, верхнего угла области до края изображения столько-то пикселей, а в диве столько то и тут уже принимать условное решение.

Ну или допустим в одной из попыток реализовать это, я делал так: изначально позиция фона ставится в координаты области (с минусом), в этом случае объект будет своим углом верхним левым уперт в соответствующий угол дива, далее, мы для каждой оси,рассчитываем разницу области с соответсвующей гранью дива, делим ее пополам. тем самым сдвигая на это значение по Х и по У. Но тут нужно еще учесть, что эти сдвиги должны быть ограничены размером самой картинки.

laimas 20.07.2020 16:09

В css есть правила, которые растянут, естественно, что может быть обрезано сверху/снизу или слева/справа в зависимости от размеров. Какой при этом смысл сдвигать, рассчитывать что-то, когда может быть центрирование лучший выбор, а тем более это не определит ни js, ни css.


Часовой пояс GMT +3, время: 20:49.