1311 private links
J'ai eu quelques soucis avec Travis CI pour des tests de bout en bout d'un outil qui manipule des images en PHP.
En gros, j'ai :
- un dossier avec des images attendues
- un dossier avec les images sources
- des tests unitaires qui passent les images sources dans la moulinette, et s'assurent qu'elles ressortent identiques aux images attendues.
Tout marchait bien en local, mais lors de l'exécution des tests Travis, toutes les images étaient différentes. À l’œil nu, c'était bien les même, mais les binaires n'étaient pas identiques.
Il s'avère qu'il suffit d'avoir une version légèrement différente de php-gd
pour que les images générées soient différentes, par exemple une amélioration de l'encodage. Merci cet article du blog de Piwik pour m'avoir mis sur la piste.
De fait, la solution est assez simple : recréer à la volée les images attendues avec PHP GD (et donc la même version que celle utilisée par la moulinette). Attention, il faut bien ré-utiliser toutes les fonctions utilisée dans la manipulation des images pour arriver au bon résultat.
En bonus, un petit snippet :
/**
* Duplicate expected images using the current GD version.
*
* Different versions of GD will result in slightly different images,
* which would make the comparaison test fail. By regenerating expected thumbs,
* the expected and actual result should be the same.
*
* @param string $image relative path of the expected thumb inside the expected thumb directory.
* @param bool $crop Set to true to apply the crop function.
*
* @throws \Exception couldn't create the image.
*/
public function regenerate($image, $crop = false)
{
$targetFolder = dirname(self::$regenerated . $image);
if (! is_dir($targetFolder)) {
mkdir($targetFolder, 0755, true);
}
$content = file_get_contents(self::$expected . $image);
$sourceImg = @imagecreatefromstring($content);
$width = imagesx($sourceImg);
$height = imagesy($sourceImg);
$targetImg = imagecreatetruecolor($width, $height);
if (! imagecopyresized(
$targetImg, $sourceImg,
0, 0, 0, 0,
$width, $height, $width, $height
)
) {
@imagedestroy($sourceImg);
@imagedestroy($targetImg);
throw new \Exception('Could not generate the expected image from source image.');
}
if ($crop) {
$targetImg = imagecrop($targetImg, [
'x' => 0,
'y' => 0,
'width' => $width,
'height' => $height
]);
}
$target = self::$regenerated . $image;
imagedestroy($sourceImg);
imagepng($targetImg, $target);
imagedestroy($targetImg);
}