简体   繁体   中英

PHP imagecopyresampled problem with ratio, resizing and cropping

Okey so i am writing a image upload where we want to force the images to be 795x440px. They can be rezised but they have to keep their aspect ratio so they can be cropped also.

The new images comes out in the right size, but the cropped image from original file has the wrong ratio, tried some diffrent ways but can't get it right.

The image i am testing right now, original file

http://image.bayimg.com/jaiflaada.jpg

The result from cropping

http://image.bayimg.com/jaifmaada.jpg

How do i get this right, so the image always gets the best size and crops the rest?

list($width, $height) = getimagesize($save_dir);

$prop = (795 / $width);
$height = floor($height * $prop);


$new_image = imagecreatetruecolor(795, 440);

$bgColor = imagecolorallocate($new_image, 255,255,255) or die("Couldn't allocate color");
imagefill($new_image , 0,0 , $bgColor) or die("Couldnt fill with color");


imagecopyresampled($new_image,$source_image,0,0,0,0,795,440,795,$height);


imagejpeg($new_image,$new_directory,100);

I have done it quite simple. Using the same technique, but - image ALWAYS keeps its aspect ratio. And is resized in the center of target image.

//Create empty image and fill background with white color   
    $thumbnail = imagecreatetruecolor($width, $height); 
    $white = imagecolorallocate($thumbnail, 255, 255, 255);
    imagefill($thumbnail, 0, 0, $white);        

    //calculate resized image picture dimensions 
    $width_ratio = $image_width/$width;
    $height_ratio = $image_height/$height;

    //This is the key. Target dimensions will be correct aspect ratio.
    if ($width_ratio>$height_ratio) {
        $dest_width=$width;
        $dest_height=$image_height/$width_ratio;        
    }
    else{       
        $dest_width=$image_width/$height_ratio + 2; // small images looks better if +2px
        $dest_height=$height;           
    }   

    //calculate picture position 'in center' of new image.
    $int_width = ($width - $dest_width)/2;
    $int_height = ($height - $dest_height)/2;        

    imagecopyresampled($thumbnail, $thumb, $int_width, $int_height, 0, 0, $dest_width, $dest_height, $image_width, $image_height);

You can try this function.

function thumb($file, $save, $width, $height)
    {
        @unlink($save);

        if (!$infos = @getimagesize($file)) {
            return false;
        }

        $iWidth = $infos[0];
        $iHeight = $infos[1];
        $iRatioW = $width / $iWidth;
        $iRatioH = $height / $iHeight;

        $iNewW = $width;
        $iNewH=($iHeight/$iWidth)*$iNewW;

        //$iNewH = $height;


        //Don't resize images which are smaller than thumbs
        if ($infos[0] < $width && $infos[1] < $height) {
            $iNewW = $infos[0];
            $iNewH = $infos[1];
        }

        if($infos[2] == 1) {

            $imgA = imagecreatefromgif($file);
            $imgB = imagecreate($iNewW,$iNewH);

            if(function_exists('imagecolorsforindex') && function_exists('imagecolortransparent')) {
                $transcolorindex = imagecolortransparent($imgA);
                    //transparent color exists
                    if($transcolorindex >= 0 ) {
                        $transcolor = imagecolorsforindex($imgA, $transcolorindex);
                        $transcolorindex = imagecolorallocate($imgB, $transcolor['red'], $transcolor['green'], $transcolor['blue']);
                        imagefill($imgB, 0, 0, $transcolorindex);
                        imagecolortransparent($imgB, $transcolorindex);
                    //fill white
                    } else {
                        $whitecolorindex = @imagecolorallocate($imgB, 255, 255, 255);
                        imagefill($imgB, 0, 0, $whitecolorindex);
                    }
            //fill white
            } else {
                $whitecolorindex = imagecolorallocate($imgB, 255, 255, 255);
                imagefill($imgB, 0, 0, $whitecolorindex);
            }
            imagecopyresampled($imgB, $imgA, 0, 0, 0, 0, $iNewW, $iNewH, $infos[0], $infos[1]);
            imagegif($imgB, $save);        

        } elseif($infos[2] == 2) {

            $imgA = imagecreatefromjpeg($file);
            $imgB = imagecreatetruecolor($iNewW,$iNewH);
            imagecopyresampled($imgB, $imgA, 0, 0, 0, 0, $iNewW, $iNewH, $infos[0], $infos[1]);
            imagejpeg($imgB, $save);


        } elseif($infos[2] == 3) {
            /*
            * Image is typ png
            */
            $imgA = imagecreatefrompng($file);
            $imgB = imagecreatetruecolor($iNewW, $iNewH);
            imagealphablending($imgB, false);
            imagecopyresampled($imgB, $imgA, 0, 0, 0, 0, $iNewW, $iNewH, $infos[0], $infos[1]);
            imagesavealpha($imgB, true);
            imagepng($imgB, $save);

        } else {
            return false;
        }
        return true;
    }

thumb($source,$target_full_path,'337','208');

I do it like that:

public function cropImage($nw, $nh, $source, $stype, $dest) {
    list($w, $h) = getimagesize($source);

    switch($stype) {
        case 'gif':
            $simg = imagecreatefromgif($source);
        break;
        case 'jpg':
        case 'jpeg':
            $simg = imagecreatefromjpeg($source);
        break;
        case 'png':
            $simg = imagecreatefrompng($source);
        break;
    }
    $dimg = imagecreatetruecolor($nw, $nh);
    $white = imagecolorallocate($dimg, 255, 255, 255);
    imagefill($dimg, 1, 1, $white);
    $wm = $w/$nw;
    $hm = $h/$nh;
    $h_height = $nh/2;
    $w_height = $nw/2;

    if($w > $h) {
         $adjusted_width = $w / $hm;
         $half_width = $adjusted_width / 2;
         $int_width = $half_width - $w_height;
         imagecopyresampled($dimg, $simg, -$int_width, 0, 0, 0, $adjusted_width, $nh, $w, $h);
    } elseif(($w < $h) || ($w == $h)) {
         $adjusted_height = $h / $wm;
         $half_height = $adjusted_height / 2;
         $int_height = $half_height - $h_height;
         imagecopyresampled($dimg,$simg,0,-$int_height,0,0,$nw,$adjusted_height,$w,$h);
    } else {
         imagecopyresampled($dimg,$simg,0,0,0,0,$nw,$nh,$w,$h);
    }       

    if(imagejpeg($dimg, $dest, 70))
        return true;
    else
        die("cropImage: error.");
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM