PHP 缩略图按比例调整大小

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4590441/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 13:36:31  来源:igfitidea点击:

PHP Thumbnail Image Resizing with proportions

phpimage-processingresizethumbnailsautoresize

提问by Sam

As a brief run down, I am currently making a dating type site. Users can create accounts and upload profile pictures (up to 8). In order to display these in the browse area of the website, I am looking for a way in PHP (with third party processor/scripts) to resize all images uploaded to have thumbnails that adhere to certain dimensions.

简而言之,我目前正在制作一个约会类型的网站。用户可以创建帐户并上传个人资料图片(最多 8 张)。为了在网站的浏览区域中显示这些内容,我正在寻找一种在 PHP(使用第三方处理器/脚本)中调整上传的所有图像大小以具有符合特定尺寸的缩略图的方法。

As an example, I will want "profile" images (thumbnails) to be NO larger than 120*150px. The scripting needs to resize uploaded images (regardless of whether they are portrait or landscape, and regardless of proportions) to adhere to these dimensions without getting stretched.

例如,我希望“个人资料”图像(缩略图)不大于 120*150 像素。脚本需要调整上传图像的大小(无论它们是纵向还是横向,也不管比例)以符合这些尺寸而不会被拉伸。

The width (eg. 120pixels) should always remain the same, but the height (eg. 150px) can vary in order to keep the image in proportion. If it's a landscape photo, I'm assuming the script would need to take a chunk out of the middle of the image?

宽度(例如 120 像素)应始终保持不变,但高度(例如 150 像素)可以变化以保持图像的比例。如果是风景照片,我假设脚本需要从图像中间取出一大块?

The reason that all images to be resized is so that when profiles are display in a grid that all thumbnails are roughly the same size.

要调整所有图像大小的原因是,当配置文件显示在网格中时,所有缩略图的大小大致相同。

Any input would be greatly appreciated.

任何投入将不胜感激。

回答by Phoenix

$maxwidth = 120;
$maxheight = 150;

$img = imagecreatefromjpeg($jpgimage); 
//or imagecreatefrompng,imagecreatefromgif,etc. depending on user's uploaded file extension

$width = imagesx($img); //get width and height of original image
$height = imagesy($img);

//determine which side is the longest to use in calculating length of the shorter side, since the longest will be the max size for whichever side is longest.    
if ($height > $width) 
{   
$ratio = $maxheight / $height;  
$newheight = $maxheight;
$newwidth = $width * $ratio; 
}
else 
{
$ratio = $maxwidth / $width;   
$newwidth = $maxwidth;  
$newheight = $height * $ratio;   
}

//create new image resource to hold the resized image
$newimg = imagecreatetruecolor($newwidth,$newheight); 

$palsize = ImageColorsTotal($img);  //Get palette size for original image
for ($i = 0; $i < $palsize; $i++) //Assign color palette to new image
{ 
$colors = ImageColorsForIndex($img, $i);   
ImageColorAllocate($newimg, $colors['red'], $colors['green'], $colors['blue']);
} 

//copy original image into new image at new size.
imagecopyresized($newimg, $img, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);

imagejpeg($newimg,$outputfile); //$output file is the path/filename where you wish to save the file.  
//Have to figure that one out yourself using whatever rules you want.  Can use imagegif() or imagepng() or whatever.

This will shrink any images down proportionally based on whichever side is longer (width or height), to the maximum size. It will also blow up any images smaller than max, which you can stop with a bit of checking on whether or not both width and height are less than their max. So, a 200x300 image will be shrunk to 100x150, and a 300x200 image will be shrunk to 120x80.

这将根据较长的一侧(宽度或高度)按比例缩小任何图像,以达到最大尺寸。它还会炸毁任何小于最大值的图像,您可以通过检查宽度和高度是否都小于它们的最大值来停止。因此,200x300 的图像将缩小为 100x150,而 300x200 的图像将缩小为 120x80。

Hmm, you want the width to always be 120, so it would change a bit, and yeah, it would have to cut something out in the case of an image like 200x300, because that would shrink to 120x180 without any distortion, or it would have to shrink it farther and letterbox it, but that should get you started nicely.

嗯,你希望宽度总是 120,所以它会改变一点,是的,在像 200x300 这样的图像的情况下,它必须剪掉一些东西,因为它会缩小到 120x180 而没有任何失真,否则它会必须进一步缩小它并将其放入信箱中,但这应该可以让您很好地开始。

Letterboxing this example would just involve figuring out what the proper x and y to start the drawing to the new image would be in the imagecopyresized() function. In the case of something like 100x150, the X would be 10, I think, so there would be 10px of blank space on each side for 120x150 in the end. Letterboxing 120x80 X would be 0 but Y would be 35, so there would be 35px of blank space above and below for 120x150.

这个例子只需要弄清楚在 imagecopyresized() 函数中开始绘制新图像的正确 x 和 y 是什么。在像 100x150 这样的情况下,我认为 X 将是 10,所以最终 120x150 的每一边都会有 10px 的空白空间。Letterboxing 120x80 X 将是 0 但 Y 将是 35,因此对于 120x150,上下会有 35px 的空白空间。

You'd also want to make $newimg with $maxwidth,$maxheight rather than $newwidth,$newheight, but the imagecopyresized() would still use both $new values.

您还希望使用 $maxwidth,$maxheight 而不是 $newwidth,$newheight 来制作 $newimg,但 imagecopyresized() 仍会同时使用这两个 $new 值。

Since I'm bored and don't have anything else to do, these changes would do it:

由于我很无聊并且无事可做,因此这些更改可以做到:

if ($height > $width) 
{   
$ratio = $maxheight / $height;  
$newheight = $maxheight;
$newwidth = $width * $ratio; 
$writex = round(($maxwidth - $newwidth) / 2);
$writey = 0;
{
else 
{
$ratio = $maxwidth / $width;   
$newwidth = $maxwidth;  
$newheight = $height * $ratio;   
$writex = 0;
$writey = round(($maxheight - $newheight) / 2);
}

$newimg = imagecreatetruecolor($maxwidth,$maxheight);

//Since you probably will want to set a color for the letter box do this
//Assign a color for the letterbox to the new image, 
//since this is the first call, for imagecolorallocate, it will set the background color
//in this case, black rgb(0,0,0)
imagecolorallocate($newimg,0,0,0);

//Loop Palette assignment stuff here

imagecopyresized($newimg, $img, $writex, $writey, 0, 0, $newwidth, $newheight, $width, $height);

That should work, haven't tried it yet.

应该可以,还没试过。

回答by Nabab

GDor Imagick functions are what you need depending on your PHP configuration.
Sorry I'm a newbie I can't post both links in the same message :(

GD或 Imagick 函数是您需要的,具体取决于您的 PHP 配置。
抱歉,我是新手,无法在同一条消息中同时发布两个链接:(

回答by Eren T.

I have recently needed php resizing (thumbnail) solution and found Zebra_Image library, which is a lightweight image manipulation library written in PHP. The code is really clean and it's also easy to use. I highly recommend using this library. The example code is just enough to get you started.

我最近需要 php 调整大小(缩略图)解决方案,并找到了Zebra_Image 库,这是一个用 PHP 编写的轻量级图像处理库。代码真的很干净,也很容易使用。我强烈推荐使用这个库。示例代码足以让您入门。

Be make sure that you have enough memory limit set in php.ini file to manipulate images which have relatively big resolution (e.g 2560x1600). I had an error with big images and there was no error to print. I debugged the problem down to imagecreatefrom{gif,jpeg,png}calls in function _create_from_sourcein lines 1262, 1279, and 1288. The calls were silented with @ so I couldn't have a change to get the error. I removed @ lines and saw a PHP error that memory limit has been exceeded. The original memory limit was set to 32MB and I increased it to 64MB. Now I can manipulate 2560x1600 and I refuse to manipulate images which are bigger.

请确保您在 php.ini 文件中设置了足够的内存限制来处理分辨率相对较大(例如 2560x1600)的图像。我在处理大图像时出现错误,并且没有打印错误。我将问题调试到第126212791288行中的imagecreatefrom{gif,jpeg,png}调用。呼叫被@静音,因此我无法更改以获取错误。我删除了 @ 行并看到一个 PHP 错误,表明已超出内存限制。最初的内存限制设置为 32MB,我将其增加到 64MB。现在我可以操作 2560x1600 并且我拒绝操作更大的图像。function _create_from_source

Below is the example code for controlling the image resolution.

下面是控制图像分辨率的示例代码。

    $image_properties = getimagesize($UPLOADED_FILE_PATH);                   
    $file_width = $image_properties[0];                                
    $file_height = $image_properties[1];                               

    if ($file_width > 2560 || $file_height > 1600) {    
        // handle your error whichever you like, I simply 'die' just to show               
        die('Cannot manipulate image bigger than 2560x1600');                                                                                                                                              
    }       

(Note: I use Zebra Image version 2.2.2)

(注意:我使用的是 Zebra Image 2.2.2 版)

回答by Dmitry Zalivadny

Some says imagic faster, i use next

有人说想象更快,我用下一个

    
    function resizeImageProportional($imagePath, $destinationPath, $width = false, $height = false, $filterType = \Imagick::FILTER_POINT, $blur = 1, $bestFit = false, $cropZoom = false)
    {
        if (!$width && !$height) {
            trigger_error("WTF_IMAGE_RESIZE");
            return false;
        }
        //The blur factor where > 1 is blurry, < 1 is sharp.
        $imagick = new \Imagick(realpath($imagePath));

if (!$width || !$height) { $orig_width = $imagick->getImageWidth(); $orig_height = $imagick->getImageHeight(); $proportion = $orig_height/$orig_width; if (!$width) { $width = $height*$proportion; } elseif (!$height) { $height = $width*$proportion; } } if ($bestFit) { $imagick->resizeImage($width, $height, $filterType, $blur, $bestFit); } else { $imagick->resizeImage($width, $height, $filterType, $blur); } if ($cropZoom) { $cropWidth = $imagick->getImageWidth(); $cropHeight = $imagick->getImageHeight(); $newWidth = $cropWidth / 2; $newHeight = $cropHeight / 2; $imagick->cropimage( $newWidth, $newHeight, ($cropWidth - $newWidth) / 2, ($cropHeight - $newHeight) / 2 ); $imagick->scaleimage( $imagick->getImageWidth() * 4, $imagick->getImageHeight() * 4 ); }

回答by dqhendricks

you don't need imagick. here is a link that will take you to a function that will resize any image using PHP GD to any arbitrary size. the function has options to use letterboxing or crop-to-fit methods to resize to the new aspect ratio. the function is also explained thoroughly. check it out.

你不需要 imagick。这是一个链接,可将您带到一个函数,该函数将使用 PHP GD 将任何图像调整为任意大小。该函数可以选择使用信箱或裁剪以适应新的纵横比。该功能也得到了彻底的解释。一探究竟。

http://www.spotlesswebdesign.com/blog.php?id=1

http://www.spotlesswebdesign.com/blog.php?id=1

if this is what you are looking for, please select the check mark next to this answer. thanks!

如果这是您要查找的内容,请选中此答案旁边的复选标记。谢谢!

回答by Ben

You can do this with ImageMagick:

你可以用ImageMagick做到这一点:

convert susan.jpg -resize x200 susan_thumb.jpg

This runs with a shell command, so in PHP you'd use shell_exec()to run the above command. I don't think you need any PHP extensions.

这使用 shell 命令运行,因此在 PHP 中您将用于shell_exec()运行上述命令。我认为您不需要任何 PHP 扩展。

A few flags can be found in the ImageMagick documentation to control the resizing operation. If I recall correctly, the x200before the number means "scale with the same aspect ratio to 200px".

在 ImageMagick 文档中可以找到一些标志来控制调整大小操作。如果我没记错的话,x200数字之前的意思是“以相同的纵横比缩放到 200 像素”。

I wrote an install guide for ImageMagick (and ghostscript): How to install, test, convert, resize PDF using ImageMagick, Ghostscript, Windows Vista/7 x64based on my bumbling around, maybe it can help you.

我写了一个 ImageMagick(和 ghostscript)的安装指南:根据我的笨拙,如何使用 ImageMagick、Ghostscript、Windows Vista/7 x64 安装、测试、转换、调整 PDF 大小,也许它可以帮助你。

The other option is the GD library (detailed in dqhendricks answer). This is faster and apparently better documented, used for basic operations.

另一个选项是 GD 库(在 dqhendricks 回答中有详细说明)。这更快,显然更好地记录,用于基本操作。