Closed imazen-bot closed 3 years ago
A better testcase:
#!php
<?php
// Request input parameters
$percent = isset($_GET["scale"]) ? floatval($_GET["scale"]) : 1;
// Build original image
$width = $height = 1000;
$image = imagecreatetruecolor($width, $height);
$white = imagecolorallocate($image, 255, 255, 255);
imagefill($image, 0, 0, $white);
// Get new dimensions
$new_width = $width * $percent;
$new_height = $height * $percent;
// Resample
$image_p = imagecreatetruecolor($new_width, $new_height);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
// Output
header('Content-Type: image/png');
imagepng($image_p, null);
Originally posted by ChALkeR (ChALkeR) on Jan 02 2014 via Bitbucket
I can confirm the same bug on PHP 5.6.10 is somebody addressing the issue?
Problem can be solved using imagescale : $image_p = imagescale($image, $new_width, $new_height, IMG_NEAREST_NEIGHBOUR);
Just tested and it works.
You can find the resulting jpg in attachment (If you can't see the artifact just add contrast in photoshop)
If I maximally decrease brightness and increase contrast, I can see artifacts, but these may be usual JPEG compression artifacts (note that JPEG quality 100 doesn't mean lossless compression). I suggest that you check with a PNG image (which is lossless).
I can confirm the same bug on PHP 5.6.10 is somebody addressing the issue?
I would need a good sample (original and resampled plus code) to reproduce the issue.
$image_p = imagescale($image, $new_width, $new_height, IMG_NEAREST_NEIGHBOUR);
Hm, IMG_NEAREST_NEIGHBOUR is not everybody's favorite. If I'm not mistaken, that is the same as imagecopyresized().
Also the artifacts may be gone too with libgd from.here. I change the sampling for q>=90 so almost no artefacts should appear.
2.2 or master branches. This charge will be in 2.2.2 or next 5.6/7.0/7.1
@cmb69 for the record here, imagecopyresanpled uses a kind of bicubic interpolation, not nearest.
imagecopyresanpled uses a kind of bicubic interpolation, not nearest.
Yes, I know. :) Therefore I'm preferring imagecopyresampled() over imagecopyresized() (even though the latter is a bit faster).
Well, actually this is the same issue that has been reported as https://bugs.php.net/bug.php?id=53580, including a rather terse analysis. The culprit appears that we cast float
/double
to int
.
Reproduce script:
<?php
$src = imagecreatetruecolor(4, 4);
$white = imagecolorallocate($src, 255, 255, 255);
imagefilledrectangle($src, 0,0, 3,3, $white);
for ($i = 0; $i < 4; $i++) {
for ($j = 0; $j < 4; $j++) {
assertColorAt($src, $i, $j, $white);
}
}
$dst = imagecreatetruecolor(7, 7);
imagecopyresampled($dst, $src, 0,0, 0,0, 7,7, 4,4);
for ($i = 0; $i < 7; $i++) {
for ($j = 0; $j < 7; $j++) {
assertColorAt($dst, $i, $j, $white);
}
}
function assertColorAt($im, $x, $y, $exp_color) {
$act_color = imagecolorat($im, $x, $y);
if ($act_color !== $exp_color) {
printf("color of %2d,%2d is %x, expected %x\n", $x, $y, $act_color, $exp_color);
}
}
The result is likely system dependent, but for me it's (current PHP master with bundled GD):
color of 1, 5 is fefefe, expected ffffff
color of 5, 1 is fefefe, expected ffffff
color of 5, 5 is fefefe, expected ffffff
And (current PHP master with current GD master):
color of 0, 3 is fefefe, expected ffffff
color of 3, 0 is fefefe, expected ffffff
gdImageScale()
has similar issues depending on the algorithm. For instance, GD_BILINEAR_FIXED
works as expected, while GD_BICUBIC
and GD_BICUBIC_FIXED
even produce several fcfcfc
pixels.
I cleanup/refactor a bit the new scaling functions and added an example here.
It fixes an issue about the support (radius) used by each filter and ensure correct filters being used.
I would GD_LANCZOS3 for downscale and mitchell for upscale, to begin width.
@cmb69 could you give a try?
gdImageCopyResampled is back to working state from a rounding point of views. Artifacts in such situations are gone. see #661
Hi Pierre,
Following your recommandation on the mailing list I open a new issue : If I resize a picture to a size which is not a multiple of the original size I have artifacts on the white background.
I just had a test on php5.53 and the bug is still here :
Here is the code I used to test (test.jpg is a 1000x1000 jpeg)
You can find the resulting jpg in attachment (If you can't see the artifact just add contrast in photoshop)