php 计算图像大小比例以调整大小

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6594089/
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-26 00:49:12  来源:igfitidea点击:

Calculating image size ratio for resizing

phpimageimage-processingresize

提问by sunjie

I have a defined fixed width and height to resize an image. However, I have problem a with this, because the image can have any kind of size ratio (it can be verticalor the horizontal). In this case, fixed width and height cause a problem. I want to calculate width and heightin a smarter way.

我有一个定义的固定宽度和高度来调整图像大小。但是,我对此有疑问,因为图像可以具有任何类型的大小比例(可以是垂直水平)。在这种情况下,固定宽度和高度会导致问题。我想以更智能的方式计算宽度和高度

For example lets say I have defined width 1024px and height 768px. And I want to resize an image which is vertical (height 1100px and width 200px). So in my case it will resize to fixed size (1024x768), so the width will be increased from 100px to 768px, and it will be very ugly. Similarly if the image has height less than 768px, it will increase the height by force to 768px.

例如,假设我定义了宽度 1024px 和高度 768px。我想调整垂直图像的大小(高度 1100 像素和宽度 200 像素)。所以在我的例子中它会调整到固定大小 (1024x768),所以宽度会从100px 增加到 768px,它会非常难看。同样,如果图像的高度小于768px,它会强制将高度增加到768px

Therefore I would like to calculate the new image size based on the original image size ratio. Lets say if the above example image should be resized to maximum height of 768px, but then what about the width? it's already less than my "maximum width", which is 200px, so should the width remain unchanged? or should it be further decreased?

因此,我想根据原始图像大小比率计算新图像大小。假设上面的示例图像是否应该调整为最大高度768px,那么宽度呢?它已经小于我的“最大宽度”,即200px,那么宽度应该保持不变吗?还是应该进一步减少?

Similarly, if the image has the height 200px, and the width 1100px. So the width should be decreased to 1024px, but what about the height?

同样,如果图像的高度为 200px,宽度为 1100px。所以宽度应该减少到 1024px,但是高度呢?

The third problem is that, let's suppose if both height and width are more than the maximum height and maximum width, let's say width: 1100px and height:4000px. Now since width and height both are more than the maximum width and maximum height but the image is vertical, it will make it horizontal. So how can I check if in this case if I should resize the image according to maximum height, or according to maximum width?

第三个问题是,假设如果高度和宽度都大于最大高度和最大宽度,我们说width: 1100px 和 height:4000px。现在由于宽度和高度都大于最大宽度和最大高度,但图像是垂直的,它将使其水平。那么如何检查在这种情况下是否应该根据最大高度或最大宽度调整图像大小?

I appreciate any help with this.

我很感激这方面的任何帮助。

回答by deceze

Here's code from my personal grab bag of image resizing code. First, data you need:

这是我个人抓包的图像大小调整代码中的代码。首先,你需要的数据:

list($originalWidth, $originalHeight) = getimagesize($imageFile);
$ratio = $originalWidth / $originalHeight;

Then, this algorithm fits the image into the target size as best it can, keeping the original aspect ratio, not stretching the image larger than the original:

然后,该算法尽可能地将图像拟合到目标尺寸,保持原始纵横比,而不是将图像拉伸得大于原始图像:

$targetWidth = $targetHeight = min($size, max($originalWidth, $originalHeight));

if ($ratio < 1) {
    $targetWidth = $targetHeight * $ratio;
} else {
    $targetHeight = $targetWidth / $ratio;
}

$srcWidth = $originalWidth;
$srcHeight = $originalHeight;
$srcX = $srcY = 0;

This crops the image to fill the target size completely, not stretching it:

这将裁剪图像以完全填充目标尺寸,而不是拉伸它:

$targetWidth = $targetHeight = min($originalWidth, $originalHeight, $size);

if ($ratio < 1) {
    $srcX = 0;
    $srcY = ($originalHeight / 2) - ($originalWidth / 2);
    $srcWidth = $srcHeight = $originalWidth;
} else {
    $srcY = 0;
    $srcX = ($originalWidth / 2) - ($originalHeight / 2);
    $srcWidth = $srcHeight = $originalHeight;
}

And this does the actual resizing:

这是实际调整大小:

$targetImage = imagecreatetruecolor($targetWidth, $targetHeight);
imagecopyresampled($targetImage, $originalImage, 0, 0, $srcX, $srcY, $targetWidth, $targetHeight, $srcWidth, $srcHeight);

In this case the $sizeis just one number for both width and height (square target size). I'm sure you can modify it to use non-square targets. It should also give you an inspiration on what other resizing algorithms you can use.

在这种情况下,$size宽度和高度(方形目标尺寸)只有一个数字。我确定您可以修改它以使用非方形目标。它还应该为您提供可以使用的其他调整大小算法的灵感。

回答by Mehran - Persian

$ratio = $originalWidth / $originalHeight

if you want to change the Height:

如果你想改变高度:

$targetWidth = $targetHeight * $ratio

if you want to change the Width:

如果要更改宽度:

$targetHeight = $targetWidth / $ratio

回答by jilles de wit

What you want is to maintain the aspect ratio of your original image. This is the ratio between the width and the height of the image. So you calculate the factor by which you have to resize the image in the vertical and horizontal direction and then you keep the higher of the two. In pseudocode:

您想要的是保持原始图像的纵横比。这是图像的宽度和高度之间的比率。因此,您计算必须在垂直和水平方向上调整图像大小的因子,然后保持两者中较高的一个。在伪代码中:

target_height = 768
target_width = 1024
# v_fact and h_fact are the factor by which the original vertical / horizontal
# image sizes should be multiplied to get the image to your target size.
v_fact = target_height / im_height 
h_fact = target_width / im_width
# you want to resize the image by the same factor in both vertical 
# and horizontal direction, so you need to pick the correct factor from
# v_fact / h_fact so that the largest (relative to target) of the new height/width
# equals the target height/width and the smallest is lower than the target.
# this is the lowest of the two factors
im_fact = min(v_fact, h_fact)
new_height = im_height * im_fact
new_width = im_width * im_fact
image.resize(new_width, new_height)

回答by kestas

this is working.

这是工作。

function calculateDimensions($width,$height,$maxwidth,$maxheight)
{

        if($width != $height)
        {
            if($width > $height)
            {
                $t_width = $maxwidth;
                $t_height = (($t_width * $height)/$width);
                //fix height
                if($t_height > $maxheight)
                {
                    $t_height = $maxheight;
                    $t_width = (($width * $t_height)/$height);
                }
            }
            else
            {
                $t_height = $maxheight;
                $t_width = (($width * $t_height)/$height);
                //fix width
                if($t_width > $maxwidth)
                {
                    $t_width = $maxwidth;
                    $t_height = (($t_width * $height)/$width);
                }
            }
        }
        else
            $t_width = $t_height = min($maxheight,$maxwidth);

        return array('height'=>(int)$t_height,'width'=>(int)$t_width);
    }

回答by Wayne

Check the php code below :

检查下面的php代码:

$new_width  = 1024;
$new_height = 768;
$this_image = "images/my_image";

list($width, $height, $type, $attr) = getimagesize("$this_image");

if ($width > $height) {
  $image_height = floor(($height/$width)*$new_width);
  $image_width  = $new_width;
} else {
  $image_width  = floor(($width/$height)*$new_height);
  $image_height = $new_height;
}
echo "<img src='$this_image' height='$image_height' width='$image_width'>";

回答by Gary Tsui

What you need is to 'maintain' the width/height ratio. Originally you have an image of size (wxh) 500x1000, this width/height ratio is 0.5. Assuming you are changing 1000to 768in height, your result width would be 0.5 * 768 = 384.

您需要的是“保持”宽高比。最初你有一个大小为 (wxh) 的图像500x1000,这个宽/高比是0.5. 假设您要更改1000768高度,则结果宽度将为0.5 * 768 = 384.

Another example, 1800 x 1200and your newheight is 200, then your newwidth is 300because 300/200is 1.5and 1800/1200is also 1.5.

另一个例子,1800 x 1200你的高度是200,那么你的宽度是300因为300/2001.5并且1800/1200也是1.5

Good luck.

祝你好运。

回答by Yaza

How about this:

这个怎么样:

double ratio = imageWidth/imageHeight;
int newHeight = Math.min(displayHeight, displayWidth / ratio); 
int newWidth =  Math.min(displayWidth, displayHeight * ratio); 

回答by r3wt

I reached this question and didn't find a suitable answer, so i set out on my own to answer the question.

我找到了这个问题,但没有找到合适的答案,所以我自己开始回答这个问题。

i started with some basic logic, and after consulting a friend of mine who is a bit better at math, this is what we came up with.

我从一些基本的逻辑开始,在咨询了我的一个数学更好的朋友之后,这就是我们想出的。

function calculate_dimensions($width,$height,$max){
    if($width != $height){
        if($width > $height){
            $t_height = $max;
            $t_width = min(($width * $t_height)/$height);
        }
        if($height > $width){
            $t_width = $max;
            $t_height = min(($t_width * $height)/$width)
        }
    }else{
        if($width > $max){
            $t_width = $t_height = $max;
        }
    }
    $res = ['height'=>$t_height,'width'=>$t_width]
    return $res;
}

This snippet of code is reusable, so knock yourself out. just pass it the maximum smallest dimension allowed, and it will calculate the largest side's dimension, so you will get back a correctly scaled dimension, in which you can then center crop, resulting in a correctly shrinked and cropped image square image. this is useful for things like profile pictures and thumbnails.

这段代码是可重用的,所以请自重。只需将允许的最大最小尺寸传递给它,它将计算最大边的尺寸,因此您将获得正确缩放的尺寸,然后您可以在其中居中裁剪,从而产生正确缩小和裁剪的图像方形图像。这对于个人资料图片和缩略图等内容很有用。

credit to my friend, Justin Gillettfor his brilliant suggestion of cross multiplication.

感谢我的朋友Justin Gillett提出的交叉乘法的绝妙建议。

回答by Sascha Galley

You should resize it depending on what property is farer away from the maximum value. Then, calculate the ratio.

您应该根据哪个属性远离最大值来调整它的大小。然后,计算比率。

if(($w - $w_max) > ($h - $h_max)) {
    $w_new = $w_max;
    $h_new = (int) ($h * ($w_max / $w));
}
else {
    $h_new = $h_max;
    $w_new = (int) ($w * ($h_max / $h));
}

回答by JPickup

This example will shrink an image to fit a defined pixel perfect aspect ratio ( 16:9 ) creating an image no larger than a specified limit ( 1200 x 675 ).

此示例将缩小图像以适应定义的像素完美纵横比 (16:9),创建不大于指定限制 (1200 x 675) 的图像。

Set your image ratio and any upper limit:

设置您的图像比例和任何上限:

const RATIO_W                       = 16;
const RATIO_H                       = 9;
const RATIO_MULIPLIER_UPPER_LIMIT   = 75;

Calculate the new image width and height

计算新的图像宽度和高度

list($imageWidth, $imageHeight) = getimagesize($path_to_image);    

if( ($imageWidth / $imageHeight) === (self::RATIO_W / self::RATIO_H) ){
    return;

// Find closest ratio multiple to image size
if($imageWidth > $imageHeight){
    // landscape
    $ratioMultiple  = round($imageHeight / self::RATIO_H, 0, PHP_ROUND_HALF_DOWN);
}else{
    // portrait
    $ratioMultiple  = round($imageWidth / self::RATIO_W, 0, PHP_ROUND_HALF_DOWN);
}    

$newWidth   = $ratioMultiple * self::RATIO_W;
$newHeight = $ratioMultiple * self::RATIO_H;    

if($newWidth > self::RATIO_W * self::RATIO_MULIPLIER_UPPER_LIMIT|| $newHeight > self::RATIO_H * self::RATIO_MULIPLIER_UPPER_LIMIT){
    // File is larger than upper limit
    $ratioMultiple = self::RATIO_MULIPLIER_UPPER_LIMIT;
}    

$this->tweakMultiplier($ratioMultiple, $imageWidth, $imageHeight);    

$newWidth   = $ratioMultiple * self::RATIO_W;
$newHeight = $ratioMultiple * self::RATIO_H;    

Resize image

调整图像大小

$originalImage  = imagecreatefromjpeg( $tempImagePath );
$newImage       = imagecreatetruecolor($newWidth, $newHeight);
imagefilledrectangle($newImage, 0, 0, $newWidth, $newHeight, imagecolorallocate($newImage, 255, 255, 255));
imagecopyresampled($newImage, $originalImage, 0, 0, 0, 0, $newWidth, $newHeight, $imageWidth, $imageHeight);
imagejpeg($newImage, $tempImagePath, 100);

Loop through factors until both dimensions are less than the original image size

循环遍历因子,直到两个维度都小于原始图像大小

protected function tweakMultiplier( &$ratioMultiple, $fitInsideWidth, $fitInsideHeight ){
    $newWidth   = $ratioMultiple * self::RATIO_W;
    $newHeight  = $ratioMultiple * self::RATIO_H;    

    if($newWidth > $fitInsideWidth || $newHeight > $fitInsideHeight){
        echo " Tweak ";
        $ratioMultiple--;
        $this->tweakMultiplier($ratioMultiple, $fitInsideWidth, $fitInsideHeight);
    }else{
        return;
    }    
}