Как бы я программно обрезал изображение до непрямоугольной формы?


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

Предположим, например, что я хочу сфотографировать флаг Айдахо и обрезать его до формы штата Айдахо. Я представляю, что сделал бы что-то вроде этого:

  1. Создайте изображение с непрозрачными пикселями для формы Айдахо, прозрачные пиксели повсюду
  2. Прочитайте и сохраните какое-либо растровое изображение для этого изображения штата Айдахо
  3. Для каждого непрозрачного местоположения пикселя на изображении штата Айдахо скопируйте соответствующий пиксель с изображения флага штата Айдахо и поместите его на пустой прозрачный холст

Шаг 1, очевидно, будет выполнен вручную, но остальное будет выполнено программно. Я думаю, что в целом у меня есть правильная идея, но я не знаю, как бы я подошел к конкретике. Может ли кто-нибудь указать мне на в правильном направлении?

Что касается технологии реализации, я парень с PHP, поэтому использование gdLibrary или чего-то, что работает с PHP, вероятно, было бы лучшим способом для меня.

Author: devios1, 2010-01-22

3 answers

Я бы подумал, что это было бы намного проще сделать, просто добавив битовую маску или альфа-канал. В этом случае вы могли бы использовать изображение негативной маски вашей фигуры, а затем просто применить его к обычному изображению в качестве маски, а затем сохранить в прозрачном формате. На самом деле я никогда не делал этого с помощью GD или ImageMagick, но я бы подумал, что это доступно, как предлагает Джерри.

На самом деле вот сообщение в блоге с аналогичным вопросом SO, которое может помочь: http://about.phalacee.com/geek/creating-mask-layers-using-php-gd

 2
Author: prodigitalson, 2010-01-22 20:52:02

Обычным способом сделать что-то подобное было бы использовать белый (все 1) и черный (все 0) для вашего контура вместо прозрачного и непрозрачного. Затем вы И это изображение с изображением, которое вы пытаетесь обрезать. В результате получается 0, где контурное изображение имело 0, а другое изображение, где контур имел 1.

Вам также может потребоваться инвертировать изображение контура и перевернутую версию с фоновым изображением. Затем вы ИЛИ фоновое изображение с изображением переднего плана, чтобы создайте композицию изображения переднего плана в форме Айдахо (для вашего примера) и фонового изображения везде.

В зависимости от возможностей используемой вами библиотеки, есть большая вероятность, что такая возможность доступна напрямую. Просто, например, Windows имеет эту возможность в функции MaskBlt.

 2
Author: Jerry Coffin, 2010-01-22 20:48:19

В php использование ImageMagick, вероятно, ваш лучший выбор:

$source = IMagick("sourcefile");
$mask = IMagick("maskfile");
$mask->adaptiveResizeImage($source->getImageWidth(), $source->getImageHeight(), true);
$source->compositeImage($mask, imagick::COMPOSITE_MULTIPLY, 0, 0);
$source->writeImage("newfile");
$source->clear();
$source->destroy();

Исходный файл должен быть исходным изображением, как вам нравится, файл маски должен быть файлом маски, в котором альфа-канал установлен правильно для нужной вам формы.

 1
Author: wich, 2010-01-22 21:06:46