View Single Post
Old 01-20-2007, 05:20 PM  
SmokeyTheBear
►SouthOfHeaven
 
SmokeyTheBear's Avatar
 
Join Date: Jun 2004
Location: PlanetEarth MyBoardRank: GerbilMaster My-Penis-Size: extralarge MyWeapon: Computer
Posts: 28,609
:stoned Watermarking made DEAD SIMPLE (tutorial )

People always ask about watermarking programs so i figured i would share a DEAD SIMPLE method for batch watermarking your images on the fly with php.

#1 reason to use php is because its flexible.. allowing you to offer different watermarks depending on who is viewing the pictures. for example it could be as simple as displaying different transparency of the logo if the picture is hotlinked than when on your own site (i.e. blatent logo when hotlinked , lighter logo when on your site ) or you could go clever and show random logos annd random large messages when the pictures are hotlinked.

Ok so heres how it works, in this example your site will be called "www.yoursite.com" your secret folder the images will be kept will be called "secret" and the follder this script is in is called "script"

so path to script would be
yoursite.com/script/

secret path of images would be
yoursite.com/script/secret/

first place a test jpg in the secret folder
yoursite.com/script/secret/test.jpg like that
then place your logo, name it "watermark.gif" in the script folder
yoursite.com/script/watermark.gif like that
then place a ttf file called font.ttf in the script folder
yoursite.com/script/font.ttf like that
(ttf is true type font , theres some in your windows font folder if you dont have one )

then copy and save the following as water.php and place it in the scripts folder
yoursite.com/script/water.php like that
Code:
<?php
class watermark{
 
      # given two images, return a blended watermarked image
function create_watermark( $main_img_obj, $watermark_img_obj, $alpha_level = 100 ) {
      $alpha_level      /= 100;     # convert 0-100 (%) alpha to decimal
 
      # calculate our images dimensions
      $main_img_obj_w   = imagesx( $main_img_obj );
      $main_img_obj_h   = imagesy( $main_img_obj );
      $watermark_img_obj_w    = imagesx( $watermark_img_obj );
      $watermark_img_obj_h    = imagesy( $watermark_img_obj );
      
      # determine center position coordinates
      $main_img_obj_min_x     = floor( ( $main_img_obj_w) - ( $watermark_img_obj_w) );
      $main_img_obj_max_x     = ceil( ( $main_img_obj_w / 2 ) + ( $watermark_img_obj_w / 2 ) );
      $main_img_obj_min_y     = floor( ( $main_img_obj_h ) - ( $watermark_img_obj_h ) );
      $main_img_obj_max_y     = ceil( ( $main_img_obj_h / 2 ) + ( $watermark_img_obj_h / 2 ) ); 
      
      # create new image to hold merged changes
      $return_img = imagecreatetruecolor( $main_img_obj_w, $main_img_obj_h );
 
      # walk through main image
      for( $y = 0; $y < $main_img_obj_h; $y++ ) {
      for( $x = 0; $x < $main_img_obj_w; $x++ ) {
            $return_color     = NULL;
            
            # determine the correct pixel location within our watermark
            $watermark_x      = $x - $main_img_obj_min_x;
            $watermark_y      = $y - $main_img_obj_min_y;
            
            # fetch color information for both of our images
            $main_rgb = imagecolorsforindex( $main_img_obj, imagecolorat( $main_img_obj, $x, $y ) );
            
            # if our watermark has a non-transparent value at this pixel intersection
            # and we're still within the bounds of the watermark image
            if (  $watermark_x >= 0 && $watermark_x < $watermark_img_obj_w &&
                              $watermark_y >= 0 && $watermark_y < $watermark_img_obj_h ) {
                  $watermark_rbg = imagecolorsforindex( $watermark_img_obj, imagecolorat( $watermark_img_obj, $watermark_x, $watermark_y ) );
                  
                  # using image alpha, and user specified alpha, calculate average
                  $watermark_alpha  = round( ( ( 127 - $watermark_rbg['alpha'] ) / 127 ), 2 );
                  $watermark_alpha  = $watermark_alpha * $alpha_level;
            
                  # calculate the color 'average' between the two - taking into account the specified alpha level
                  $avg_red          = $this->_get_ave_color( $main_rgb['red'],            $watermark_rbg['red'],        $watermark_alpha );
                  $avg_green  = $this->_get_ave_color( $main_rgb['green'],      $watermark_rbg['green'],      $watermark_alpha );
                  $avg_blue         = $this->_get_ave_color( $main_rgb['blue'],      $watermark_rbg['blue'],       $watermark_alpha );
                  
                  # calculate a color index value using the average RGB values we've determined
                  $return_color     = $this->_get_image_color( $return_img, $avg_red, $avg_green, $avg_blue );
                  
            # if we're not dealing with an average color here, then let's just copy over the main color
            } else {
                  $return_color     = imagecolorat( $main_img_obj, $x, $y );
                  
            } # END if watermark
 
            # draw the appropriate color onto the return image
            imagesetpixel( $return_img, $x, $y, $return_color );
 
      } # END for each X pixel
} # END for each Y pixel 
            
      # return the resulting, watermarked image for display
      return $return_img;
 
} # END create_watermark()
      
      # average two colors given an alpha
      function _get_ave_color( $color_a, $color_b, $alpha_level ) {
      return round( ( ( $color_a * ( 1 - $alpha_level ) ) + ( $color_b  * $alpha_level ) ) );
} # END _get_ave_color()    
 
      # return closest pallette-color match for RGB values
    function _get_image_color($im, $r, $g, $b) {
      $c=imagecolorexact($im, $r, $g, $b);
      if ($c!=-1) return $c;
      $c=imagecolorallocate($im, $r, $g, $b);
      if ($c!=-1) return $c;
      return imagecolorclosest($im, $r, $g, $b);
} # EBD _get_image_color()

 
} # END watermark API
?>

now copy and save the following as index.php and place in the scripts folder
yoursite.com/script/index.php like that

Code:
<?php
$pic = $_GET['stb'];
$water = "watermark.gif";
$pic = "secret/$pic.jpg";
 
      # include our watermerking class
      include 'water.php';
      $watermark              = new watermark();
 

   $main_img_obj                       = imagecreatefromjpeg("$pic");
      $watermark_img_obj      = imagecreatefromgif("$water");


// writing text

 $words = "Hello This is example text";

// true type font
$font = 'font.ttf';


// size duh

$fontsize=13;
// color

$color = ImageColorAllocate($main_img_obj, 100, 0, 100);

// Where to place the text
// from top
$ft = "22";
//from right
$fr = "22";
// angle
$angle = "0";

imagettftext($main_img_obj,  $fontsize, $angle, $fr, $ft, $color, $font, $words );



      # create our watermarked image - set 66% alpha transparency for our watermark
      $return_img_obj               = $watermark->create_watermark( $main_img_obj, $watermark_img_obj, 66 );
 
      # display our watermarked image - first telling the browser that it's a JPEG, 
      # and that it should be displayed inline
      header( 'Content-Type: image/jpeg' );
      header( 'Content-Disposition: inline; filename=' . $_GET['src'] );
      imagejpeg( $return_img_obj, '', 50 );
 
?>
Last but not least copy and save the following as ".htaccess" and upload to the script directory

Code:
RewriteEngine on
 RewriteRule ^(.*)\.jpeg http://www.yoursite.com/script/?stb=$1 [nc]
now you can try it out by pointing your browser to
yoursite.com/script/test.jpeg
or bypassing htacces if its giving you troubles by pointing to
yoursite.com/script/?stb=test

the picture is really inside the secret folder.

Now you should note that when you call the image you call it .jpeg not .jpg but the real images should be named .jpg

Nobody will know the secret directory but the server. if perhaps someone does , you can easily just rename the secret folder ( and change the index.php to reflect the new path ) and pictures wont work but your pictures will still work fine without having to change all your exisiting img tags

enjoy.. ill add a few tips in a moment.

any questions feels free to ask
__________________
hatisblack at yahoo.com
SmokeyTheBear is offline   Share thread on Digg Share thread on Twitter Share thread on Reddit Share thread on Facebook Reply With Quote