Solved

PHP htaccess Watermark PNG

Posted on 2012-03-28
10
731 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Salesforce Has Never Been Easier

Improve and reinforce salesforce training & adoption using WalkMe's digital adoption platform. Start saving on costly employee training by creating fast intuitive Walk-Thrus for Salesforce. Claim your Free Account Now

 

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

NFR key for Veeam Backup for Microsoft Office 365

Veeam is happy to provide a free NFR license (for 1 year, up to 10 users). This license allows for the non‑production use of Veeam Backup for Microsoft Office 365 in your home lab without any feature limitations.

Question has a verified solution.

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

This article was originally published on Monitis Blog, you can check it here . Today it’s fairly well known that high-performing websites and applications bring in more visitors, higher SEO, and ultimately more sales. By the same token, downtime…
Australian government abolished Visa 457 earlier this April and this article describes how this decision might affect Australian IT scene and IT experts.
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 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…

635 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