Как я могу обрезать только левую и правую часть изображения, используя Imagemagick в PHP?
Я пытаюсь обрезать переменное количество пробелов в изображении только левой и правой стороной, используя ImageMagick и PHP. Кто-нибудь знает, как это сделать (возможно, используя что-то другое, кроме imagemagick?)?
Вот пример.
У меня есть эти два изображения:
![Test]()
![Test Again]()
Каждый из них имеет переменное количество текста, которое динамически создается в изображении с фиксированной шириной.
Что мне нужно сделать, это обрезать фон с правой и левой стороны, чтобы изображения выходили следующим образом:
![TestResult]()
![Test Again Result]()
Если ImageMagick не может этого сделать, я готов использовать что-то еще, но мне нужна помощь в том, как именно потому, что я не очень программист. Спасибо!
Вот мой текущий код, который обрезает все стороны изображения:
<?php
/* Create the object and read the image in */
$i = '3';
$im = new Imagick("test".$i.".png");
/* Trim the image. */
$im->trimImage(0);
/* Ouput the image */
//header("Content-Type: image/" . $im->getImageFormat());
//echo $im;
/*** Write the trimmed image to disk ***/
$im->writeImage(dirname(__FILE__) . '/test'.$i.'.png');
/*Display Image*/
echo $img = "<img src=\"test".$i.".png\">";
?>
Ответы
Ответ 1
Из того, что я вижу в документах ImageMagick на обрезке и границах, это не представляется возможным.
вы не можете указать ребро для "интеллектуального" обрезки (в командной строке называемое -trim
), и для всех методов обрезки, которые принимают аргумент геометрии, требуется фиксированное число для обрезки.
Единственная идея, которая приходит на ум, - получить цвет бритой области в отдельном вызове, запустить trimImage
и добавить потерянные области обратно с помощью -border
.
Изменить: Пособие по IM предлагает нечто подобное. Проверьте Обрезка только одной стороны изображения. Я не знаком с расширением IM PHP, чтобы перевести код на PHP-вызовы, но он должен быть наполовину -простой.
Ответ 2
Я думаю, что вы на правильном пути с оператором ImageMagick
-trim
1) но трюк заключался бы в том, чтобы заставить его сказать вам, что бы он сделал, не выполняя его, а затем измените это, чтобы делать то, что вы действительно хотите...
Итак, чтобы получить триммер ImageMagick
для вашего первого изображения, вы выполните следующее:
convert -fuzz 10% image.jpg -format "%@" info:
60x29+21+31
Это прямоугольник размером 60x29 пикселей, смещение 21 поперек и 31 вниз от верхнего левого угла. Теперь мы хотим получить эти значения в переменные bash
, поэтому я устанавливаю IFS (разделитель полей ввода) для разделения полей на пробелы, x
, а также +
знаков:
#!/bin/bash
IFS=" x+" read a b c d < <(convert -fuzz 10% image.jpg -format "%@" info:)
echo $a $b $c $d
60 29 21 31
Теперь я могу игнорировать 29
и 31
, потому что нас интересует только обрезка ширины и обрезается вот так:
convert image.jpg -crop "${a}x+${c}+0" out.jpg
Итак, для ваших 2 изображений я получаю следующее:
![enter image description here]()
![enter image description here]()
и полная процедура такова:
#!/bin/bash
IFS=" x+" read a b c d < <(convert -fuzz 10% image.jpg -format "%@" info:)
convert image.jpg -crop "${a}x+${c}+0" out.jpg
Примечания
1) -format %@
является просто сокращением для оператора -trim
, который был бы в полном объеме
convert image.jpg -trim info:
image.jpg JPEG 72x40 200x100+16+24 8-bit sRGB 0.000u 0:00.000
Ответ 3
Библиотека на основе GD WideImage имеет нечто похожее. Он называется autoCrop
, по умолчанию он работает на всех четырех сторонах.
Однако вы можете просто добавить еще один параметр и на нем использовать только верхний/нижний или левый/правый.
код автозагрузки
Это довольно хорошо документировано. $img
- тип WideImage_Image
. Существует также интерактивная онлайн-демонстрация.
Похожие вопросы: Удаление черных полос с миниатюры видео.
Ответ 4
Использование GD:
function imageautocrop( &$img) {
$emptycol = function ( $img, $x, $min, $max) {
for( $y=$min; $y<$max; $y++) {
$col = imagecolorsforindex( $img, imagecolorat( $img, $x, $y));
if( $col['alpha'] != 127) return false;
}
return true;
}
$trim = Array('top'=>0,'bot'=>0,'lft'=>0,'rgt'=>0);
$size = Array('x'=>imagesx($img)-1,'y'=>imagesy($img)-1);
// code for affecting rows removed due to question asked
while( $emptycol( $img, $trim['lft'], $trim['top'], $size['y']-$trim['bot'])) $trim['lft']++;
while( $emptycol( $img, $size['x']-$trim['rgt'], $trim['top'], $size['y']-$trim['bot'])) $trim['rgt']++;
$newimg = imagecreate( $size['x']-$trim['lft']-$trim['rgt']+1, $size['y']-$trim['top']-$trim['bot']+1);
imagecopy( $newimg, $img, 0, 0, $trim['lft'], $trim['top'], imagesx($newimg)+1, imagesy($newimg)+1);
imagedestroy($img);
$img = $newimg;
}
Это очень старый код, поэтому, вероятно, не оптимальный, но он выполняет эту работу.
Ответ 5
Вместо этого используйте cropImage(). Что-то вроде этого, возможно:
$img_x_size = 800; // Set these to relevant values
$img_y_size = 600;
$crop_pixels = 20; // How many pixels to crop
// cropImage(XsizeOfCrop, YsizeOfCrop, CropXPos, CropYPos)
$im->cropImage($img_x_size - $crop_pixels, $img_y_size, 0, $crop_pixels / 2);
Ответ 6
Это двухэтапный процесс, когда текст динамически генерируется
- Создайте текстовое изображение, определите ширину (изображение)
- Наложение текстового изображения на фон, определение ширины (фона)
- Используйте один инструмент, упомянутый выше, обрезка (ширина (фон) -width (изображение)/2 с обеих сторон
Трюк вычисляет ширину (изображение). Смотрите: Как настроить автоматическую настройку ширины GD-сгенерированного изображения в соответствии с текстом?
Затем, если вы знаете ширину (изображение), вы можете обрезать ширину (фон) перед наложением