PHP/GD: лучшая гауссовская размытость

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

<?php $im = imagecreatefrompng($_GET['image']);
if($im && imagefilter($im, IMG_FILTER_GAUSSIAN_BLUR))
{
  header('Content-Type: image/png');
    imagepng($im);
}
else
{
    echo 'fail';
}

imagedestroy($im);

Я хочу что-то вроде этого или, по крайней мере, рядом с ним. image from //tutorial9.s3.amazonaws.com/uploads/2008/06/lens-blur.jpg

Ответы

Ответ 1

Вы можете попробовать свертку:

$gaussian = array(array(1.0, 2.0, 1.0), array(2.0, 4.0, 2.0), array(1.0, 2.0, 1.0));
imageconvolution($image, $gaussian, 16, 0);

$gaussian - матрица, поэтому математически это

[[1, 2, 1],
 [2, 4, 2],
 [1, 2, 1]]

вы можете найти другие фильтры свертки: http://aishack.in/tutorials/image-convolution-examples/

imageconvolution( <image element>, <convolution matrix>, <divisor (sum of convolution matrix)>, <color offset>);

поэтому из кода выше 1+2+1+2+4+2+1+2+1 = 16 сумма матрицы. http://www.php.net/manual/en/function.imageconvolution.php#97921 - это аккуратный трюк для получения сумма дивизора.

просмотрите http://php.net/manual/en/function.imageconvolution.php для получения дополнительной информации об этой функции.

хорошее модное размытие (1,2,1), (2,1,2), (1,2,1)

EDIT: как указано ниже, вы можете запускать любой фильтр более одного раза на результирующем выходе, чтобы также улучшить эффект.

Ответ 2

После того, как вы столкнулись с одной и той же проблемой, я применил тот же фильтр несколько раз и каждый раз к результирующему ресурсу предыдущего вызова "imagefilter". Я получил "более размытый" эффект, который вы ищете.

например:.

for ($x=1; $x<=15; $x++)
   imagefilter($image, IMG_FILTER_GAUSSIAN_BLUR);

Ответ 3

Не уверен, что аргументы imagefilter помогают, но проверяют их.

В качестве альтернативы просто примените фильтр изображения к нему результат пару раз

Ответ 4

попробуйте следующее:

<?php
//
//fastblur function from image hosting and processing site http://hero-in.com
//

function blur($img, $radius=10)
{

if ($radius>100) $radius=100; //max radius
if ($radius<0) $radius=0; //nin radius

$radius=$radius*4;
$alphaStep=round(100/$radius)*1.7;
$width=imagesx($img);
$height=imagesy($img);
$beginX=floor($radius/2);
$beginY=floor($radius/2);


//make clean imahe sample for multiply
$cleanImageSample=imagecreatetruecolor($width, $height);
imagecopy($cleanImageSample, $img, 0, 0, 0, 0, $width, $height);


//make h blur
for($i = 1; $i < $radius+1; $i++)
{
$xPoint=($beginX*-1)+$i-1;
imagecopymerge($img, $cleanImageSample, $xPoint, 0, 0, 0, $width, $height, $alphaStep);
}
//make v blur
imagecopy($cleanImageSample, $img, 0, 0, 0, 0, $width, $height);
for($i = 1; $i < $radius+1; $i++)
{
$yPoint=($beginY*-1)+$i-1;
imagecopymerge($img, $cleanImageSample, 0, $yPoint, 0, 0, $width, $height, $alphaStep);
}
//finish
return $img;
imagedestroy($cleanImageSample); 
}

//example
$im = ImageCreateFromJpeg('image.jpg');
$im = blur($im,10);
imagejpeg($im)
imagedestroy($im);
?>

Ответ 5

У меня очень хороший результат с последующим кодом, основанным на это решение:

    for ($i = 0; $i < 25; $i++) {
        if ($i % 10 == 0) {//each 10th time apply 'IMG_FILTER_SMOOTH' with 'level of smoothness' set to -7
            imagefilter($tmp_dst_image, IMG_FILTER_SMOOTH, -7);
        }
        imagefilter($tmp_dst_image, IMG_FILTER_GAUSSIAN_BLUR);
    }

Когда вы наносите гладкость после нескольких размытий, он обеспечивает очень хороший размытый эффект. Вы можете поэкспериментировать со следующим номером в коде: 25, 10, -7.

См. также: Как измерить скорость кода, написанного на PHP