<?php // FOREIGN/watermark_test_hotlink.php
error_reporting(E_ALL);
// ALWAYS START THE SESSION ON EVERY PAGE
session_start();
// THE FOREIGN SCRIPT DOES NOT KNOW THAT IT MUST DO THIS
// $_SESSION["noWaterMark"] = array();
// $_SESSION["noWaterMark"][] = "r1.jpg";
// $_SESSION["noWaterMark"][] = "r2.jpg";
echo '<image src="http://www.iconoun.com/demo/watermark_hotlinked_image.php?q=r1.jpg" />';
echo '<image src="http://www.iconoun.com/demo/watermark_hotlinked_image.php?q=r2.jpg" />';
And here is the script on the authorized server, where the secret handshake ($_SESSION["image_link"]) is filled in correctly.
<?php // demo/watermark_test_hotlink.php
error_reporting(E_ALL);
// ALWAYS START THE SESSION ON EVERY PAGE
session_start();
// SET THE NAMES OF ALL OF THE IMAGES IN THIS FIELD OF THE SESSION
$_SESSION["noWaterMark"] = array();
$_SESSION["noWaterMark"][] = "r1.jpg";
$_SESSION["noWaterMark"][] = "r2.jpg";
// THESE TWO IMAGES WILL NOT BE WATERMARKED
echo '<image src="http://www.iconoun.com/demo/watermark_hotlinked_image.php?q=r1.jpg" />';
echo '<image src="http://www.iconoun.com/demo/watermark_hotlinked_image.php?q=r2.jpg" />';
// THIS IMAGE IS NOT LISTED IN THE SESSION - IT WILL BE WATERMARKED
echo '<image src="http://www.iconoun.com/demo/watermark_hotlinked_image.php?q=r3.jpg" />';
// THIS IMAGE DOES NOT EXIST
echo '<image src="http://www.iconoun.com/demo/watermark_hotlinked_image.php?q=bogus.jpg" />';
Testing When the Foreign and Authorized Scripts are on the Same Shared Server
<?php // demo/watermark_hotlinked_image.php
error_reporting(E_ALL);
ini_set('log_errors', TRUE);
// WRITES A WATERMARK OVER THE IMAGE IF
// THE FILE IS HOTLINKED BY A FOREIGN SITE
// THERE WILL BE A SIGNAL IN THE SESSION IF IT OK TO PRODUCE UN-WATERMARKED IMAGES
session_start();
// HARDWIRED: THE IMAGE DIRECTORY (OUTSIDE OF THE WEB ROOT)
$image_dir = '../root_images' . DIRECTORY_SEPARATOR;
// GET THE IMAGE NAME
$image_url = (isset($_GET['q'])) ? $_GET['q'] : NULL;
if (!$image_url) die();
// GET THE IMAGE NAME, EXTENSION AND HEADER TYPE FOR JPEG OR PNG
$image_ext = end(explode('.', $image_url));
$image_ext = strtolower($image_ext);
$image_hed = 'jpeg';
if ($image_ext == 'png') $image_hed = 'png';
// TEST IF IT IS OK TO PRODUCE UN-WATERMARKED IMAGES
$image_set = isset($_SESSION["noWaterMark"]) ? $_SESSION["noWaterMark"] : array();
if (in_array($image_url, $image_set))
{
// REMOVE THIS IMAGE FROM THE LIST
foreach ($image_set as $key => $image_nam)
{
if ($image_url == $image_nam)
{
unset($image_set[$key]);
break;
}
}
// REPLACE THE LIST IN THE SESSION ARRAY AND COMMIT THE SESSION
$_SESSION["noWaterMark"] = $image_set;
session_write_close();
// SEND THE UNWATERMARKED IMAGE - EITHER JPG OR PNG
header("Content-Type: image/$image_hed");
echo file_get_contents($image_dir . $image_url);
exit;
}
// GET THE IMAGE RESOURCE
$image_res = FALSE;
if ($image_hed == 'png') $image_res = ImageCreateFromPNG($image_dir . $image_url);
if ($image_hed == 'jpeg') $image_res = ImageCreateFromJPEG($image_dir . $image_url);
if (!$image_res) die();
// COMPUTE THE WATERMARK TEXT SIZE IN POINTS
$image_w = ImagesX($image_res);
$image_h = ImagesY($image_res);
$image_pct = $image_w / 100.0;
$image_size = round($image_pct * 2);
// SET THE WATERMARK TEXT
date_default_timezone_set('America/Chicago');
$image_wmk = '© ' . date('Y') . ' Ray Paseur';
// LOCATE THE FONT (VERDANA Z = BOLD ITALIC)
$font = 'fonts/verdanaz.ttf';
// PREPARE HORIZONTAL TEXT WITH ZERO ANGLE
$angle = 0;
// GET THE BOUNDING BOX SIZE FOR THE TEXT (DOES NOT INCLUDE DESCENDERS)
$poz = imageTTFBBox
( $image_size // SIZE IN POINTS
, $angle // ONLY WORKS RIGHT IF ANGLE = 0
, $font // PATH TO TTF FILE
, $image_wmk // TEXT
)
;
// GET THE WIDTH AND HEIGHT OF THE WATERMARK IMAGE WITH ROOM FOR DESCENDERS
$wmi_w = $poz[2] - $poz[0] + $image_size;
$wmi_h = $poz[1] - $poz[7] + $image_size;
// CREATE A TRUE COLOR WATERMARK IMAGE
$image_wmi = imageCreateTrueColor($wmi_w, $wmi_h);
// MAKE THE BACKGROUND, TEXT AND SHADOW COLORS
$wmi_bgc = imageColorAllocateAlpha($image_wmi, 0, 0, 0, 64);
$wmi_txt = imageColorAllocateAlpha($image_wmi, 224, 224, 224, 64);
$wmi_sh1 = imageColorAllocateAlpha($image_wmi, 128, 128, 128, 80);
$wmi_sh2 = imageColorAllocateAlpha($image_wmi, 96, 96, 96, 96);
$wmi_sh3 = imageColorAllocateAlpha($image_wmi, 80, 80, 80, 112);
imageFill($image_wmi, 0, 0, $wmi_bgc);
// SET SOME PADDING VALUES
$off_x = 6;
$off_y = (int)( $image_size / 2 ) + ( $off_x / 2);
// SHADOW THE TEXT ON THE WATERMARK IMAGE
imageTTFText
( $image_wmi // IMAGE RESOURCE
, $image_size // SIZE
, $angle // ANGLE
, $off_x + 3 // HORIZONTAL LEFTMOST BASEPOINT
, $wmi_h - $off_y + 3 // VERTICAL BASEPOINT
, $wmi_sh3 // COLOR INDEX
, $font // PATH TO TTF FILE
, $image_wmk // TEXT
)
;
// SHADOW THE TEXT ON THE WATERMARK IMAGE
imageTTFText
( $image_wmi // IMAGE RESOURCE
, $image_size // SIZE
, $angle // ANGLE
, $off_x + 2 // HORIZONTAL LEFTMOST BASEPOINT
, $wmi_h - $off_y + 2 // VERTICAL BASEPOINT
, $wmi_sh2 // COLOR INDEX
, $font // PATH TO TTF FILE
, $image_wmk // TEXT
)
;
// SHADOW THE TEXT ON THE WATERMARK IMAGE
imageTTFText
( $image_wmi // IMAGE RESOURCE
, $image_size // SIZE
, $angle // ANGLE
, $off_x + 1 // HORIZONTAL LEFTMOST BASEPOINT
, $wmi_h - $off_y + 1 // VERTICAL BASEPOINT
, $wmi_sh1 // COLOR INDEX
, $font // PATH TO TTF FILE
, $image_wmk // TEXT
)
;
// WRITE THE TEXT ON THE WATERMARK IMAGE
imageTTFText
( $image_wmi // IMAGE RESOURCE
, $image_size // SIZE
, $angle // ANGLE
, $off_x + 0 // HORIZONTAL LEFTMOST BASEPOINT
, $wmi_h - $off_y + 0 // VERTICAL BASEPOINT
, $wmi_txt // COLOR INDEX
, $font // PATH TO TTF FILE
, $image_wmk // TEXT
)
;
// PUT THE WATERMARK IN THE MIDDLE OF THE IMAGE
imageCopy
( $image_res // DESTINATION
, $image_wmi // SOURCE (WATERMARK)
, ($image_w / 2) - ($wmi_w / 2) // DESTINATION X-AXIS IN PIXELS
, ($image_h / 2) - ($wmi_h / 2) // DESTINATION Y-AXIS IN PIXELS
, 0 // SOURCE X-AXIS IN PIXELS
, 0 // SOURCE Y-AXIS IN PIXELS
, $wmi_w // SOURCE WIDTH
, $wmi_h // SOURCE HEIGHT
)
;
// RENDER THE IMAGES AND RELEASE THE MEMORY
header('Content-Type: image/png');
imagePNG($image_res);
imageDestroy($image_wmi);
imageDestroy($image_res);
You can copy this code, install it on your server (changing the $image_dir variable as needed) and test it out.
Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.
Comments (3)
Commented:
"Yes" vote above.
Vic
Commented:
Author
Commented: