Search code examples
phpimageimagefilter

How create image with a blur image background in php


Im trying to create with php a 4:3 image with any image uploaded by user. No matter the image original size, i want to fill the background with a blurred copy of the same image.

This is the code i use (from 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);

The result is like this image: my result until now

What do i need? The result that i hope

Please any idea will be welcome. Thank you in advance!!!


Solution

  • I enhanced @mhuenchul code and it works now whatever the image size is.

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