PHP imagecopy решает проблему с соотношением, изменением размера и кадрированием - PullRequest
0 голосов
/ 11 мая 2011

Хорошо, я пишу загрузку изображений, где мы хотим, чтобы изображения были размером 795x440 пикселей. Их можно изменить, но они должны сохранить соотношение сторон, чтобы их можно было обрезать.

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

Изображение, которое я сейчас тестирую, оригинальный файл

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

Результат обрезки

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

Как я могу сделать это правильно, чтобы изображение всегда получало наилучший размер и обрезало все остальное?

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

Ответы [ 3 ]

2 голосов
/ 15 января 2013

Я сделал это довольно просто.Используя ту же технику, но - изображение ВСЕГДА сохраняет свое соотношение сторон.И изменяется в центре целевого изображения.


    //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);  

1 голос
/ 11 мая 2011

Вы можете попробовать эту функцию.

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');
0 голосов
/ 11 мая 2011

Я делаю так:

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.");
}
...