Solved

PHP htaccess Watermark PNG

Posted on 2012-03-28
10
716 Views
Last Modified: 2012-12-01
I have a PHP script which places a watermark on images on my site.  It exports the images with a content type of JPEG but I'm wondering how I could modify my script so that if the image that the watermark is being placed on could export with a content type of PNG so it doesn't increase the file size of the image.

Here's my code:

<?php
    
    /*
     * This script places a watermark on a given jpeg, png or gif image.
     */
    
      // loads a png, jpeg or gif image from the given file name
      function imagecreatefromfile($image_path) {
        // retrieve the type of the provided image file
        list($width, $height, $image_type) = getimagesize($image_path);
    
        // select the appropriate imagecreatefrom* function based on the determined
        // image type
        switch ($image_type)
        {
          case IMAGETYPE_GIF: return imagecreatefromgif($image_path); break;
          case IMAGETYPE_JPEG: return imagecreatefromjpeg($image_path); break;
          case IMAGETYPE_PNG: return imagecreatefrompng($image_path); break;
          default: return ''; break;
        }
      }
    
      // load source image to memory
      $image = imagecreatefromfile($_GET['image']);
      if (!$image) die('Unable to open image');
    
      // load watermark to memory
      $watermark = imagecreatefromfile($_GET['watermark']);
      if (!$image) die('Unable to open watermark');
    
      // calculate the position of the watermark in the output image (the
      // watermark shall be placed in the lower right corner)
      $watermark_pos_x = imagesx($image) - imagesx($watermark);
      $watermark_pos_y = imagesy($image) - imagesy($watermark);
    
      // merge the source image and the watermark
      imagecopy($image, $watermark,  $watermark_pos_x, $watermark_pos_y, 0, 0,
        imagesx($watermark), imagesy($watermark));
    
      // output watermarked image to browser
      header('Content-Type: image/jpeg');
      imagejpeg($image, '', 85);  // use best image quality (100)
    
      // remove the images from memory
      imagedestroy($image);
      imagedestroy($watermark);
    
    ?>

Open in new window


Not sure if this matters but here's my .htaccess code:
RewriteEngine on
    RewriteRule ^(.*\.(jp?g))$ /videogames/watermark.php?image=$1&watermark=watermark.png [NC]

Open in new window


Thanks.
0
Comment
Question by:davideo7
  • 3
  • 2
  • 2
  • +1
10 Comments
 
LVL 7

Assisted Solution

by:designatedinitializer
designatedinitializer earned 200 total points
ID: 37779760
try changing this:
 // output watermarked image to browser
      header('Content-Type: image/jpeg');
      imagejpeg($image, '', 85);  // use best image quality (100)

Open in new window


to this:
 // output watermarked image to browser
      header('Content-Type: image/png');
      imagepng($image, '', 100);  // use best image quality (100)

Open in new window

0
 

Author Comment

by:davideo7
ID: 37779790
designatedinitializer: That actually doesn't work, not sure why but it just doesn't place the watermark on the image when I do that.
0
 
LVL 7

Assisted Solution

by:designatedinitializer
designatedinitializer earned 200 total points
ID: 37779852
sorry about that.
I see now.
The script loads a watermark file with the same file type as the image requested.
You need a little more programming in there.
We must create a new image resource and copy the resulting merged image into it so we can output it as a PNG, regardless of the original file types.
I unindented the lines of code I changed/added:

...
...    
      // merge the source image and the watermark
      imagecopy($image, $watermark,  $watermark_pos_x, $watermark_pos_y, 0, 0, imagesx($watermark), imagesy($watermark));
    
 // create new blank image with the same size as the original
$finalimage = imagecreatetruecolor(imagesx($image), imagesy($image));
// copy merged image to final destination
imagecopy($finalimage, $image, 0,0,0,0,imagesx($image),imagesy($image));

// output watermarked image to browser
header('Content-Type: image/png');
imagepng($finalimage, '', 100);  // use best image quality (100)
    
// remove the images from memory
imagedestroy($finalimage);
      imagedestroy($image);
      imagedestroy($watermark);
...

Open in new window

0
Space-Age Communications Transitions to DevOps

ViaSat, a global provider of satellite and wireless communications, securely connects businesses, governments, and organizations to the Internet. Learn how ViaSat’s Network Solutions Engineer, drove the transition from a traditional network support to a DevOps-centric model.

 

Author Comment

by:davideo7
ID: 37779864
Same thing happened as before.

Here's what my code looks like with your modification, just want to make sure I implemented your modified code properly:

<?php
    
    /*
     * This script places a watermark on a given jpeg, png or gif image.
     */
    
      // loads a png, jpeg or gif image from the given file name
      function imagecreatefromfile($image_path) {
        // retrieve the type of the provided image file
        list($width, $height, $image_type) = getimagesize($image_path);
    
        // select the appropriate imagecreatefrom* function based on the determined
        // image type
        switch ($image_type)
        {
          case IMAGETYPE_GIF: return imagecreatefromgif($image_path); break;
          case IMAGETYPE_JPEG: return imagecreatefromjpeg($image_path); break;
          case IMAGETYPE_PNG: return imagecreatefrompng($image_path); break;
          default: return ''; break;
        }
      }
    
      // load source image to memory
      $image = imagecreatefromfile($_GET['image']);
      if (!$image) die('Unable to open image');
    
      // load watermark to memory
      $watermark = imagecreatefromfile($_GET['watermark']);
      if (!$image) die('Unable to open watermark');
    
      // calculate the position of the watermark in the output image (the
      // watermark shall be placed in the lower right corner)
      $watermark_pos_x = imagesx($image) - imagesx($watermark);
      $watermark_pos_y = imagesy($image) - imagesy($watermark);
    
           // merge the source image and the watermark
      imagecopy($image, $watermark,  $watermark_pos_x, $watermark_pos_y, 0, 0, imagesx($watermark), imagesy($watermark));
    
 // create new blank image with the same size as the original
$finalimage = imagecreatetruecolor(imagesx($image), imagesy($image));
// copy merged image to final destination
imagecopy($finalimage, $image, 0,0,0,0,imagesx($image),imagesy($image));

// output watermarked image to browser
header('Content-Type: image/png');
imagepng($finalimage, '', 100);  // use best image quality (100)
    
// remove the images from memory
imagedestroy($finalimage);
      imagedestroy($image);
      imagedestroy($watermark);
    
    ?>

Open in new window

0
 
LVL 110

Assisted Solution

by:Ray Paseur
Ray Paseur earned 200 total points
ID: 38460252
In my experience, a PNG image is almost always larger than a JPG version of the same image.  PNG has some compression and remains faithful to the original image, and I see that as its largest advantage.  It does not have as much compression as JPG.
0
 
LVL 110

Expert Comment

by:Ray Paseur
ID: 38460264
0
 
LVL 42

Assisted Solution

by:David S.
David S. earned 100 total points
ID: 38460985
In my experience, a PNG image is almost always larger than a JPG version of the same image.  PNG has some compression and remains faithful to the original image, and I see that as its largest advantage.  It does not have as much compression as JPG.
Often, yes, but it really depends on the image. One of the biggest factors is the number of colors used in the image. Recently I converted a 54kb JPEG to a 9KB PNG. In that case the image was only using 77 colors, so it could be converted to a PNG-8 (which can use up to 256 colors in the image; in comparison, a PNG-24 can use as many colors as a JPEG).

JPEG is a "lossy" format, while PNG is a "lossless" format (unless of course you reduce an image that used more than 256 colors into a PNG-8). One problem with JPEGs is that each time one is (re-)saved it loses quality.
0
 
LVL 110

Accepted Solution

by:
Ray Paseur earned 200 total points
ID: 38461084
@Kravimir: Agreed that it depends on the image.  A photographic image is likely to be larger in PNG than a JPG, however many graphic images will be nicely rendered with only 256 colors or less.  As a quick test I took an 8MB JPG photo and saved it in PNG format using Photoshop CS5.  It blew up to 23MB.  (The in-Photoshop memory was 51MB)  Saving photos with 256 colors usually results in posterization.
0

Featured Post

Back Up Your Microsoft Windows Server®

Back up all your Microsoft Windows Server – on-premises, in remote locations, in private and hybrid clouds. Your entire Windows Server will be backed up in one easy step with patented, block-level disk imaging. We achieve RTOs (recovery time objectives) as low as 15 seconds.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

An enjoyable and seamless user experience can go a long way on an eCommerce site. While a cohesive layout and engaging copy play roles in creating a positive user experience, some sites neglect aspects that seem marginal but in actuality prove very …
There’s a good reason for why it’s called a homepage – it closely resembles that of a physical house and the only real difference is that it’s online. Your website’s homepage is where people come to visit you. It’s the family room of your website wh…
The viewer will learn the benefit of using external CSS files and the relationship between class and ID selectors. Create your external css file by saving it as style.css then set up your style tags: (CODE) Reference the nav tag and set your prop…
The viewer will the learn the benefit of plain text editors and code an HTML5 based template for use in further tutorials.

713 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question