Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

PHP htaccess Watermark PNG

Posted on 2012-03-28
10
Medium Priority
?
746 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
8 Comments
 
LVL 7

Assisted Solution

by:designatedinitializer
designatedinitializer earned 800 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 800 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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

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 111

Assisted Solution

by:Ray Paseur
Ray Paseur earned 800 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 111

Expert Comment

by:Ray Paseur
ID: 38460264
0
 
LVL 43

Assisted Solution

by:David S.
David S. earned 400 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 111

Accepted Solution

by:
Ray Paseur earned 800 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

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

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

Although a lot of people devote their energy toward marketing for specific industries, there are some basic principles that can be applied to any sector imaginable. We’ll look at four steps to take and examine how those steps were put into action fo…
Q&A with Course Creator, Mark Lassoff, on the importance of HTML5 in the career of a modern-day developer.
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.
The viewer will get a basic understanding of what section 508 compliance can entail, learn about skip navigation links, alt text, transcripts, and font size controls.
Suggested Courses

782 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