Watermarking using too much CPU time

Posted on 2011-10-05
Last Modified: 2013-12-25
On a property website I'm dynamically watermarking images using script that can be found here
This works beautifully as we don't want to permanently watermark images as these are included in several feeds to portal sites where they apply their own watermark.

However, the hosting company are now saying that this script is using up too much CPU time.

Anyone got any ideas as to how we can overcome this?
Question by:fionafenton
    LVL 13

    Expert Comment

    by:Hugh McCurdy
    How about two copies of the images, one with the watermark and one without?
    LVL 10

    Accepted Solution

    Personally I would save every image once its been watermarked. Then in your script you could check for the image existance. If it doesn't exist create it however if it does just output the existing image. Something like the following (note I've used my own watermark function as I dont like that class you linked lol but you could change it to use it)

    // define a default watermark if none specified
    define('DEFAULT_WATERMARK',   'watermark.png');
    // I would prefer to do this with id's and a database lookup
    // but for simplicity url might be image.php?image=picture101.jpg&wm=company_logo.png
    $image = isset($_GET['image']) ? $_GET['image'] : FALSE;
    if( !$image ) die('No image specified.');
    $wm = isset($_GET['wm']) ? $_GET['wm'] : DEFAULT_WATERMARK;
    $img_name = pathinfo($image,PATHINFO_FILENAME);
    $wm_name = pathinfo($wm,PATHINFO_FILENAME);
    $output_name = $img_name . '_' . $wm_name . '.png';
    // Check if the watermark image already exists
    if( file_exists($output_name) ) {
       $output = imagecreatefrompng($output_name);
    } else {
       $output = watermark($image,$wm);
    // output the image to the browser
    header('Content-type: image/png');
    function watermark($base,$watermark) 
       list($basew,$baseh) = getimagesize($base);
       list($wmw,$wmh) = getimagesize($watermark);
       // Get the scale for the watermark
       if( $basew > $baseh ) 
          $wmscale = ($basew/2)/$wmw;
       } else 
          $wmscale = ($baseh/2)/$wmh;
       $newwmw = $wmw*$wmscale;
       $newwmh = $wmh*$wmscale;
       // Create the watermark the right size
       $wmimg = imagecreatefrompng($watermark);
       $newwmimg = imagecreate($newwmw,$newwmh);
       // Open the image, place watermark on it
       $baseimg = imagecreatefromjpeg($base);
       $dst_x = ($basew/2) - ($newwmw/2);
       $dst_y = ($baseh/2) - ($newwmh/2);
       return $baseimg;

    Open in new window


    LVL 13

    Expert Comment

    by:Hugh McCurdy
    Derokorian, while yours is a variation of my answer, I like yours better.  The watermarked copy is made only if needed.  Of course, it's kept (which is my solution).  I also like your solution because it looks simple to implement and it will (almost certainly) solve the problem, as stated.

    Now, if the problem is different than stated, this isn't solved.  If the watermark is supposed to contain information about the recipient, we still have a problem.

    Fiona?  Are the watermarks unique to each recipient?

    If they are, all I can think of is to make the code more efficient.  Perhaps run the water mark software in C if possible.
    LVL 10

    Expert Comment

    @hmccurdy I didn't want to suggest that you weren't right, I was merely showing how I implement the idea you already proposed - except to allow for as many watermarks as needed. Our solution would reduce CPU/RAM usage significantly and increase HD usage. However HD storage is a dime a gig (maybe even a dime a tera!)

    @fiona another problem could be the size of the images, if the resolution is very high you could think about resizing them down to a more reasonable resolution when you upload them. IE if the image will never be displayed higher than 1024x768 why store it at 3200x2400 anyway? Especially since it will hog more resources to watermark / output.
    LVL 1

    Author Comment

    Derokorian: Your solution is along the lines of what I had already concluded I would have to do. I was hoping there might be some other solution that I hadn't thought of. I have the additional problem that photos are often changed (but file names aren't).
    I think the simplest solution is to include all this in the image upload script, which already resizes all the images and creates the folders and thumbnails. I'll just get it to create an extra folder and watermark the images at the same time. That way I can be sure that the watermarked and unwatermaked images are the same.
    LVL 13

    Assisted Solution

    by:Hugh McCurdy
    @Derokorian -- No issues with you.  I didn't think you were suggesting I wasn't right.  I like your idea.

    @Fiona -- I don't think there's a better approach than we've discussed.  I think you are right about an image upload script.  If you blend in some of Derokorian's code (or write your own) with the existing script, I think you'll have the best possible solution.

    The only other idea I have is to push some of the PHP work off to C/C++.  Alternatively, compile the PHP code (something I've never done) so that it doesn't go through the interpreter. But I suspect the expense of development makes that solution "not best."
    LVL 1

    Author Closing Comment

    Thank you both for your input. I have some code rewriting to do!
    LVL 13

    Expert Comment

    by:Hugh McCurdy
    You're welcome.
    LVL 10

    Expert Comment

    Glad to help! If you need help rewriting code - feel free to post what you have and explain what you need and we'll be here!

    Good luck!

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    Maximize Your Threat Intelligence Reporting

    Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

    Using SQL Scripts we can save all the SQL queries as files that we use very frequently on our database later point of time. This is one of the feature present under SQL Workshop in Oracle Application Express.
    Password hashing is better than message digests or encryption, and you should be using it instead of message digests or encryption.  Find out why and how in this article, which supplements the original article on PHP Client Registration, Login, Logo…
    The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …
    Video by: Kyle
    After watching the Introduction to GIMP and additional tools to use in GIMP we are shown how to utilize multiple tools to create a 3D effect image.

    759 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

    Need Help in Real-Time?

    Connect with top rated Experts

    10 Experts available now in Live!

    Get 1:1 Help Now