Moi et un collège essayons de construire une méthode qui peut trouver la plus grande taille pour une sélection affichée par défaut dans une image. La sélection a un ratio.PHP: Trouver la dimension maximum upscalée tout en respectant un ratio
Jusqu'à présent, nous avons essayé ceci:
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);
}
Mais échouer nos tests unitaires.
Nous avons également essayé ceci:
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);
}
}
Il semble fonctionner, mais il est pas parfait pixel. Comme notre ratio est fait d'un petit nombre, nous avons besoin d'une méthode qui respecte VRAIMENT le rapport, même si l'image n'est pas remplie à 100%. Et il est aussi vraiment stupide de coder en constante constante comme * 10000 parce que nous sommes incapables de trouver une bonne formule mathématique. ;)
Nous avons également construit ces tests PHPUnit, qui semblaient comme représentant pour nous (donc on aurait pu oublié certains cas)
/**
* @covers Img_GD::findBestSizeInBox
*/
public function testfindBestSizeForRatioReturnValidValueForEasyInput()
{
$img = new Img_GD();
//1
$iW = 400; $iH = 300; //Input image size
$rW = 4; $rH = 3; //ratio
$eW = 400; $eH = 300; //Expected
$this->assertEquals(array($eW, $eH), $img->findBestSizeForRatio($iW, $iH, $rW, $rH), "Img: {$iW} x {$iH} Ratio: {$rW} x {$rH}");
//2
$iW = 400; $iH = 3000; //Input image size
$rW = 4; $rH = 3; //ratio
$eW = 400; $eH = 300; //Expected
$this->assertEquals(array($eW, $eH), $img->findBestSizeForRatio($iW, $iH, $rW, $rH), "Img: {$iW} x {$iH} Ratio: {$rW} x {$rH}");
//3
$iW = 4000; $iH = 300; //Input image size
$rW = 4; $rH = 3; //ratio.
$eW = 400; $eH = 300; //Expected
$this->assertEquals(array($eW, $eH), $img->findBestSizeForRatio($iW, $iH, $rW, $rH), "Img: {$iW} x {$iH} Ratio: {$rW} x {$rH}");
//4
$iW = 400; $iH = 3000; //Input image size
$rW = 3; $rH = 4; //ratio
$eW = 399; $eH = 532; //Expected
$this->assertEquals(array($eW, $eH), $img->findBestSizeForRatio($iW, $iH, $rW, $rH), "Img: {$iW} x {$iH} Ratio: {$rW} x {$rH}");
//5
$iW = 4000; $iH = 300; //Input image size
$rW = 3; $rH = 4; //ratio.
$eW = 225; $eH = 300; //Expected
$this->assertEquals(array($eW, $eH), $img->findBestSizeForRatio($iW, $iH, $rW, $rH), "Img: {$iW} x {$iH} Ratio: {$rW} x {$rH}");
//6
$iW = 4000; $iH = 300; //Input image size
$rW = 3; $rH = 4; //ratio.
$eW = 225; $eH = 300; //Expected
$this->assertEquals(array($eW, $eH), $img->findBestSizeForRatio($iW, $iH, $rW, $rH), "Img: {$iW} x {$iH} Ratio: {$rW} x {$rH}");
}
/**
* @covers Img_GD::findBestSizeInBox
*/
public function testfindBestSizeForRatioReturnValidValueForNonExactInput()
{
$img = new Img_GD();
//7
$iW = 403; $iH = 302; //Input image size
$rW = 4; $rH = 3; //ratio
$eW = 400; $eH = 300; //Expected
$this->assertEquals(array($eW, $eH), $img->findBestSizeForRatio($iW, $iH, $rW, $rH), "Img: {$iW} x {$iH} Ratio: {$rW} x {$rH}");
//8
$iW = 403; $iH = 3000; //Input image size
$rW = 4; $rH = 3; //ratio
$eW = 400; $eH = 300; //Expected
$this->assertEquals(array($eW, $eH), $img->findBestSizeForRatio($iW, $iH, $rW, $rH), "Img: {$iW} x {$iH} Ratio: {$rW} x {$rH}");
//9
$iW = 4000; $iH = 302; //Input image size
$rW = 4; $rH = 3; //ratio.
$eW = 400; $eH = 300; //Expected
$this->assertEquals(array($eW, $eH), $img->findBestSizeForRatio($iW, $iH, $rW, $rH), "Img: {$iW} x {$iH} Ratio: {$rW} x {$rH}");
//10
$iW = 403; $iH = 3000; //Input image size
$rW = 3; $rH = 4; //ratio
$eW = 402; $eH = 536; //Expected
$this->assertEquals(array($eW, $eH), $img->findBestSizeForRatio($iW, $iH, $rW, $rH), "Img: {$iW} x {$iH} Ratio: {$rW} x {$rH}");
//11
$iW = 4000; $iH = 302; //Input image size
$rW = 3; $rH = 4; //ratio.
$eW = 225; $eH = 300; //Expected
$this->assertEquals(array($eW, $eH), $img->findBestSizeForRatio($iW, $iH, $rW, $rH), "Img: {$iW} x {$iH} Ratio: {$rW} x {$rH}");
//12
$iW = 4000; $iH = 302; //Input image size
$rW = 3; $rH = 4; //ratio.
$eW = 225; $eH = 300; //Expected
$this->assertEquals(array($eW, $eH), $img->findBestSizeForRatio($iW, $iH, $rW, $rH), "Img: {$iW} x {$iH} Ratio: {$rW} x {$rH}");
}
Toute solution qui passe tous les tests?
Si la précision de vos calculs vous concerne, vous pouvez consulter http://php.net/manual/fr/book.bc.php ou http://php.net/manual/fr/ book.gmp.php – Mikk
@Mikk ce n'est pas que j'ai besoin de précision comme la précision en virgule flottante. C'est que je ne veux pas arrondir. Si Regardez le test # 4. Je ne veux pas 400 x 533,333, je veux 399 x 532, car il est impossible de maintenir le ratio avec une largeur idéale de 400. Je veux seulement un entier dans mes résultats, toujours, et non arrondi. – FMaz008