PHP将图像转换为特定的高度和宽度而不拉伸

时间:2017-10-03 19:47:40

标签: php image

我正在尝试制作我躺在身边的图像缩略图。它们有各种各样的分辨率,但我想创建尺寸为225 x 150的缩略图。我一直试图做的是直接转换宽度或高度(取决于最佳效果)并使用原始图像的居中部分。对于某些图像,它可以正常工作,但对于其他图像,它可能会非常糟糕。

我想做的事情之间的直接逻辑:

if the width is fine, and the height is big:
   use the width as is
   calculate height - the height which would go with width for the thumbnail ratio.
else
    use the height as is
    calculate width - the width which would go with height for the thumbnail ratio

这将给出未使用的图像部分。它用作x和y偏移量。我还减小了所用图像部分的大小。

我有一个用于缩略图的功能,但我不确定比率与实际宽度和高度之间的关系:

function shrinkImage( $owidth, $oheight, $filename, $newFile ) {
    if ( ($img_info = getimagesize( $filename ) ) === FALSE) {
        die("Image not found or not an image");
    }

    switch ( $img_info[2] ) {
        case IMAGETYPE_GIF  :
            $image = imagecreatefromgif( $filename);
            break;
        case IMAGETYPE_JPEG :
            $image = imagecreatefromjpeg( $filename );
            break;
        case IMAGETYPE_PNG  :
            $image = imagecreatefrompng( $filename );
            break;
        default :
            die( "Unknown filetype" );
    }

    $thumb_width = 225;
    $thumb_height = 150;

    if( ($oheight/$thumb_height) < ($owidth/$thumb_width) ) {
        $y = 0;
        $x = $owidth - ($oheight * $thumb_width / $thumb_height);
    } else {
        $x = 0;
        $y = $oheight - (($owidth * $thumb_height) / $thumb_width);
    }

    $thumb = imagecreatetruecolor( $thumb_width, $thumb_height );
    imagecopyresampled( $thumb, $image, 0, 0, $x, $y, $thumb_width, $thumb_height, $owidth - ($x * 2), $oheight - ($y * 2));

    switch ( $img_info[2] ) {
        case IMAGETYPE_GIF  :
            imagegif( $thumb,  $newFile );
            break;
        case IMAGETYPE_JPEG :
            imagejpeg( $thumb, $newFile, 100 );
            break;
        case IMAGETYPE_PNG  :
            imagepng($thumb,  $newFile, 0 );
            break;
        default :
            die("Unknown filetype");
    }
    return True;
}

以下是原始图片与裁剪图片的示例: The original image The cropped image

这不是我的代码产生的缩略图,而是我想要它做的一个例子。

修改

if( ($oheight/$thumb_height) < ($owidth/$thumb_width) ) {
    $y = 0;
    $x = $owidth - ($oheight * $thumb_width / $thumb_height);
} else {
    $x = 0;
    $y = $oheight - ($owidth * $thumb_height / $thumb_width * 2);
}

适用于高大的图像和一些普通图像,但会为宽图像创建一些可怕的线条。A sample of code result

1 个答案:

答案 0 :(得分:1)

在挖掘了一些长期失去的数学知识之后,我找到了一个有效的解决方案:

    $thumb_width = 225;
    $thumb_height = 150;

    if( ($owidth/$thumb_width) > ($oheight/$thumb_height) ) {
        $y = 0;
        $x = $owidth - ( ($oheight * $thumb_width) / $thumb_height);
    } else {
        $x = 0;
        $y = $oheight - ( ($owidth * $thumb_height) / $thumb_width);
    }

    $thumb = imagecreatetruecolor( $thumb_width, $thumb_height );
    imagecopyresampled( $thumb, $image, 0, 0, $x/2, $y/2, $thumb_width, $thumb_height, $owidth - $x, $oheight - $y);