首页 文章

计算用于调整大小的图像大小比率

提问于
浏览
42

我有一个定义的固定宽度和高度来调整图像大小 . 但是,我有这个问题,因为图像可以有任何类型的大小比例(它可以是 verticalhorizontal ) . 在这种情况下,固定的宽度和高度会引起问题 . 我想以更聪明的方式计算 width and height .

例如,假设我已经定义了 width 1024px and height 768px . 我想调整一个垂直的图像 (height 1100px and width 200px) . 所以在我的情况下它将调整为固定 size (1024x768) ,因此宽度将从 100px to 768px 增加,并且它将非常难看 . 同样,如果图像的高度小于 768px ,则会强制将高度增加到 768px .

因此,我想根据原始图像大小比率计算新的图像大小 . 让我们说如果上面的示例图像应该调整到 768px 的最大高度,但那么宽度呢?它已经小于我的"maximum width",这是 200px ,所以宽度应保持不变吗?还是应该进一步减少?

同样,如果图像有 the height 200px, and the width 1100px . 所以宽度应该是 decreased to 1024px ,但高度怎么样?

第三个问题是,让's suppose if both height and width are more than the maximum height and maximum width, let' s说 width: 1100px and height:4000px . 现在,由于宽度和高度都超过最大宽度和最大高度,但图像是垂直的,它将使其成为水平 . 那么如何在这种情况下检查是否应根据最大高度或根据最大宽度调整图像大小?

我很感激任何帮助 .

12 回答

  • 45

    这是有效的 .

    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);
        }
    
  • 0

    检查下面的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'>";
    
  • 0

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

    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));
    }
    
  • 0

    这是我个人抓取图像大小调整代码的代码 . 首先,您需要的数据:

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

    然后,此算法尽可能地将图像拟合到目标大小,保持原始宽高比,而不是将图像拉伸大于原始图像:

    $targetWidth = $targetHeight = min($size, max($originalWidth, $originalHeight));
    
    if ($ratio < 1) {
        $targetWidth = $targetHeight * $ratio;
    } else {
        $targetHeight = $targetWidth / $ratio;
    }
    
    $srcWidth = $originalWidth;
    $srcHeight = $originalHeight;
    $srcX = $srcY = 0;
    

    这会使图像完全填满目标尺寸,而不是拉伸它:

    $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;
    }
    

    而这实际上是调整大小:

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

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

  • 0
    $ratio = $originalWidth / $originalHeight
    

    如果你想改变高度:

    $targetWidth = $targetHeight * $ratio
    

    如果要更改宽度:

    $targetHeight = $targetWidth / $ratio
    
  • 0

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

    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)
    
  • 6

    我达成了这个问题并没有找到合适的答案,所以我自己开始回答这个问题 .

    我从一些基本的逻辑开始,在咨询了我的朋友,他在数学方面做得更好,这就是我们想出来的 .

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

    这段代码是可重用的,所以要把自己搞定 . 只需传递允许的最大最小尺寸,它就会计算出最大边的尺寸,这样你就可以得到一个正确缩放的尺寸,然后你可以在其中居中裁剪,从而产生正确缩小和裁剪的图像方形图像 . 这对于 Profiles 图片和缩略图等内容非常有用 .

    感谢我的朋友,Justin Gillett,因为他对交叉乘法的精彩建议 .

  • 68

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

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

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

    计算新图像的宽度和高度

    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;
    

    调整图像大小

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

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

    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;
        }    
    }
    
  • 1

    如果给出或不给出最大高度或宽度,使用@(jilles de wit)逻辑

    considerations : these should already be defined!

    $mh = given height limit; //optional
    $mw = given width limit; //optional
    
    $height = $nh =[your original height];
    $width = $nw =[your original width];
    

    代码

    if($mh || $mw){
    if(is_numeric($mh)){$h_fact = $mh / $nh;}
    if(is_numeric($mw)){$v_fact = $mw / $nw;}
    
    if(is_numeric($v_fact) && is_numeric($h_fact)  ){$im_fact = min($v_fact, $h_fact);}else{$im_fact=is_numeric($v_fact)?$v_fact:$h_fact;}
    $nw = $nw * $im_fact;
    $nh = $nh * $im_fact;
    }
    

    resampling

    $dst_img = imagecreatetruecolor($nw,$nh);
    imagecopyresampled ($dst_img, $image, 0, 0, 0, 0, $nw, $nh, $width , $height);
    
  • 12
    class Image_Aspect_Ratio_Resize {
    var $image_to_resize;
    var $new_width;
    var $new_height;
    var $ratio;
    var $new_image_name;
    var $save_folder;
    
    function resize() {
        if (!file_exists($this->image_to_resize)) {
            exit("File " . $this->image_to_resize . " does not exist.");
        }
    
        $info = GetImageSize($this->image_to_resize);
    
        if (empty($info)) {
            exit("The file " . $this->image_to_resize . " doesn't seem to be an image.");
        }
    
        $width = $info[0];
        $height = $info[1];
        $mime = $info['mime'];
    
        /* Keep Aspect Ratio? */
    
        if ($this->ratio) {
            $thumb = ($this->new_width < $width && $this->new_height < $height) ? true : false; // Thumbnail
            $bigger_image = ($this->new_width > $width || $this->new_height > $height) ? true : false; // Bigger Image
    
            if ($thumb) {
                if ($this->new_width >= $this->new_height) {
                    $x = ($width / $this->new_width);
    
                    $this->new_height = ($height / $x);
                } else if ($this->new_height >= $this->new_width) {
                    $x = ($height / $this->new_height);
    
                    $this->new_width = ($width / $x);
                }
            } else if ($bigger_image) {
                if ($this->new_width >= $width) {
                    $x = ($this->new_width / $width);
    
                    $this->new_height = ($height * $x);
                } else if ($this->new_height >= $height) {
                    $x = ($this->new_height / $height);
    
                    $this->new_width = ($width * $x);
                }
            }
        }
    
    
        $type = substr(strrchr($mime, '/'), 1);
    
        switch ($type) {
            case 'jpeg':
                $image_create_func = 'ImageCreateFromJPEG';
                $image_save_func = 'ImageJPEG';
                $new_image_ext = 'jpg';
                break;
    
            case 'png':
                $image_create_func = 'ImageCreateFromPNG';
                $image_save_func = 'ImagePNG';
                $new_image_ext = 'png';
                break;
    
            case 'bmp':
                $image_create_func = 'ImageCreateFromBMP';
                $image_save_func = 'ImageBMP';
                $new_image_ext = 'bmp';
                break;
    
            case 'gif':
                $image_create_func = 'ImageCreateFromGIF';
                $image_save_func = 'ImageGIF';
                $new_image_ext = 'gif';
                break;
    
            case 'vnd.wap.wbmp':
                $image_create_func = 'ImageCreateFromWBMP';
                $image_save_func = 'ImageWBMP';
                $new_image_ext = 'bmp';
                break;
    
            case 'xbm':
                $image_create_func = 'ImageCreateFromXBM';
                $image_save_func = 'ImageXBM';
                $new_image_ext = 'xbm';
                break;
    
            default:
                $image_create_func = 'ImageCreateFromJPEG';
                $image_save_func = 'ImageJPEG';
                $new_image_ext = 'jpg';
        }
    
        // New Image
        $image_c = ImageCreateTrueColor($this->new_width, $this->new_height);
    
        $new_image = $image_create_func($this->image_to_resize);
    
        ImageCopyResampled($image_c, $new_image, 0, 0, 0, 0, $this->new_width, $this->new_height, $width, $height);
    
        if ($this->save_folder) {
            if ($this->new_image_name) {
                $new_name = $this->new_image_name . '.' . $new_image_ext;
            } else {
                $new_name = $this->new_thumb_name(basename($this->image_to_resize)) . '_resized.' . $new_image_ext;
            }
    
            $save_path = $this->save_folder . $new_name;
        } else {
            /* Show the image without saving it to a folder */
            header("Content-Type: " . $mime);
    
            $image_save_func($image_c);
    
            $save_path = '';
        }
    
        $process = $image_save_func($image_c, $save_path);
    
        return array('result' => $process, 'new_file_path' => $save_path);
    }}
    

    / 函数调用 /

    $resize_image = new Image_Aspect_Ratio_Resize;
    $new_width = (int) $_POST['new_width'];
    $new_height = (int) $_POST['new_height'];
    $resize_image->new_width = $new_width;
    $resize_image->new_height = $new_height;
    $resize_image->image_to_resize = $image; // Full Path to the file
    $resize_image->ratio = true; // Keep aspect ratio
    // Name of the new image (optional) - If it's not set a new will be added automatically
    $resize_image->new_image_name = 'water_lilies_thumbnail';
    /* Path where the new image should be saved. If it's not set the script will output the image without saving it */
    $resize_image->save_folder = 'thumbs/';
    $process = $resize_image->resize(); // Output image
    
  • 0

    你需要的是'maintain'的宽高比 . 最初你有一个大小(wxh) 500x1000 的图像,这个宽高比是 0.5 . 假设您正在将 1000 更改为 768 高度,则结果宽度将为 0.5 * 768 = 384 .

    另一个例子, 1800 x 1200 和你的新高度是 200 ,那么你的新宽度是 300 因为 300/2001.51800/1200 也是 1.5 .

    祝好运 .

  • 0

    这个怎么样:

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

相关问题