views:

259

answers:

3
+2  Q: 

PHP watermarking

i am using this code to create watermark.

    $image = '1.jpg';
 $overlay = 'stamp.png';
 $opacity = "20";
 if (!file_exists($image)) {
  die("Image does not exist.");
 }
 // Set offset from bottom-right corner
 $w_offset = 0;
 $h_offset = 100;
 $extension = strtolower(substr($image, strrpos($image, ".") + 1));
 // Load image from file
 switch ($extension)
 {
  case 'jpg':
  $background = imagecreatefromjpeg($image);
  break;
  case 'jpeg':
  $background = imagecreatefromjpeg($image);
  break;
  case 'png':
  $background = imagecreatefrompng($image);
  break;
  case 'gif':
  $background = imagecreatefromgif($image);
  break;
  default:
  die("Image is of unsupported type.");
 }
 // Find base image size
 $swidth = imagesx($background);
 $sheight = imagesy($background);
 // Turn on alpha blending
 imagealphablending($background, true);
 // Create overlay image
 $overlay = imagecreatefrompng($overlay);
 // Get the size of overlay
 $owidth = imagesx($overlay);
 $oheight = imagesy($overlay);
 // Overlay watermark
 imagecopymerge($background, $overlay, $swidth - $owidth - $w_offset, $sheight - $oheight - $h_offset, 0, 0, $owidth, $oheight, $opacity);
 imagejpeg($background,$image);
 // Destroy the images
 imagedestroy($background);
 imagedestroy($overlay);

the png image contains a text with all other region as transparent. but when i execute this code , it applys the png over jpg, but the transparecy is not maintained of the png. it shows in a box.

how can i acheive that . ie if a png contains transaparent part , it should show the below image in that part....?

A: 

Have you tried using imagecopyresampled()? http://php.net/manual/en/function.imagecopyresampled.php

Brandon G
+1  A: 

The jpg format doesn't support transparency, so conceptually you will have to:

  • grab the pixels from the larger image (the jpeg) and put them into a buffer
  • grab the non-transparent pixels from the smaller image (the watermark) and move them into that buffer, applying the alpha along the way

You probably want to let a library do this. I like ImageMagick, especially since it's built in to php... here's an example of how to use it for this purpose from PHP:

// Let's read the images. 
$glasses = new Imagick(); 
if (FALSE === $glasses->readImage($dir . '/glasses.png')) 
{ 
    throw new Exception(); 
} 

$face = new Imagick(); 
if (FALSE === $face->readImage($dir . '/face.jpg')) 
{ 
    throw new Exception(); 
} 

// Let's put the glasses on (10 pixels from left, 20 pixels from top of face). 
$face->compositeImage($glasses, Imagick::COMPOSITE_DEFAULT, 10, 20);

And here's the link to the PHP manual page for ImageMagick::compositeImage (from which the above example came).

Benjamin Cox
+1  A: 

replacing imagecopymerge with imagecopy solved the issue. here is the new code

function watermark($image){
 $overlay = '../../../photos/photosets/stamp.png';
 $opacity = "20";
 if (!file_exists($image)) {
  die("Image does not exist.");
 }
 // Set offset from bottom-right corner
 $w_offset = 0;
 $h_offset = 100;
 $extension = strtolower(substr($image, strrpos($image, ".") + 1));
 // Load image from file
 switch ($extension)
 {
  case 'jpg':
  $background = imagecreatefromjpeg($image);
  break;
  case 'jpeg':
  $background = imagecreatefromjpeg($image);
  break;
  case 'png':
  $background = imagecreatefrompng($image);
  break;
  case 'gif':
  $background = imagecreatefromgif($image);
  break;
  default:
  die("Image is of unsupported type.");
 }
 // Find base image size
 $swidth = imagesx($background);
 $sheight = imagesy($background);
 // Turn on alpha blending
 imagealphablending($background, true);
 // Create overlay image
 //$overlay = imagecreatefrompng($overlay);
 // Get the size of overlay
 $owidth = imagesx($overlay);
 $oheight = imagesy($overlay);

 $photo = imagecreatefromjpeg($image);
 $watermark = imagecreatefrompng($overlay);
             // This is the key. Without ImageAlphaBlending on, the PNG won't render correctly.
 imagealphablending($photo, true);
            // Copy the watermark onto the master, $offset px from the bottom right corner.
 $offset = 10;
 imagecopy($photo, $watermark, imagesx($photo) - imagesx($watermark) - $offset, imagesy($photo) - imagesy($watermark) - $offset, 0, 0, imagesx($watermark), imagesy($watermark));
            // Output to the browser
 header("Content-Type: image/jpeg");
 imagejpeg($photo,$image);
 // Overlay watermark
 // Destroy the images
 imagedestroy($background);
 imagedestroy($overlay);
}
Jasim