Php 在考虑比率的情况下,找到最大的放大尺寸

Php 在考虑比率的情况下,找到最大的放大尺寸,php,math,resize,Php,Math,Resize,我和一所大学正在尝试建立一种方法,可以找到默认显示在图像中的选择的最大大小。选择是有一个比率 到目前为止,我们一直在尝试: public function findBestSizeForRatio($inputW, $inputH, $ratioW, $ratioH) { if($inputW / $ratioW > $ratioH / $inputH){ $w = floor($inputW / $ratioW) * $ratioW; $h = $

我和一所大学正在尝试建立一种方法,可以找到默认显示在图像中的选择的最大大小。选择是有一个比率

到目前为止,我们一直在尝试:

public function findBestSizeForRatio($inputW, $inputH, $ratioW, $ratioH)
{
    if($inputW / $ratioW > $ratioH / $inputH){
        $w = floor($inputW / $ratioW) * $ratioW;
        $h = $w * $ratioH / $ratioW;
    }
    else{
        $h = floor($inputH / $ratioH) * $ratioH;
        $w = $h * $ratioW / $ratioH;
    }

    return array($w, $h);
}
public function findBestSizeForRatio($inputW, $inputH, $ratioW, $ratioH)
{
     return $this->findBestSizeInBox($ratioW*10000, $ratioH*10000, $inputW, $inputH);
}
public function findBestSizeInBox($inputW, $inputH, $boxW, $boxH)
{
    if($inputW / $boxW > $inputH / $boxH){
        return array($boxW, round($inputH * $boxW / $inputW));
    }
    else{
        return array(round($inputW * $boxH / $inputH), $boxH);
    }
}
但是它没有通过我们的单元测试

我们也尝试过:

public function findBestSizeForRatio($inputW, $inputH, $ratioW, $ratioH)
{
    if($inputW / $ratioW > $ratioH / $inputH){
        $w = floor($inputW / $ratioW) * $ratioW;
        $h = $w * $ratioH / $ratioW;
    }
    else{
        $h = floor($inputH / $ratioH) * $ratioH;
        $w = $h * $ratioW / $ratioH;
    }

    return array($w, $h);
}
public function findBestSizeForRatio($inputW, $inputH, $ratioW, $ratioH)
{
     return $this->findBestSizeInBox($ratioW*10000, $ratioH*10000, $inputW, $inputH);
}
public function findBestSizeInBox($inputW, $inputH, $boxW, $boxH)
{
    if($inputW / $boxW > $inputH / $boxH){
        return array($boxW, round($inputH * $boxW / $inputW));
    }
    else{
        return array(round($inputW * $boxH / $inputH), $boxH);
    }
}
它似乎可以工作,但不是像素级的完美。因为我们的比率是由小数字组成的,所以我们需要一种真正尊重比率的方法,即使图像不是100%填充的。对*10000这样的常量进行硬编码也是非常愚蠢的,因为我们无法找到一个好的数学公式

我们还构建了那些PHPUnit测试,这些测试对我们来说似乎具有代表性(因此我们可能忘记了一些案例)


任何能够通过所有测试的解决方案?

让我确定我有这个权利。您需要拍摄一张图像,并拍摄最大的一块图像,这是一个具有指定高宽比的矩形

在这种情况下,请记住单元测试也是代码的规则。当您的单元测试失败时,甚至有可能是单元测试中的错误。考虑到这一点,您的单元测试看起来是错误的。例如,以4为例。533/400不是精确的4/3比率。有了这个确切的比例,最好的答案是532/399

如果你愿意放松比率的精确性,那么你应该采取如下措施:

public function findBestSizeForRatio($inputW, $inputH, $ratioW, $ratioH)
{
    if($inputW / $ratioW > $ratioH / $inputH){
        $w = $inputW;
        $h = round($w * $ratioH / $ratioW);
    }
    else{
        $h = $inputH;
        $h = round($h * $ratioW / $ratioH);
    }

    return array($w, $h);
}

让我确定我有这个权利。您需要拍摄一张图像,并拍摄最大的一块图像,这是一个具有指定高宽比的矩形

在这种情况下,请记住单元测试也是代码的规则。当您的单元测试失败时,甚至有可能是单元测试中的错误。考虑到这一点,您的单元测试看起来是错误的。例如,以4为例。533/400不是精确的4/3比率。有了这个确切的比例,最好的答案是532/399

如果你愿意放松比率的精确性,那么你应该采取如下措施:

public function findBestSizeForRatio($inputW, $inputH, $ratioW, $ratioH)
{
    if($inputW / $ratioW > $ratioH / $inputH){
        $w = $inputW;
        $h = round($w * $ratioH / $ratioW);
    }
    else{
        $h = $inputH;
        $h = round($h * $ratioW / $ratioH);
    }

    return array($w, $h);
}

试试这个微妙的变化:

public function findBestSizeForRatio($inputW, $inputH, $ratioW, $ratioH)
{
    if($inputW / $ratioW < $inputH / $ratioH){
        $w = floor($inputW / $ratioW) * $ratioW;
        $h = $w * $ratioH / $ratioW;
    }
    else{
        $h = floor($inputH / $ratioH) * $ratioH;
        $w = $h * $ratioW / $ratioH;
    }

    return array($w, $h);
} 
公共函数findBestSizeForRatio($inputW、$inputH、$ratioW、$ratioH)
{
如果($inputW/$ratioW<$inputH/$ratioH){
$w=地板($inputW/$ratioW)*$ratioW;
$h=$w*$ratioH/$ratioW;
}
否则{
$h=地板($inputH/$ratioH)*$ratioH;
$w=$h*$ratioW/$ratioH;
}
返回数组($w,$h);
} 

我看到您已经将单元测试修复为;很好。

试试这一细微的变化:

public function findBestSizeForRatio($inputW, $inputH, $ratioW, $ratioH)
{
    if($inputW / $ratioW < $inputH / $ratioH){
        $w = floor($inputW / $ratioW) * $ratioW;
        $h = $w * $ratioH / $ratioW;
    }
    else{
        $h = floor($inputH / $ratioH) * $ratioH;
        $w = $h * $ratioW / $ratioH;
    }

    return array($w, $h);
} 
公共函数findBestSizeForRatio($inputW、$inputH、$ratioW、$ratioH)
{
如果($inputW/$ratioW<$inputH/$ratioH){
$w=地板($inputW/$ratioW)*$ratioW;
$h=$w*$ratioH/$ratioW;
}
否则{
$h=地板($inputH/$ratioH)*$ratioH;
$w=$h*$ratioW/$ratioH;
}
返回数组($w,$h);
} 

我看到您已经将单元测试修复为;很好。

如果您关心的是计算的精度,您可能想检查一下,或者@Mikk,我不需要像浮点精度那样的精度。是因为我不想要四舍五入。如果你看这个测试#4。我不想要400 x 533.333,我想要399 x 532,因为不可能保持理想宽度为400的比例。我只想在结果中使用整数,始终不使用四舍五入。如果您关心的是计算的精度,那么您可能需要签出或@Mikk,我不需要像浮点精度那样的精度。是因为我不想要四舍五入。如果你看这个测试#4。我不想要400 x 533.333,我想要399 x 532,因为不可能保持理想宽度为400的比例。我只想在结果中输入整数,总是这样,而不是四舍五入。你已经正确理解了这个问题。但是不,我不想放松。正如你所注意到的,我已经有了这个方法(而且它工作得很好)。你是对的,测试4是错误的,正如你指出的,预期结果应该是532/399。我会编辑这篇文章。@FMaz008:啊。在这种情况下,
$w=$inputW-($inputW%$ratioW)
然后是
$h=$w*$ratioH/$ratioW
。这假设
$ratioW
$ratioH
是相对素数。如果你不能假设这一点,很容易用gcd除以它们来保证这一点。在中搜索“gcd”以查找该示例实现。@b illy不是$w=$inputW-($inputW%$ratioW)和$w=floor($inputW/$ratioW)*$ratioW;还差不多吗?我看不出有什么不同。。。是的,我确实假设比率会降低(40/30将始终是4/3)@b就我所能理解的而言,问题在于我的IF条件。我有些考试及格了。如果我颠倒等式,我会有其他的测试通过。在这两种情况下,每次我得到一个失败的测试,在另一种情况下,我会有好的公式值,如果。。。我的观点(我可能是错的)是,如果我的情况遗漏了一个细节。我什么都没想。@FMaz008-D'oh
$inputW/$ratioW>$ratioH/$inputH
应该是
$inputW/$ratioW>$inputH/$ratioH
。您已经正确理解了问题。但是不,我不想放松。正如你所注意到的,我已经有了这个方法(而且它工作得很好)。你是对的,测试4是错误的,正如你指出的,预期结果应该是532/399。我会编辑这篇文章。@FMaz008:啊。在这种情况下,
$w=$inputW-($inputW%$ratioW)
然后是
$h=$w*$ratioH/$ratioW
。这假设
$ratioW
$ratioH
是相对素数。如果你不能假设这一点,很容易用gcd除以它们来保证这一点。在中搜索“gcd”以查找该示例实现。@b illy不是$w=$inputW-($inputW%$ratioW)和$w=floor($inputW/$ratioW)*$ratioW;还差不多吗?我看不出有什么不同。。。是的,我确实假设这个比例会减少(40/30总是4/3)@b至少