3

Having a few teething problems watermarking a photo. It all works fine apart from the watermarked photo's colors become duller than they should be - very noticeable in-fact.

I'm using imagecopyresized to do my watermarking, as this specifically allows me to use PNG-24 watermarks, the others do not. I know the colors are usually OK, as I have just used readfile($url) as a test, and the photos are perfect.

Here is my script:

<?php

// get parent and watermark images & sizes
$image = imagecreatefromjpeg($url);
$imageSize = getimagesize($url);
$watermark = imagecreatefrompng('watermark.png');
$watermark_o_width = imagesx($watermark);
$watermark_o_height = imagesy($watermark);

// calculate new watermark width and position
if ($imageSize[0] > $imageSize[1] || $imageSize[0] == $imageSize[1]) {
    $leftPercent = 23;
} else {
    $leftPercent = 7;
}
$leftPixels = ($imageSize[0]/100)*$leftPercent;
$newWatermarkWidth = $imageSize[0]-$leftPixels;
$newWatermarkHeight = $watermark_o_height * ($newWatermarkWidth / $watermark_o_width);

// place watermark on parent image, centered and scaled
imagecopyresized(
    $image,
    $watermark,
    $imageSize[0]/2 - $newWatermarkWidth/2,
    $imageSize[1]/2 - $newWatermarkHeight/2,
    0,
    0,
    $newWatermarkWidth,
    $newWatermarkHeight,
    imagesx($watermark),
    imagesy($watermark)
);

// print
imagejpeg($image);

// destroy
imagedestroy($image);
imagedestroy($watermark);

?>

How can I stop this from happening? I'm reading about imagecreatetruecolor, does that solve the issue? I'm Googling "imagecreatetruecolor color loss photos" and variations but nobody really talks about this issue. If I do need this function, where would I add that to this script?

This has totally thrown a spanner in the works for me and would love for somebody to tell me where to stick it (not literally).

Here is an example of the color loss. The preview image should be exactly the same colors as the thumbnail. The thumbnails are created using readfile() whereas the previews are created using imagecreatefromjpeg and imagecopresized.

enter image description here

TheCarver
  • 19,391
  • 25
  • 99
  • 149
  • Can you provide a link to the images being used? at least the watermark? – Zuul Jul 29 '12 at 04:35
  • @Zuul: I'm sorry, I unable do that - my loss. – TheCarver Jul 29 '12 at 04:39
  • Hmm... You've edited your question with the images, goes the same, just needed to see exactly what was happening! It's Time to solve the issue then! – Zuul Jul 29 '12 at 04:42
  • I'm not quite seeing it. Maybe some freehand circles would help :P – Bailey Parker Jul 29 '12 at 04:53
  • @PhpMyCoder: Are you from ComedianOverflow.com? :P – TheCarver Jul 29 '12 at 04:55
  • @PaparazzoKid My username used to be TheTXI – Bailey Parker Jul 29 '12 at 04:57
  • What is the original format of the image? If it's a PNG originally, saving it as a JPEG might change the colors a bit because of compression. That would be my guess, but I'm no photo expert. – Bailey Parker Jul 29 '12 at 04:59
  • @PhpMyCoder: It's a JPEG file. Do you want me to circle which one it is? :P – TheCarver Jul 29 '12 at 05:00
  • What if, instead of merging with a watermark, you tried merging with an empty PNG file (completely transparent and the exact size of the image). Then try merging a jpeg image with the jpeg (I know the waterwark can't be transparent, but try something that's not to see if adding the PNG is what causes the problem). – Bailey Parker Jul 29 '12 at 05:03
  • @PhpMyCoder: I'll give it ago but may need sleep first, it's 5 hours past bedtime here in UK! This is another guy suffering from the same, he came to the same conclusion to use **imagecreatetruecolor()**. http://stackoverflow.com/questions/2420320/when-dealing-with-gd-library-unwantedly-altering-colors – TheCarver Jul 29 '12 at 05:09
  • My guess is that the original image has a color profile that isn't being preserved by GD. –  Jul 29 '12 at 17:34
  • @duskwuff: I think you are right... I'm currently reading a few articles suggesting the same thing. Apparently GD does not support previous color profiles, which explains why readfile() is fine and the other functions are not. I'm gonna keep tinkering before making a decision. – TheCarver Jul 29 '12 at 19:22

2 Answers2

2

This example code works fine, by using the same characteristics as your images:

Original JPG: dark background; beautiful girl; red dress. Watermark PNG: transparent background; text; gray color.

<?php

// Path the the requested file (clean up the value if needed)
$path = $url;

// Load image
$image = imagecreatefromjpeg($path);
$w = imagesx($image);
$h = imagesy($image);

// Load watermark
$watermark = imagecreatefrompng('watermark.png');
$ww = imagesx($watermark);
$wh = imagesy($watermark);

// Merge watermark upon the original image (center center)
imagecopy($image, $watermark, (($w/2)-($ww/2)), (($h/2)-($wh/2)), 0, 0, $ww, $wh);

// Output the image to the browser
header('Content-type: image/jpeg');
imagejpeg($image);

// destroy both images
imagedestroy($image);
imagedestroy($watermark);

// kill script
exit();

?>


Left: Output Image | Right: Original Image

Screen Shot

Note:

The output image was compressed several times until: Original -> PHP Output -> GIMP -> Here.

Community
  • 1
  • 1
Zuul
  • 16,217
  • 6
  • 61
  • 88
  • Giving this a try now. Is there a reason behind **$path = $url** and not using it anywhere in the script? Never seen this before... – TheCarver Jul 29 '12 at 17:10
  • @PaparazzoKid My bad, small typo in the code, the reason is just to provide some cleanup to the variable contents before usage. Fixed now! *Was probably asleep at the keyboard;)* – Zuul Jul 29 '12 at 17:13
  • Just tried your script and the colors are still bad. I personally don't think GD can deal with color profiles very well. – TheCarver Jul 29 '12 at 20:35
  • @PaparazzoKid I use GD for all kinds of image manipulations, never had any problems with the color profile. If I could see your image, I could tell you exactly whats going on. That's with no doubt an issue with your images. – Zuul Jul 29 '12 at 20:38
  • Can't send the photo, have to respect my clients data unfortunately and there are .5 million of them stored on Amazon S3, so changing them is not an option. I'm looking at the photos details now and they're all set to sRGB color profile. – TheCarver Jul 29 '12 at 20:54
  • @PaparazzoKid Since I can't access your images, the only thing I can recommend is an alternative way of dealing with this issue. Instead of using PHP GD, use ImageMagick. You can do the same thing, and ImageMagick is aware of color profile being used. [ImageMagick examples](http://www.imagemagick.org/Usage/) and what you need to pay close attention to: [Compositing Images](http://www.imagemagick.org/Usage/compose/). – Zuul Jul 29 '12 at 23:02
0

After much testing, I came to the conclusion that PHP's GD Image does not support color profiles on the images that are being watermarked. I am now using Imagick and the colors are perfect.

TheCarver
  • 19,391
  • 25
  • 99
  • 149