Watermark fail

Ok Something is wrong. I am trying to take a watermark and put it on an image then return the watermarked image to the browser. However if it places the watermark right, it doesn’t show all of it, and sometimes it puts blank squares all over. the following is the script in its test form:


<?php
/**
* Display an image to the browser with a watermark
*
* @author Ryan Pallas
* @version v0.5
* @since v0.6
*/
$num = ( ISSET($_GET['num']) && is_numeric($_GET['num']) ) ? (int) $_GET['num'] : '';
/**
 * @var int bottom margin
 */
$marginbot = 10;

/**
 * @var int right margin
 */
$marginright = 10;


/**
 * @var string base image file with full path
 */
//$base = $this->config->item('upload_path') . DIRECTORY_SEPARATOR . $folder . DIRECTORY_SEPARATOR .$img->image_filename . '.' . $img->image_ext;
if( $num == '' || $num == '1' || $num == '3' ) {
   $base = 'test' . $num . '.jpg';
} elseif( $num == '2' ) {
   $base = 'test' . $num . '.png';
} else {
   DIE('Fatal Error');
}

/**
 * @var string watermark image with full path
 */
//$watermark = $this->config->item('upload_path') . 'watermark.png';
$watermark = "watermark.png";

/**
 * @var array base image info
 */
$baseinfo = getimagesize($base);
list($baseh,$basew,$baset) = $baseinfo;

/**
 * @var array watermark image info
 */
$wminfo = getimagesize($watermark);
list($wmh,$wmw) = $wminfo;


if( (($wmw*2) > $basew) || (($wmh*2) > $baseh) ) {
	if( $basew > $baseh ) {
		$wmscale = ($basew/2)/$wmw;
	} else {
		$wmscale = ($baseh/2)/$wmh;
	}
	$newwmw = $wmw*$wmscale;
	$newwmh = $wmh*$wmscale;
} else {
	$newwmh = $wmh;
	$newwmw = $wmw;
}


/**
 * determine file type for correct functions
 */
switch($baset)
	{ 
	case IMAGETYPE_JPEG: 
		$create = "imagecreatefromjpeg"; 
		break; 
	case IMAGETYPE_GIF: 
		$create = "imagecreatefromgif"; 
		break; 
	case IMAGETYPE_PNG: 
		$create = "imagecreatefrompng"; 
		break; 
	case IMAGETYPE_WBMP: 
		$create = "imagecreatefromwbmp"; 
		break; 
	default: 
		return FALSE; 
}

/**
 * create image
 */
$baseimg = $create($base);

$wmimg = imagecreatefrompng($watermark);
$newwmimg = imagecreate($newwmw,$newwmh);
imagecopyresized($newwmimg,$wmimg,0,0,0,0,$newwmw,$newwmh,$wmw,$wmh);

imagecopy($baseimg,$newwmimg,($basew-$newwmw-$marginright),($baseh-$newwmh-$marginbot),0,0,$newwmw,$newwmh);
// Output and free memory
header('Content-type: image/png');
imagepng($baseimg);

You can see the examples at http://dev.rdennispallas.com/test.php?num=3 (replace 3 with 2, 1 and remove the query string for 4 different images). The problem is on one image it looks goo except it doesn’t show the whole water mark, on the others it is thowing up black squares all over the place so I did something wrong. Hopefully someone can tell me where I screwed up.

TYIA

I pressume the blac boxes are where your watermark should be ? You are losing the transparency of the watermark somewhere.

This is some very old code of mine and it looks like I use imagecopymerge not imagecopy. Unsure how it works now as I use Imagemagick.

As to your position problem I would echo out the variables to confirm you are getting what you expect as there could be a problem with your calculations.

<?php
// Create the canvas
$canvas = imagecreate( 200, 100 );  
// Define the colours to use
$black = imagecolorallocate( $canvas, 0, 0, 0 );  
$white = imagecolorallocate( $canvas, 255, 255, 255 );  
// Create a rectangle and fill it white
imagefilledrectangle( $canvas, 0, 0, 200, 100, $white );  
// The path to the font
$font = "verdana.ttf"; 
// The text to use 
$text = "House"; 
// The font size 
$size = "30";   
// Set the path to the image to watermark
$input_image = "House.jpg"; 
// Calculate the size of the text 
// If php has been setup without ttf support this will not work.
$box = imagettfbbox( $size, 0, $font, $text );  
$x = (200 - ($box[2] - $box[0])) / 2;  
$y = (100 - ($box[1] - $box[7])) / 2;  
$y -= $box[7];  
// Add the text to the image
imageTTFText( $canvas, $size, 0, $x, $y, $black, $font, $text );  
// Make white transparent
imagecolortransparent ( $canvas, $white );  
// Save the text image as temp.png
imagepng( $canvas, "temp.png" );  
// Cleanup the tempory image canvas.png
ImageDestroy( $canvas );  
// Read in the text watermark image
$watermark = imagecreatefrompng( "temp.png" );  
// Returns the width of the given image resource  
$watermark_width = imagesx( $watermark );
//Returns the height of the given image resource    
$watermark_height = imagesy( $watermark );    
$image = imagecreatetruecolor( $watermark_width, $watermark_height );    
$image = imagecreatefromjpeg( $input_image );
// Find the size of the original image and read it into an array      
$size = getimagesize( $input_image );  
// Set the positions of the watermark on the image
$dest_x = $size[0] - $watermark_width - 100;    
$dest_y = $size[1] - $watermark_height - 200;    
imagecopymerge($image, $watermark, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height, 50);   
// Save the watermarked image as watermarked.jpg 
imagejpeg( $image, "watermarked.jpg" );
// Clear the memory of the tempory image     
imagedestroy( $image );    
imagedestroy( $watermark );    
// Delete the text watermark image
unlink( "temp.png");  
?> 

Ok I’ve identified the problem as:


if( (($wmw*2) > $basew) || (($wmh*2) > $baseh) ) {
    if( $basew > $baseh ) {
        $wmscale = ($basew/2)/$wmw;
    } else {
        $wmscale = ($baseh/2)/$wmh;
    }
    $newwmw = $wmw*$wmscale;
    $newwmh = $wmh*$wmscale;
} else {
    $newwmh = $wmh;
    $newwmw = $wmw;
}

However when I do the calculations with the same numbers as a certain image on the calculator I get the right values in the end. Something is wrong with my math and well… I am boggled by it.

Nvm got it working, the problem was actually when i assigned the width and height, i used list with height first instead of width…

/punch self

As I said echo the variables to see what you are getting; try it on a page of its own so you do not have to run through the other code.

When you have it working put it back into your full code.