简体   繁体   中英

PHP watermark images on the fly

Background

I have read through many sites including this one for a solution. I have a watermark script which up until a few months ago worked flawlessly. My hosting provider performed routine updates and hosed my script. I made one adjustment to it, it worked. With time, the watermark script seems be very heavy on system resources, causing all sorts of issues with my site including images not loading at random, etc. Currently, it appears I could run the site on PHP version 5.4 or a version or two above and below it. Currently running at 5.4 if that should help.

Explanation

The script is intended to find image files from a specific location, pending on size, combine with one of several png images on the fly without overwriting the original image.

The script

I have modified my script significantly in the past week, with minor performance improvement. I'm at my wits end, are there further improvements to this script to be made or cleaner code. Any assistance would greatly be appreciated.

Files .htaccess, three jpg(s), and the watermark.php script.

.htaccess

    RewriteRule ^(.*)wp-content/uploads/(.*) $1watermark.php?src=wp-content/uploads/$2

watermark.php

<?php
$src = $_GET['src'];

    if(preg_match('/.gif/i',$src)) { $image = imagecreatefromgif($src); }
    if(preg_match('/.png/i',$src)) { $image = imagecreatefrompng($src); }
    if(preg_match('/.jpeg/i',$src)||preg_match('/.jpg/i',$src)) { $image = imagecreatefromjpeg($src); }
    if (!$image) exit();
//  if (empty($images)) die();

    if (imagesx($image) > 301 ) { $watermark = imagecreatefrompng('watermark.png'); }      // height greater than 301 then apply watermark 600x600
elseif (imagesx($image) > 175 ) { $watermark = imagecreatefrompng('watermarksm.png'); }    // height greater than 175 then apply small watermark 200x200
                           else { $watermark = imagecreatefrompng('empty.png'); }          // apply a dummy watermark resulting in none. 1x1

$dest_x = imagesx($image) - imagesx($watermark) - 0;
$dest_y = imagesy($image) - imagesy($watermark) - 0;

imagecopy($image, $watermark, $dest_x, $dest_y, 0, 0, imagesx($watermark), imagesy($watermark));
header('content-type: image/jpeg');  
imagejpeg($image);
imagedestroy($image);
imagedestroy($watermark); 
//die();
?>

A couple of things I have tried not reflected in this script is the following "minor" change.

if(preg_match('/.gif/i',$src)) to if(preg_match('/\\.gif$/i',$src))

Another variation attempted in the preg_match was with jpe$g and jp(|e)g$ . Those change didn't seem to help in anyway and seemed to hurt the performance further.

Again, any guidance would be appreciated. Thank you in advance.

Why don't you once for all create watermarked version of all your images ? It will avoid the server to work each time an image will be displayed on your website, and you will gain in performance.

If for any reason you need to display the original image, do a script that check the credential of the viewer then return the image.

First of all, those regular expressions are not the performance hogs. The real performance problems comes from image manipulation.

Save the result from imagejpeg($image); into a file on disk "hidden" from the world. You can restrict access to that folder with .htaccess .

The the logic should be something like this:

<?php
// Implement getTempFile to get a path name to the hidden folder.
$tempsrc = getTempFile($src)

$tempsrcexists = file_exists($tempsrc);

if (!$tempsrcexists)
{
    // Create image on disk.
    ...
}

// At this point, the temporary file must exist.    
$fp = fopen($tempsrcexists, 'rb');

// Output data to the client from the temporary file
header("Content-type: image/jpeg");
fpassthrough($fp);

fclose($fp);

?>

This should reduce the load on the server significantly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM