phpimagegdjpeglossy-compression

PHP GD Edit Jpeg without re-compressing


Say I have a jpeg file and I want to set some pixels to a certain color. When I save the jpeg, I am losing color and I see aliasing around my new pixels, even if I set quality to 100. I know it's a lossy format, but I don't want to re-compress the picture, just set a few pixels.

// Create the GD resource
$img = imagecreatefromjpeg($filename);

// Set the first pixel to red
$color = imagecolorallocate($img, 255, 0, 0);
imagesetpixel($img, 0, 0, $color);

// Save the jpeg - is this where I'm wrong? I see the red pixel but it's the wrong color and is blurred.
imagejpeg($img, 'foo.jpg', 100);

// Lossless format works fine, red pixel is bright and accurate.
imagepng($img, 'foo.png');

So maybe GD isn't the way to go here? I do need to change the color of some pixels and they need to be accurate when saved. Is there a way to do this without relying on GIF, PNG, or JPEG2000 ?


Solution

  • As you said yourself, JPEG is a lossy format. It doesn't actually store "pixels" directly. If you make a change to the image, the image has to be re-compressed. There is no way around this.

    The reason your red pixel is the "wrong color" and "blurred" is because of how JPEG compression works. Again, it doesn't store pixels. It puts emphasis on changes in brightness, and actual color information doesn't matter so much.

    I'm not positive, but you may be able to only re-compress the few blocks that are affected by your change. You would not be able to do this with any standard functions, and would have to dig into the format and compression schemes yourself.