Объедините несколько изображений в одно большое изображение

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

edit: добавлено ограничение на изменение размера


person Linor    schedule 24.09.2008    source источник
comment
Привет, Линор! так что ты сделал наконец? это поможет...   -  person Lazer    schedule 30.09.2009


Ответы (6)


Возможно, вы ищете что-то вроде этого: Автоматический макет журнала.

person Grey Panther    schedule 24.09.2008
comment
Проблема с этим решением заключается в том, что оно работает только для нескольких изображений и изменяет размер изображений, чтобы они соответствовали. - person Linor; 24.09.2008

По-видимому, это называется «проблемой упаковки», которая часто используется в программировании игр. Для тех, кто заинтересован, вот несколько предлагаемых реализаций:

Упаковка карт освещения, Прямоугольная упаковка и Размещение прямоугольника

person Linor    schedule 24.09.2008

Я создал для них алгоритм, на самом деле это вариант NP-Hard < href="http://en.wikipedia.org/wiki/Bin_packing_problem" rel="nofollow noreferrer">упаковка контейнера, но с бесконечным размером контейнера.

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

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

Описание:

Images: array of the input images
ResultMap: 2d array of Booleans
FinalImage: large image
  1. Отсортируйте массив изображений так, чтобы самое большое изображение было вверху.
  2. Вычислите общий размер ваших изображений и инициализируйте ResultMap так, чтобы его размер в 1,5 раза превышал общий размер ваших изображений (вы можете сделать этот шаг умнее для лучшего использования памяти и производительности). Сделайте ResultMap того же размера и заполните его значениями False.
  3. Затем добавьте первое изображение слева от вашего FinalImage и установите все логические значения в ResultMap в значение true от 0,0 до ImageHeight, ImageWidth.

ResultMap используется для быстрой проверки того, можете ли вы разместить изображение на текущем FinalImage. Вы можете оптимизировать его для использования int32 и использовать каждый бит для одного пикселя. Это уменьшит память и повысит производительность, потому что вы можете проверять 32 бита сразу (используя маску). Но это станет более сложным, потому что вам придется подумать о маске, которую вам нужно будет сделать для краев вашего изображения.

Теперь я опишу реальный цикл «алгоритма».

  1. For each image in the array try to find a place were it would fit. You could write a loop which would look trough the ResultMap array and look for a false value and than start to see if it remains false in both directions for the size of the image to place.
    • If you find a place, copy the image to the FinalImage and update the correct booleans in ResultMap
    • Если вы можете найти место, увеличьте размер FinalImage достаточно (поэтому посмотрите на края, где требуется минимальное количество дополнительного пространства), а также синхронизируйте его с ResultMap.
  2. ПЕРЕЙТИ 1 :)

Это не оптимально, но может решить проблему достаточно оптимальным способом (особенно если в конце есть несколько изображений меньшего размера, чтобы заполнить пробелы).

person Davy Landman    schedule 24.09.2008

Оптимальная упаковка сложна, но вам могут быть доступны упрощения в зависимости от деталей вашей проблемной области. Несколько идей:

  1. Если вы можете разбить свои растровые изображения на плитки одинакового размера, то упаковка становится тривиальной. Затем, по требованию, вы собирали растровые изображения из плиток.

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

  3. Используйте генетический алгоритм. Начните с нескольких случайно выбранных макетов. Оценка их на основе того, насколько плотно они упакованы. Смешивайте решения, получившие наибольшее количество баллов, и повторяйте, пока не получите приемлемый балл.

person Adrian McCarthy    schedule 10.05.2009


Непрограммным способом вы можете использовать функцию MS Paint «Вставить из», т. Е. Вставить файл (JPEG) в область изображения mspaint. Используя это, вы можете упорядочить отдельные изображения и создать окончательное большое изображение и сохранить его в формате JPEG/GIF/Raw-BMP.

-AD.

person goldenmean    schedule 24.09.2008