tags:

views:

345

answers:

1

Below is a watermark function I made for my php photo upload script. I am curious if there is a better way of doing the parts that check for the file type, notice I had to use that part of code 2 times

<?PHP
function watermark($source_file,$source_width,$source_height,$image_type) {
    //first image below will be large then small in 1line if/else
    $watermarksize = ($source_width > 300) ? '../images/fpwatermark.gif' : '../images/fpwatermark.gif';
    //now add the watermark to the image.
    $watermark = imagecreatefromgif($watermarksize);
    switch ($image_type) {
     case 'gif':
      $image = imagecreatefromgif($source_file);
      break;
     case 'jpg':
      $image = imagecreatefromjpeg($source_file);
      break;
     case 'png':
      $image = imagecreatefrompng($source_file);
      break;
     default:
      $image = imagecreatefromjpeg($source_file);
      break;
    }
    //get the dimensions of the watermark
    list($water_width, $water_height) = getimagesize($watermarksize);
    // Water mark process
    $x = $source_width - $water_width - 8; //horizontal position
    $y = $source_height - $water_height - 8; //vertical positon
    // imagesy($image) can be the source images width
    imagecopymerge($image, $watermark, $x, $y, 0, 0, $water_width, $water_height, 65);
    switch ($image_type) {
     case 'gif':
      imagegif($image, $source_file, 90);
      break;
     case 'jpg':
      imagejpeg($image, $source_file, 90);
      break;
     case 'png':
      imagepng($image, $source_file, 90);
      break;
     default:
      imagejpeg($image, $source_file, 90);
      break;
    }
    imagedestroy($image);
    return $source_file;
}
?>
+2  A: 

You could use dynamic function calls, as illustrated below. This code is subtly different from yours since it returns if an invalid image type is provided rather than assume that it's jpeg. If you insist on that behavior it should be easy enough to change, tough.

It's not always the case that all these image types are supported by PHP so you might want to use function_exists() to check for that before calling them. Calling a non-existant function is a fatal error in PHP.

<?PHP
function watermark($source_file,$source_width,$source_height,$image_type) {
    $validTypes = array("gif" => "gif", "jpg" => "jpeg", "jpeg" => "jpeg", "png" => "png");
    if (!array_key_exists($image_type, $validTypes)) {
        trigger_error("Not a valid image type", E_USER_WARNING);
        return NULL;
    }

    $inFunc = "imagecreatefrom" . $validTypes[$image_type];
    $outFunc = "image" . $validTypes[$image_type];

    //first image below will be large then small in 1line if/else
    $watermarksize = ($source_width > 300) ? '../images/fpwatermark.gif' : '../images/fpwatermark.gif';
    //now add the watermark to the image.
    $watermark = imagecreatefromgif($watermarksize);

    // open the image using the assigned function
    $image = $inFunc($source_file);

    //get the dimensions of the watermark
    list($water_width, $water_height) = getimagesize($watermarksize);
    // Water mark process
    $x = $source_width - $water_width - 8; //horizontal position
    $y = $source_height - $water_height - 8; //vertical positon
    // imagesy($image) can be the source images width
    imagecopymerge($image, $watermark, $x, $y, 0, 0, $water_width, $water_height, 65);

    // save the image
    $outFunc($image, $source_file, 90);

    imagedestroy($image);
    return $source_file;
}

If you have the exif extension installed you could use exif_imagetype() to automatically detect the type of the image.

Another option that's a bit more elegant, but also contains more code is to use polymorfism:

<?php

interface Codec {
    public function open($file);
    public function save($img);
}

class JPEGCodec implements Codec {
    public function open($file) { return imagecreatefromjpeg($file); }
    public function save($img, $out_file) { imagejpeg($img, $out_file, 90); }
}

class PNGCodec implements Codec {
    public function open($file) { return imagecreatefrompng($file); }
    public function save($img, $out_file) { imagepng($img, $out_file, 9); }
}

class GIFCodec implements Codec {
    public function open($file) { return imagecreatefromgif($file); }
    public function save($img, $out_file) { imagegif($img, $out_file); }
}

class WatermarkException extends Exception {}

class Watermark
{
    private $_codecs = array();

    public function __construct()
    {
     $this->_codecs["jpg"] = $this->_codecs["jpeg"] = new JPEGCodec();
     $this->_codecs["png"] = new PNGCodec();
     $this->_codecs["gif"] = new GIFCodec();
    }

    function watermark($source_file,$source_width,$source_height,$image_type) {
     if (!array_key_exists($image_type, $this->_codecs)) {
      throw new WatermarkException("Not a valid image type");
     }

     $codec = $this->_codecs[$image_type];

     //first image below will be large then small in 1line if/else
     $watermarksize = ($source_width > 300) ? '../images/fpwatermark.gif' : '../images/fpwatermark.gif';
     //now add the watermark to the image.
     $watermark = imagecreatefromgif($watermarksize);

     // load image
     $image = $codec->open($source_file);

     //get the dimensions of the watermark
     list($water_width, $water_height) = getimagesize($watermarksize);
     // Water mark process
     $x = $source_width - $water_width - 8; //horizontal position
     $y = $source_height - $water_height - 8; //vertical positon
     // imagesy($image) can be the source images width
     imagecopymerge($image, $watermark, $x, $y, 0, 0, $water_width, $water_height, 65);

     // save image
     $codec->save($image, $source_file);

     imagedestroy($image);
     return $source_file;
    }
}

I realize that you'll probably prefer the first one. :)

Emil H
thanks, that looks much better! also I will be passing the file type into the function from the page it is used on
jasondavis
Thanks, and yeah thats really confusing to me,but nice to see and have as future reference, thank you
jasondavis
ImageCreateFromString(file_get_contents($source_file));
Alix Axel