Обрезать пробелы из изображения в PHP

Можно ли удалить пробел, окружающий изображение в PHP?

ПРИМЕЧАНИЕ. Чтобы уточнить, я имею в виду что-то вроде функции отделки photoshop.

Благодарю.

Related of "Обрезать пробелы из изображения в PHP"

Чтобы обрезать все пробелы, как вы его называете, окружая интересную часть изображения, сначала мы узнаем, где останавливается «пробел», а затем мы копируем все внутри этих границ.

//load the image $img = imagecreatefromjpeg("http://img.ruphp.com/php/413XvF0yukL._SL500_AA280_.jpg"); //find the size of the borders $b_top = 0; $b_btm = 0; $b_lft = 0; $b_rt = 0; //top for(; $b_top < imagesy($img); ++$b_top) { for($x = 0; $x < imagesx($img); ++$x) { if(imagecolorat($img, $x, $b_top) != 0xFFFFFF) { break 2; //out of the 'top' loop } } } //bottom for(; $b_btm < imagesy($img); ++$b_btm) { for($x = 0; $x < imagesx($img); ++$x) { if(imagecolorat($img, $x, imagesy($img) - $b_btm-1) != 0xFFFFFF) { break 2; //out of the 'bottom' loop } } } //left for(; $b_lft < imagesx($img); ++$b_lft) { for($y = 0; $y < imagesy($img); ++$y) { if(imagecolorat($img, $b_lft, $y) != 0xFFFFFF) { break 2; //out of the 'left' loop } } } //right for(; $b_rt < imagesx($img); ++$b_rt) { for($y = 0; $y < imagesy($img); ++$y) { if(imagecolorat($img, imagesx($img) - $b_rt-1, $y) != 0xFFFFFF) { break 2; //out of the 'right' loop } } } //copy the contents, excluding the border $newimg = imagecreatetruecolor( imagesx($img)-($b_lft+$b_rt), imagesy($img)-($b_top+$b_btm)); imagecopy($newimg, $img, 0, 0, $b_lft, $b_top, imagesx($newimg), imagesy($newimg)); //finally, output the image header("Content-Type: image/jpeg"); imagejpeg($newimg); 

Мой старый пример, который предполагает идентичную «границу» со всех сторон изображения, просто для уточнения комментариев 🙂

 //load the image $img = imagecreatefromjpeg("img.jpg"); //find the size of the border. $border = 0; while(imagecolorat($img, $border, $border) == 0xFFFFFF) { $border++; } //copy the contents, excluding the border //This code assumes that the border is the same size on all sides of the image. $newimg = imagecreatetruecolor(imagesx($img)-($border*2), imagesy($img)-($border*2)); imagecopy($newimg, $img, 0, 0, $border, $border, imagesx($newimg), imagesy($newimg)); //finally, if you want, overwrite the original image imagejpeg($newimg, "img.jpg"); 

Сценарий Гнуда избыточно вызывает imagesx и imagesy. Он также выполняет итерацию каждого пикселя со всех сторон, даже когда углы перекрываются. Эта улучшенная версия исключает избыточные вызовы функций и проверяет каждый пиксель только один раз, обеспечивая значительное увеличение скорости. Функция возвращает статус ($ result ['#']), равный 2, если каждый пиксель обрезается.

 example(); function example(){ $img = imagecreatefromjpeg("http://img.ruphp.com/php/413XvF0yukL._SL500_AA280_.jpg"); // find the trimmed image border $box = imageTrimBox($img); // copy cropped portion $img2 = imagecreate($box['w'], $box['h']); imagecopy($img2, $img, 0, 0, $box['l'], $box['t'], $box['w'], $box['h']); // output cropped image to the browser header('Content-Type: image/png'); imagepng($img2); imagedestroy($img); imagedestroy($img2); } function imageTrimBox($img, $hex=null){ if (!ctype_xdigit($hex)) $hex = imagecolorat($img, 0,0); $b_top = $b_lft = 0; $b_rt = $w1 = $w2 = imagesx($img); $b_btm = $h1 = $h2 = imagesy($img); do { //top for(; $b_top < $h1; ++$b_top) { for($x = 0; $x < $w1; ++$x) { if(imagecolorat($img, $x, $b_top) != $hex) { break 2; } } } // stop if all pixels are trimmed if ($b_top == $b_btm) { $b_top = 0; $code = 2; break 1; } // bottom for(; $b_btm >= 0; --$b_btm) { for($x = 0; $x < $w1; ++$x) { if(imagecolorat($img, $x, $b_btm-1) != $hex) { break 2; } } } // left for(; $b_lft < $w1; ++$b_lft) { for($y = $b_top; $y <= $b_btm; ++$y) { if(imagecolorat($img, $b_lft, $y) != $hex) { break 2; } } } // right for(; $b_rt >= 0; --$b_rt) { for($y = $b_top; $y <= $b_btm; ++$y) { if(imagecolorat($img, $b_rt-1, $y) != $hex) { break 2; } } } $w2 = $b_rt - $b_lft; $h2 = $b_btm - $b_top; $code = ($w2 < $w1 || $h2 < $h1) ? 1 : 0; } while (0); // result codes: // 0 = Trim Zero Pixels // 1 = Trim Some Pixels // 2 = Trim All Pixels return array( '#' => $code, // result code 'l' => $b_lft, // left 't' => $b_top, // top 'r' => $b_rt, // right 'b' => $b_btm, // bottom 'w' => $w2, // new width 'h' => $h2, // new height 'w1' => $w1, // original width 'h1' => $h1, // original height ); } 

Я знаю, что это довольно старый, но если у вас включен ImageMagick, вы можете использовать этот метод

Trim Image

Я понимаю, что это довольно старый, но я немного по-другому беру на обрезку изображения через GD. Вместо того, чтобы делать только одну сторону за раз – все четыре. В какой-то степени это быстрее и дешевле cpu-wise. Однако, если вы остановите цикл FOR в тот момент, когда вы найдете правую верхнюю левую и правую стороны – это быстрее, чем это.

Итак, сначала есть:

 # # Do all four sides at once # echo "Finding the top-left-bottom-right edges of the image...please wait.\n"; $top = 99999; $bot = -99999; $left = 99999; $right = -99999; for( $x=$offset; $x<($w-$offset); $x++ ){ for( $y=$offset; $y<($h-$offset); $y++ ){ $rgb = imagecolorat( $gd, $x, $y ); if( $color != $rgb ){ $left = ($x < $left) ? $x : $left; $right = ($x > $right) ? $x : $right; $top = ($y < $top) ? $y : $top; $bot = ($y > $bot) ? $y : $bot; } } } 

а затем есть:

 # # Top # echo "Finding the top of the image\n"; $top = null; for( $y=$offset; $y<($h-$offset); $y++ ){ for( $x=$offset; $x<($w-$offset); $x++ ){ $rgb = imagecolorat( $gd, $x, $y ); if( $color != $rgb ){ $top = $y; break; } } if( !is_null($top) ){ break; } } # # Bottom # echo "Finding the bottom of the image\n"; $bot = null; for( $y=($h-$offset); $y>$offset; $y-- ){ for( $x=$offset; $x<($w-$offset); $x++ ){ $rgb = imagecolorat( $gd, $x, $y ); if( $color != $rgb ){ $bot = $y; break; } } if( !is_null($bot) ){ break; } } # # Left # echo "Finding the left of the image\n"; $left = null; for( $x=$offset; $x<($w-$offset); $x++ ){ for( $y=$offset; $y<($h-$offset); $y++ ){ $rgb = imagecolorat( $gd, $x, $y ); if( $color != $rgb ){ $left = $x; break; } } if( !is_null($left) ){ break; } } # # right # echo "Finding the right of the image\n"; $right = null; for( $x=($w-$offset); $x>$offset; $x-- ){ for( $y=$offset; $y<($h-$offset); $y++ ){ $rgb = imagecolorat( $gd, $x, $y ); if( $color != $rgb ){ $right = $x; break; } } if( !is_null($right) ){ break; } } 

В обоих случаях переменная $ color содержит первую цветовую точку на изображении:

 $color = imagecolorat( $gd, 0, 0 ); 

Это связано с тем, что в GIF-изображениях – первая точка в 99% случаев прозрачного (или фонового) цвета. Кроме того, смещение $ (для меня) означает, что я знаю, что изображение будет только таким широким и таким высоким. Поэтому, если я нарисую что-то, что составляет максимум 256 на 256, но я помещаю его на фон 1024 x 1024, я могу отбросить часть этого фона и сделать смещение 255, тем самым делая цикл FOR только от 255 до (1024 -255) или 769.

Хорошо – прежде чем кто-то спросит – ПОЧЕМУ Я бы сделал такое – потому что некоторые шрифты (например, Bastarda) не имеют правильной информации о шрифтах в них, а вывод 256pt буквы «z» создает изображение, z "проходит мимо 256 (вплоть до примерно 512), поэтому, чтобы получить весь образ, вы должны начать (или закончить) дальше, чем то, что, по вашему мнению, будет идти. Поэтому я разделил разницу и ударил 255 пикселей с обоих концов. Это было после того, как он увидел, что это делает Бастарда.

Некоторые дополнительные примечания:

1. PNG-изображения, которые вы можете настроить как изображения GIF, но обычно вам нужно указать, какой будет цвет фона.
2. Изображения JPEG НЕ разматывают точно так же каждый раз. Поэтому даже сравнение того же изображения, которое вы загрузили дважды, может не работать одинаково и может давать разные размеры.
3. Эти процедуры лучше всего работают на простых черно-белых (или двухцветных) изображениях. Несколько цветов могут отбросить эти процедуры. Особенно, если вы решите использовать допуски.
4. Чтобы использовать допуски, чтобы определить, нашли ли вы край изображения, все, что вам нужно сделать, это предварительно вычислить как высокий, так и низкий допуск (т. Е. Если у вас есть допущение пяти (5) на красном компоненте , то вы можете вычислить допуск как X-5-x-x + 5 или x-2,5-x + 2,5 в зависимости от того, хотите ли вы, чтобы допуск был диапазоном WHOLE или только диапазоном +/-). Вы можете иметь допуск для красных, зеленых, голубых и ALPHA частей цвета или всего цвета. Таким образом, есть несколько разных допусков, которые вы можете вычислить, если хотите, и все они – правильный способ сделать это в зависимости от ваших потребностей.

Проверьте библиотеку ImageMagick на PHP. Он имеет хорошие методы работы с изображениями (включая растение ) и манипулирования ими.

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

В gd-библиотеке PHP есть функция imagecropauto :

 <?php $img=imagecreatefrompng("tux.png"); // Load and instantiate the image if($img) { $cropped=imagecropauto($img,IMG_CROP_DEFAULT); // Auto-crop the image imagedestroy($img); // Clean up as $img is no longer needed header("Content-type: image/png"); // Set the appropriate header so the browser // knows how to present it imagepng($cropped); // Return the newly cropped image } 

По умолчанию imagecropauto будет пытаться обрезать с использованием прозрачности, а затем снова вернуться к использованию четырех углов изображения, чтобы попытаться обнаружить фон для обрезки; У меня также был успех со следующими константами вместо IMG_CROP_AUTO в приведенном выше примере:

  • IMG_CROP_BLACK – Полезно для изображений с черным фоном
  • IMG_CROP_WHITE – Полезно для изображений с белым фоном
  • IMG_CROP_THRESHOLD – позволяет установить цвет и порог для использования при обрезке

imagecropauto был включен в php с версии 5.5, для получения дополнительной информации см. Документацию по PHP для imagecropauto здесь .