如何在 php 中创建具有模糊图像背景的图像

How create image with a blur image background in php

我正在尝试使用 php 创建一张 4:3 图像,其中包含用户上传的任何图像。无论图像原始大小如何,我都想用同一图像的模糊副本填充背景。

这是我使用的代码(来自 István Ujj-Mészáros):

function resize($source_image, $destination, $tn_w, $tn_h, $quality = 90) {

    $info = getimagesize($source_image);
    $imgtype = image_type_to_mime_type($info[2]);

    #assuming the mime type is correct
    switch ($imgtype) {
        case 'image/jpeg':
            $source = imagecreatefromjpeg($source_image);
            break;
        case 'image/gif':
            $source = imagecreatefromgif($source_image);
            break;
        case 'image/png':
            $source = imagecreatefrompng($source_image);
            break;
        default:
            die('Invalid image type.');
    }

    #Figure out the dimensions of the image and the dimensions of the desired thumbnail
    $src_w = imagesx($source);
    $src_h = imagesy($source);

    #Do some math to figure out which way we'll need to crop the image
    #to get it proportional to the new size, then crop or adjust as needed
    $x_ratio = $tn_w / $src_w;
    $y_ratio = $tn_h / $src_h;

    if (($src_w <= $tn_w) && ($src_h <= $tn_h)) {
        $new_w = $src_w;
        $new_h = $src_h;
    } elseif (($x_ratio * $src_h) < $tn_h) {
        $new_h = ceil($x_ratio * $src_h);
        $new_w = $tn_w;
    } else {
        $new_w = ceil($y_ratio * $src_w);
        $new_h = $tn_h;
    }

    $newpic = imagecreatetruecolor(round($new_w), round($new_h));
    imagecopyresampled($newpic, $source, 0, 0, 0, 0, $new_w, $new_h, $src_w, $src_h);
    $final = imagecreatetruecolor($tn_w, $tn_h);

    // This code fill with green color
    //$backgroundColor = imagecolorallocate($final, 0, 255, 0);
    //imagefill($final, 0, 0, $backgroundColor);
    imagecopy($final, $newpic, (($tn_w - $new_w)/ 2), (($tn_h - $new_h) / 2), 0, 0, $new_w, $new_h);

    // This code generates a blurred image
    # ****************************************************
    //for ($x=1; $x <=2; $x++){
    //    imagefilter($final, IMG_FILTER_GAUSSIAN_BLUR, 999);
    //} 
    //imagefilter($final, IMG_FILTER_SMOOTH,99);
    //imagefilter($final, IMG_FILTER_BRIGHTNESS, 10);  
    # ****************************************************

    if (imagejpeg($final, $destination, $quality)) {
        return true;
    }
    return false;
}

// targetFilePath contains the folder an filename
resize($targetFilePath,$targetFilePath,640,480,90);

结果就像这张图: my result until now

我需要什么? The result that i hope

欢迎任何想法。 提前致谢!!!

有很多方法,但我建议您使用 imagecopymerge 而不是 imagecopy。您提供目的地和源坐标 以及源大小 瞧!

但是请注意,这样您将无法保持透明度(对于 GIF/PNG,如果存在)。为此,请查看 PHP 文档中 Sina Salek 的评论:PNG ALPHA CHANNEL SUPPORT for imagecopymerge()

但我同意@LeeKowalkowski 的观点 - 从长远来看 运行,你应该考虑迁移到 ImageMagick,原因有很多 - 最重要的是图像质量。

编辑:我忘了提到,在合并之前,用 imagecolortransparent 设置透明颜色(扩展的 canvas)。然后,Sina Salek在PHP文档中的评论(上面的link)。

好的,我做了我的工作并研究了更多关于 php 图像命令的信息。我写了一个非常有效的解决方案。

<?php

$image = "01.jpg";

image_web($image, 700, 525); // I need final images 700x525 (4:3)

echo '<img src="00.jpg"/>';

function image_web($image, $width, $height){ // Get the image source and the final desire dimensions
    $info = getimagesize($image);
    //$mimetype = $info['mime']; // other way to get mimetype
    $mimetype = image_type_to_mime_type($info[2]);
    $allowTypes = array('image/jpeg','image/png','image/gif');    
    if(in_array($mimetype, $allowTypes)){
        switch ($mimetype) {
            case 'image/jpeg':
                $image = imagecreatefromjpeg($image);
                break;
            case 'image/gif':
                $image = imagecreatefromgif($image);
                break;
            case 'image/png':
                $image = imagecreatefrompng($image);
                break;
            default:
                die('Invalid image type.');
        }
    } else {
        echo 'Is not a image';
    }
    $image2 = $image; // Save a copy to be used for front image
    $wor = imagesx($image); // Get original image width
    $hor = imagesy($image); // Get original image height
    if ($hor >= $wor){ // If is vertical*******************************************************************************************************
        if ($wor >= $width){ // If image source is bigger than final desire dimensions
            $hcenter = ($hor/2)-($height/2); // center image source in height
            $back = imagecreatetruecolor(round($width), round($height));
            imagecopyresampled($back, $image, 0, -$hcenter, 0, 0, $wor, $hor, $wor, $hor);
        } else { // If image source is not bigger than final desire dimensions
            $hcenter = ($hor/2)-($height/2); // center image source in height
            $hnu = ($hor*$width)/$wor;
            $back = imagecreatetruecolor(round($width), round($height));
            imagecopyresampled($back, $image, 0, -$hcenter, 0, 0, $width, $hnu, $wor, $hor);
        }
    } else { // If is portrait rectangular****************************************************************************************************  
        $ratio = $wor/$hor;
        if($ratio > 1.3333333){ // If is portrait larger than 4:3       
            $wnu = ($wor*$height)/$hor;
            $wcenter = ($wnu/2)-($width/2); // center image in width
            $back = imagecreatetruecolor(round($width), round($height));
            imagecopyresampled($back, $image, -$wcenter, 0, 0, 0, $wnu, $height, $wor, $hor); 
        } else { // If portrait is not larger than 4:3
            $hnu = ($wor*$height)/$hor;
            $hcenter = ($hnu/2)-($height/2); // center image source in height
            $back = imagecreatetruecolor(round($width), round($height));
            imagecopyresampled($back, $image, 0, -$hcenter, 0, 0, $width, $hnu, $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);
    // Getting the dimensions of the image
    $src_w = imagesx($image2);
    $src_h = imagesy($image2);
    // Do some math to figure out which way we'll need to crop the image
    // to get it proportional to the new size, then crop or adjust as needed
    $x_ratio = $width / $src_w;
    $y_ratio = $height / $src_h;
    if (($src_w <= $width) && ($src_h <= $height)) {
        $new_w = $src_w;
        $new_h = $src_h;
    } elseif (($x_ratio * $src_h) < $height) {
        $new_h = ceil($x_ratio * $src_h);
        $new_w = $width;
    } else {
        $new_w = ceil($y_ratio * $src_w);
        $new_h = $height;
    }
    $front = imagecreatetruecolor(round($new_w), round($new_h));
    imagecopyresampled($front, $image2, 0, 0, 0, 0, $new_w, $new_h, $src_w, $src_h);
    if ($new_h >= $new_w){ // If is vertical image
        $wctr = ($new_w/2)-($width/2);
        imagecopymerge($back, $front,-$wctr, 0, 0, 0, $new_w, $new_h, 100);
    } else { // if is portrait
        $hctr = ($new_h/2)-($height/2);
        imagecopymerge($back, $front,0, -$hctr, 0, 0, $new_w, $new_h, 100);
    }
    // output new file
    imagejpeg($back,'00.jpg',90);
    imagedestroy($back);
    imagedestroy($front);
    //*********************************************************************************
    /**
    Do other actions like send ajax responses, save in database, etc
    **/
}

?>

我增强了@mhuenchul 代码,现在无论图像大小如何,它都可以工作。

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;
}