图像调整大小错误

时间:2014-10-10 14:02:24

标签: php image image-processing

我继承了一个调整图像大小的功能。它在大多数情况下效果很好,但由于某些原因,在某些情况下,调整图像大小的结果与最初包含的图像完全不同。功能如下:

function image_resize($source, $destination, $width, $height, $resizeMode='fit', $type = 'jpeg', $options = array()) {


    $defaults = array(
        'output' => 'file',
        'isFile' => true,
        'quality' => '100',
        'preserveAnimation' => false,
        'offsetTop' => 0,
        'offsetLeft' => 0,
        'offsetType' => 'percent'
    );

    foreach ($defaults as $k => $v) {
        if (!isset($options[$k])) {
            $options[$k] = $v;
        }
    }

    if ($options['isFile']) {
        $image_info = getimagesize($source);
        $image = null;
        switch ($image_info[2]) {
            case IMAGETYPE_JPEG:
                $image = imagecreatefromjpeg($source);
                break;
            case IMAGETYPE_PNG:
                $image = imagecreatefrompng($source);
                break;
            case IMAGETYPE_GIF:
                $image = imagecreatefromgif($source);
                break;
            case IMAGETYPE_BMP:
                $image = imagecreatefromwbmp($source);
                break;
            default :
                return false;
        }
    } else {
        $image = imagecreatefromstring($source);
    }

    //we have an image resource
    $iwidth = imagesx($image);
    $iheight = imagesy($image);

    //We need $width and $height for this call
    if (QM::isAcceptableProfilePhotoSize($width, $height) == false)
    {
        throw new Exception("Size of ".$width."x".$height." is not supported");
    }

    //determine ratios
    $wratio = $width / $iwidth;
    $hratio = $height / $iheight;
    $mratio = min(array($wratio, $hratio));

    $rimage = null;

    switch ($resizeMode) {
        case 'fit':
            $rimage = imagecreatetruecolor($iwidth * $mratio, $iheight * $mratio);
            $image = imagecopyresampled($rimage, $image, 0, 0, 0, 0, $iwidth * $mratio, $iheight * $mratio, $iwidth, $iheight);
            break;
        case 'crop':
            $rratio = $width / $height;


            if ($rratio < 1) {
                $nwidth = $iwidth;
                $nheight = $iwidth * 1/$rratio;
                if ($nheight>$iheight) {
                    $nwidth = $nwidth*$iheight/$nheight;
                    $nheight = $iheight;
                }
            } else {
                $nwidth = $iheight*$rratio;
                $nheight = $iheight;
                if ($nwidth>$iwidth) {
                    $nheight = $nheight*$iwidth/$nwidth;
                    $nwidth = $iwidth;
                }
            }
            switch ($options['offsetType']) {
                case 'percent':
                    $sx = ($iwidth-$nwidth)*$options['offsetLeft']/100;
                    $sy = ($iheight-$nheight)*$options['offsetTop']/100;
                    break;
                default :
                    return false;
            }

            $rimage = imagecreatetruecolor($width, $height);
            $image = imagecopyresampled($rimage, $image, 0, 0, $sx, $sy, $width, $height, $nwidth, $nheight);
            break;
        default :
            return false;
            break;
    }

    if (!is_writeable(dirname($destination))) {
        throw new Exception(getcwd(). "/" .dirname($destination)." is not writeable");
    }

    switch ($options['output']) {
        case 'file':
            switch ($image_info[2]) {
                case IMAGETYPE_JPEG:
                    return imagejpeg($rimage, $destination, $options['quality']);
                case IMAGETYPE_PNG:
                    return imagepng($rimage, $destination, 0);
                case IMAGETYPE_GIF:
                    return imagegif($rimage, $destination);
                case IMAGETYPE_BMP:
                    return imagejpeg($rimage, $destination, $options['quality']);
                default :
                    return false;
                    break;
            }
            return true;
            break;
        default :
            return false;
            break;
    }
}

导致问题的示例图像: enter image description here

此图片已成功上传,但当我尝试调整图片大小时,生成的图片为:

enter image description here

我用这种方式调用函数:

image_resize($ofile, $cfile, $width, $height, 'crop', 'jpeg');

$ofile是原始文件,$cfile是计划目的地,$width是所需宽度(本例中为90),$height是所需高度(在这种情况下为90),'crop'是选定的策略,'jpeg'是某个$type值,在函数中未使用(正如我所提到的,我继承了代码)。此外,唯一可以重现问题的例子是附加图像,这是一个png,其他png文件正确上传,所以我不明白问题的原因,也不知道如何解决它。任何人都可以描述问题的原因吗?我已经搜索和实验了很长一段时间而没有取得成功。

1 个答案:

答案 0 :(得分:1)

我用你的鸟图片尝试了你的“image_resize”功能,它在我的电脑上工作得很好, 我是否将源图像设置为jpg或png,它按预期工作:

resized bird

然而,为什么不选择“适合”而不是“庄稼”如此:

image_resize($ofile, $cfile, $width = 90, $height = 90, 'fit', 'jpeg');

编辑:基于其他人在调整PNG大小后获取黑色图片的问题,这将是更正:

function image_resize($source, $destination, $width, $height, $resizeMode='fit', $type = 'jpeg', $options = array()) {

    $defaults = array(
        'output' => 'file',
        'isFile' => true,
        'quality' => '100',
        'preserveAnimation' => false,
        'offsetTop' => 0,
        'offsetLeft' => 0,
        'offsetType' => 'percent'
    );

    foreach ($defaults as $k => $v) {
        if (!isset($options[$k])) {
            $options[$k] = $v;
        }
    }

    if ($options['isFile']) {
        $image_info = getimagesize($source);
        $image = null;
        switch ($image_info[2]) {
            case IMAGETYPE_JPEG:
                $image = imagecreatefromjpeg($source);
                break;
            case IMAGETYPE_PNG:
                $image = imagecreatefrompng($source);
                break;
            case IMAGETYPE_GIF:
                $image = imagecreatefromgif($source);
                break;
            case IMAGETYPE_BMP:
                $image = imagecreatefromwbmp($source);
                break;
            default :
                return false;
        }   
    } else {
        $image = imagecreatefromstring($source);
    }   

    //we have an image resource
    $iwidth = imagesx($image);
    $iheight = imagesy($image);

    //determine ratios
    $wratio = $width / $iwidth;
    $hratio = $height / $iheight;
    $mratio = min(array($wratio, $hratio));

    $rimage = null;

    switch ($resizeMode) {
        case 'fit':
            $rimage = imagecreatetruecolor($iwidth * $mratio, $iheight * $mratio);
            imagealphablending( $rimage, false );
            imagesavealpha( $rimage, true ); 
            $image = imagecopyresampled($rimage, $image, 0, 0, 0, 0, $iwidth * $mratio, $iheight * $mratio, $iwidth, $iheight);
            break;
        case 'crop':
            $rratio = $width / $height;


            if ($rratio < 1) {
                $nwidth = $iwidth;
                $nheight = $iwidth * 1/$rratio;
                if ($nheight>$iheight) {
                    $nwidth = $nwidth*$iheight/$nheight;
                    $nheight = $iheight;
                }
            } else {
                $nwidth = $iheight*$rratio;
                $nheight = $iheight;
                if ($nwidth>$iwidth) {
                    $nheight = $nheight*$iwidth/$nwidth;
                    $nwidth = $iwidth;
                }
            }
            switch ($options['offsetType']) {
                case 'percent':
                    $sx = ($iwidth-$nwidth)*$options['offsetLeft']/100;
                    $sy = ($iheight-$nheight)*$options['offsetTop']/100;
                    break;
                default :
                    return false;
            }

            $rimage = imagecreatetruecolor($width, $height);
            imagealphablending( $rimage, false );
            imagesavealpha( $rimage, true );
            $image = imagecopyresampled($rimage, $image, 0, 0, $sx, $sy, $width, $height, $nwidth, $nheight);
            break;
        default :
            return false;
            break;
    }

    if (!is_writeable(dirname($destination))) {
        throw new Exception(getcwd(). "/" .dirname($destination)." is not writeable");
    }

    switch ($options['output']) {
        case 'file':
            switch ($image_info[2]) {
                case IMAGETYPE_JPEG:
                    return imagejpeg($rimage, $destination, $options['quality']);
                case IMAGETYPE_PNG:
                    return imagepng($rimage, $destination, 0);
                case IMAGETYPE_GIF:
                    return imagegif($rimage, $destination);
                case IMAGETYPE_BMP:
                    return imagejpeg($rimage, $destination, $options['quality']);
                default :
                    return false;
                    break;
            }
            return true;
            break;
        default :
            return false;
            break;
    }
}