Я создал алгоритм для этого, на самом деле это вариант задачи NP-Hard Бин , но с бесконечным размером бина.
Вы можете попытаться найти некоторые статьи об этом и попытаться оптимизировать свой алгоритм, но в конце концов он останется грубым способом попробовать каждую возможность и попытаться минимизировать размер получаемого бина.
Если вам не нужно лучшее решение, а только одно решение, вы можете избежать грубого форсирования всех комбинаций. Я создал программу, которая тоже это делала однажды.
Описание:
Images: array of the input images
ResultMap: 2d array of Booleans
FinalImage: large image
- Сортируйте массив изображений так, чтобы наибольшее изображение находилось сверху.
- Рассчитайте общий размер ваших изображений и инициализируйте ResultMap, чтобы его размер в 1,5 раза превышал общий размер ваших изображений (вы можете сделать этот шаг умнее для лучшего использования памяти и производительности). Сделайте ResultMap такого же размера и заполните его ложными значениями.
- Затем добавьте первое изображение слева от FinalImage и установите для всех логических значений в ResultMap значение true от 0,0 до ImageHeight, ImageWidth.
ResultMap используется для быстрой проверки, можете ли вы вписать изображение в текущий FinalImage. Вы можете оптимизировать его для использования int32 и использовать каждый бит для одного пикселя. Это уменьшит память и увеличит производительность, потому что вы можете проверять 32-битные данные одновременно (используя маску). Но это станет более сложным, потому что вам придется подумать о маске, которую вы должны будете сделать для краев вашего изображения.
Теперь я опишу реальный цикл «алгоритма».
- Для каждого изображения в массиве попытайтесь найти место, где оно будет подходить. Вы можете написать цикл, который будет выглядеть через массив ResultMap и искать ложное значение, а затем начать проверять, остается ли оно ложным в обоих направлениях для размера изображения, которое нужно разместить.
- Если вы найдете место, скопируйте изображение в FinalImage и обновите правильные логические значения в ResultMap
- Если вы найдете место, достаточно увеличить размер FinalImage (посмотрите на края, где требуется минимальное количество дополнительного пространства), а также синхронизируйте его с ResultMap
- GOTO 1:)
Это не оптимально, но может решить проблему достаточно оптимальным способом (особенно, если в конце есть несколько небольших изображений для заполнения пробелов).