imagecopyresampled() produces rounding errors

Issue #26 resolved
Vitaliy Filippov created an issue

imagecopyresampled() produces rounding errors.

A simple example is trying to resample a fully transparent 560x349 image down to 100x62.

The resulting image will have transparency 2/255, not 0 as it was in the original image.

This is caused by a conversion to int without rounding - alpha/spixels is often something like 126.999999999, that is floored down to int 126, and then 126 is transformed into opacity=2.

The fix would be to change

red /= spixels;
green /= spixels;
blue /= spixels;
alpha /= spixels;

to

red = red/spixels+0.5;
green = green/spixels+0.5;
blue = blue/spixels+0.5;
alpha = alpha/spixels+0.5;

Comments (4)

  1. Tjelvar Eriksson

    I'm having similar issues with absolutely white images being distorted to #fffffe with imagecopyresampled.

    Certain ratios are ok, others are not. The rounding errors probably also increases the jpegsize. From my perspective it's a major and severe bug.

    regards, /tj

    //r=0.7 gives error
    //r=0.8 ok
    $r = 0.314;
    //$r = 0.5;
    $im2 = imagecreatefromjpeg('307_004Rn.jpg');
    $d = array(imagesx($im2) * $r,imagesy($im2) * $r);
    $im = imagecreatetruecolor($d[0],$d[1]);
    imagecopyresampled($im,$im2,0,0,0,0,$d[0],$d[1],imagesx($im2),imagesy($im2));
    
    //output doesn't affect error. Error affects both png ang jpeg.
    if(false) {
      header('content-type:image/jpeg');
      imagejpeg($im,null,100);
    } else {
      header('content-type:image/png');
      imagepng($im);
    }
    

    Bundled gd-version:

    Array
    (
        [GD Version] => bundled (2.0.34 compatible)
        [FreeType Support] => 1
        [FreeType Linkage] => with freetype
        [T1Lib Support] => 
        [GIF Read Support] => 1
        [GIF Create Support] => 1
        [JPEG Support] => 1
        [PNG Support] => 1
        [WBMP Support] => 1
        [XPM Support] => 
        [XBM Support] => 1
        [JIS-mapped Japanese Font Support] => 
    )
    
  2. Tjelvar Eriksson

    To anyone with the same problems;

    imagefilter($im,IMG_FILTER_CONTRAST,-1);
    

    before saving restores #FFFFFE to pure white.

  3. Log in to comment