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

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

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

Благодарю.

Ответы на вопрос(5)

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

example();
function example(){
    $img = imagecreatefromjpeg("http://ecx.images-amazon.com/images/I/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 = 0; --$b_rt) {
        for($y = $b_top; $y  $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
);
}
 Mike Odie14 окт. 2014 г., 02:31
Спасибо за это. Я столкнулся с некоторыми проблемами при попытке доступа к пикселям за пределами диапазона. Например, если изображение имеет ширину 1500 пикселей, оно пытается вызвать imagecolorat ($ img, 1500, 5); $ b_rt & $ b_btm должен быть на 1 меньше ширины & высота соответственно.
Решение Вопроса

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

//load the image
$img = imagecreatefromjpeg("http://ecx.images-amazon.com/images/I/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");
 usertest05 нояб. 2009 г., 17:29
Отличное спасибо, очень хороший код. И еще раз спасибо за помощь.
 John Smith02 окт. 2012 г., 03:19
Это так медленно ...
 gnud04 нояб. 2009 г., 02:04
Как я уже сказал в своем комментарии, я никогда не тестировал этот код. Начните с исправления опечаток и посмотрите, к чему это приведет - если вы предоставите пример изображения, яЯ проверю это.
 usertest03 нояб. 2009 г., 21:01
Я только что попробовал код, он отрезает часть изображения.
 gnud03 нояб. 2009 г., 21:16
Добавлен новый пример, который может помочь - этоне проверено, хотя. И я'Я не уверен, как это происходит с прозрачностью. Но вы можете понять это самостоятельно :)
 usertest04 нояб. 2009 г., 17:16
Спасибо, GNUD, как насчет этого?ecx.images-amazon.com/images/I/413XvF0yukL._SL500_AA280_.jpg
 jheddings03 нояб. 2009 г., 20:53
Хороший пример ... Как вы указали (только для пояснения), это предполагает наличие фиксированной границы белого цвета вокруг изображения.
 Arthur15 февр. 2016 г., 03:38
@gnud Можете ли вы привести пример, когда изображение для обрезки не может быть больше 200 пикселей?
 gnud03 нояб. 2009 г., 21:01
Этот код неПредполагается фиксированный размер рамки (например, все границы 14px), но предполагается, что граница одинакова по всем сторонам изображения. Вы можете использовать это как отправную точку, хотя. Помните, что проверка всех пикселей со всех сторон будет медленной - не надоДелайте это каждый раз, когда вы показываете изображение, делайте это, когда пользователь загружает его в первый раз :)
 Petar Vasilev11 февр. 2019 г., 22:05
@gnud я могу сделать это: $ img = imagecreatefromstring ($ data), где $ data - строка изображения, а затем передать $ img вашему коду вместо $ img = imagecreatefromjpeg ('URL-вот)? Я попробовал это, и это неЯ просто получаю чисто черное изображение! Не уверен, что попробовать.
 gnud03 нояб. 2009 г., 21:18
Все координаты изображения в библиотеке GD - 0,0 слева вверху. Мой оригинальный пример (теперь 2-й) ищет по диагонали вниз по направлению к правому нижнему углу в поисках небелого пикселя.
 Ankit13 февр. 2016 г., 00:37
Это то, что я искал.
 usertest03 нояб. 2009 г., 21:23
Теперь он отлично работает для верхних и левых, но неничего не делай для дна и справа.
 Ankit13 февр. 2016 г., 00:38
@JohnSmith Медленно, принимая во внимание больше написанного кода или в практическом исполнении?
 gnud05 нояб. 2009 г., 11:07
Хорошо яМы сделали два изменения, и это работает для меня. Исправлена одна опечатка, и добавлено "-1" к нижним и правым индексам, потому что индекс начинается с 0, а не с 1.
 Rapti25 нояб. 2013 г., 00:29
Спасибо! Но что мне нужно изменить, чтобы обрезать прозрачные границы?
 usertest03 нояб. 2009 г., 20:59
Привет граница нет фиксированного размера. Я'Я думаю о чем-то вроде фотошопа.
 Captain Hypertext27 авг. 2018 г., 18:55
Этот ответ, кажется, устарел, кажется, что есть некоторые встроенные решения, приведенные в ответах ниже.
 usertest03 нояб. 2009 г., 21:05
@gnud: Я понимаю, что вы говорите, вы имеете в виду проработать белую рамку с каждой стороны в отдельности. Код выше вычисляет границу сверху или слева страницы?

Я понимаю, что это довольно старый процесс, но у меня немного другой подход к обрезке изображения с помощью GD. Вместо того, чтобы делать только одну сторону за раз - делай все четыре. В некоторых отношениях это быстрее и дешевле. Однако, если вы остановите циклы 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

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

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

 a2030 нояб. 2017 г., 12:42
Я хочу убрать белую рамку из изображений, потому что она выглядит некрасиво на небелых фонах (красный, черный и т. Д.). Php»Библиотека Imagick имеет только функцию Imagick-> trimImage (), который удаляет только те границы, которые совпадают с фоном - для меня это бесполезно.

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

Обрезать изображение

 Bill H30 нояб. 2017 г., 20:52
Попробуйте использовать Imagick :: shave (). Пока границы все равны, это должно помочь.
 a2030 нояб. 2017 г., 12:42
Я хочу убрать белую рамку из изображений, потому что она выглядит некрасиво на небелых фонах (красный, черный и т. Д.). Php»Библиотека Imagick имеет только функцию Imagick-> trimImage (), который удаляет только те границы, которые совпадают с фоном - для меня это бесполезно.
 jjwdesign27 февр. 2017 г., 14:17
Imagick :: trimImage теперь имеет параметр fuzz: "По умолчанию цель должна точно соответствовать определенному цвету пикселя. Однако во многих случаях два цвета могут незначительно отличаться. Размытый элемент изображения определяет, насколько допустимо допускать, чтобы два цвета считались одинаковыми. Этот параметр представляет собой изменение квантового диапазона ".

Ваш ответ на вопрос