Иногда есть необходимость "заблюрить картинку", т.е. сделать ее размытой с помощью php-скрипта. Это может понадобится для замены каких-то изображений для неавторизованных пользователей, например, или для скрытия результатов теста. Можно для этой цели использовать CSS-фильтр blur(), но при открытии картинки в новой вкладке пользователь все равно увидит изображение без фильтра.
Поэтому мы можем использовать функцию, которая будет преобразовывать изображение из его нормального вида в размытое. В функцию мы будем передавать URL изображения, а возвращать будем 2 параметра в виде массива - URL нового размытого изображения и путь к нему в файловой системе.
Внутри функции нам понадобится получить путь к файлу изображения не по URL, а в файловой системе сервера, т.к. именно в папку, где хранится исходное изображение, мы будем сохранять новое, размытое изображение с суффиксом -blured
. Разрешение файла изображения может быть JPEG, PNG, GIF, WEBP или AVIF, т.к. php предоставляет ряд функций для создания изображений в этих форматах, но вы должны понимать, что такая функция, как imageavif() будет работать только с php с версии 8.1.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | <?php function createBlurryPic($url) { if(strpos($url, '-blured')>4) return false; $picPath = parse_url($url)['path']; $actual_link = (empty($_SERVER['HTTPS']) ? 'http' : 'https') . "://" . $_SERVER['HTTP_HOST']; $file = $_SERVER['DOCUMENT_ROOT'].$picPath; $replacedPath = preg_replace('/(\.\w+)$/', '-blured$1', $picPath); $dest = $_SERVER['DOCUMENT_ROOT'].$replacedPath; $urlBlured = rtrim($actual_link,'/').$replacedPath; if( file_exists($dest) ) return array('path'=>$dest, 'url' => $urlBlured); $type = exif_imagetype($url); switch ($type){ case 1: $src = imagecreatefromgif($file); break; case 2: $src = imagecreatefromjpeg($file); break; case 3: $src = imagecreatefrompng($file); break; case 18: $src = imagecreatefromwebp($file); break; case 19: $src = imagecreatefromavif($file); break; default: return array('path'=>$file, 'url' => $url); } for ($x=1; $x <=50; $x++){ imagefilter($src, IMG_FILTER_GAUSSIAN_BLUR, 999); } imagefilter($src, IMG_FILTER_SMOOTH,99); imagefilter($src, IMG_FILTER_BRIGHTNESS, 10); switch ($type){ case 1: imagegif($src, $dest); break; case 2: imagejpeg($src, $dest); break; case 3: imagepng($src, $dest); break; case 18: imagewebp($src, $dest); break; case 19: imageavif($src, $dest); break; default: return array('path'=>$file, 'url' => $url); } imagedestroy($src); return array('path'=>$dest, 'url' => $urlBlured); } $pic = "http://testsite.com/images/boats.jpg"; $pic_blured = createBlurryPic($pic)["url"]; $pic1 = "http://testsite.com/images/door.webp"; $pic1_blured = createBlurryPic("http://testsite.com/images/door.webp")["url"]; ?> <div class="warpper"> <h1>Blurred images with php</h1> <img src="<?= $pic ?>" alt="Beach"> <img src="<?= $pic_blured ?>" alt="Beach"> <img src="<?= $pic1 ?>" alt="Door"> <img src="<?= $pic1_blured ?>" alt="Door"> </div> |
Результатом выполнения этого кода будет вывод 2-х изображений в форматах JPG и WEBP в нормальном и размытом состоянии:
В коде есть проверка на существование нужного вам изображения для того, чтобы не генерировать его снова.
Неполное размытие картинки по сторонам
Еще более крутой вариант - размытие только по боковым сторонам. Подсмотрено здесь.
И этот, и предыдущий код требует от одной до нескольких секунд для создания изображений в зависимости от мощности компьютера и размеров картинки, поэтому вам нужно будет подождать результата.
Функция, приведенная ниже, отличается от той, что была в первом коде. В нее вы передаете путь к обычному изображению и тот путь, куда должно быть сохранено новое. Вставить в код нужное изображение вы должны сами в зависимости от заданного вами пути к нему.
Проверка на существование нужного вам изображения в функции отсутствует.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | <?php function image_blurred_bg($image, $dest, $width, $height){ try{ $info = getimagesize($image); } catch (Exception $e){ return false; } $mimetype = image_type_to_mime_type($info[2]); switch ($mimetype) { case 'image/jpeg': $image = imagecreatefromjpeg($image); break; case 'image/gif': $image = imagecreatefromgif($image); break; case 'image/png': $image = imagecreatefrompng($image); break; default: return false; } $wor = imagesx($image); $hor = imagesy($image); $back = imagecreatetruecolor($width, $height); $maxfact = max($width/$wor, $height/$hor); $new_w = $wor*$maxfact; $new_h = $hor*$maxfact; imagecopyresampled($back, $image, -(($new_w-$width)/2), -(($new_h-$height)/2), 0, 0, $new_w, $new_h, $wor, $hor); // Blur Image for ($x=1; $x <=40; $x++){ imagefilter($back, IMG_FILTER_GAUSSIAN_BLUR, 999); } imagefilter($back, IMG_FILTER_SMOOTH,99); imagefilter($back, IMG_FILTER_BRIGHTNESS, 10); $minfact = min($width/$wor, $height/$hor); $new_w = $wor*$minfact; $new_h = $hor*$minfact; $front = imagecreatetruecolor($new_w, $new_h); imagecopyresampled($front, $image, 0, 0, 0, 0, $new_w, $new_h, $wor, $hor); imagecopymerge($back, $front,-(($new_w-$width)/2), -(($new_h-$height)/2), 0, 0, $new_w, $new_h, 100); // output new file imagejpeg($back,$dest,90); imagedestroy($back); imagedestroy($front); return true; } image_blurred_bg("images/app.jpg", "images/app1.jpg", 400, 400 ); ?> |
Результат выполнения кода будет таким: