Page 1 of 1

Alternative to Imagick?

Posted: 2011-03-29T01:46:44-07:00
by webchap
Hi there, I have recently taken over a website for a client and their site uses Image Magick and the Imagick module to re-size and upload images.

I can add a new product to the database, the record goes in fine, as does the image file name into the MySQL database but the actual physical image does not get uploaded.

After looking at the logs it appears that although Image Magick is installed, the Imagick module is not. I have asked my hosts to add it but they say as it is on a shared hosting package they will not add it for security reasons.

Now I am new to PHP so am struggling to find al alternative on how to get these images up. Here is the code I am currently using:

I have this at the top

Code: Select all

<?php
	$uploadedfile = $_FILES['userfile']['tmp_name'];
	//$uploadedfile_dimensions = getimagesize($uploadedfile);
then the rest of the page and then

Code: Select all

}
	if(is_uploaded_file($_FILES['image']['tmp_name']))
	{
		$image = new Imagick($_FILES['image']['tmp_name']);
		$maxWidth = 250;
		$maxHeight = 250;
		if(($maxWidth/$image->getImageWidth()) < ($maxHeight/$image->getImageHeight()))
			$maxHeight = 0;
		else
			$maxWidth = 0;
		$image->thumbnailImage($maxWidth, $maxHeight);
		$image->writeImage($_SERVER['DOCUMENT_ROOT'].'/product_images/'.$product_id.'-'.$product_version.'_large.jpg');
		$maxWidth = 180;
		$maxHeight = 180;
		if(($maxWidth/$image->getImageWidth()) < ($maxHeight/$image->getImageHeight()))
			$maxHeight = 0;
		else
			$maxWidth = 0;
		$image->thumbnailImage($maxWidth, $maxHeight);
		$image->writeImage($_SERVER['DOCUMENT_ROOT'].'/product_images/'.$product_id.'-'.$product_version.'_small.jpg');
	}
	else if(isset($_REQUEST['product_id']) && (int)$_REQUEST['product_id'] > 0)
	{
		$old_product_version = $product_version - 1;
		copy($_SERVER['DOCUMENT_ROOT'].'/product_images/'.$product_id.'-'.$old_product_version.'_large.jpg', $_SERVER['DOCUMENT_ROOT'].'/product_images/'.$product_id.'-'.$product_version.'_large.jpg');
		copy($_SERVER['DOCUMENT_ROOT'].'/product_images/'.$product_id.'-'.$old_product_version.'_small.jpg', $_SERVER['DOCUMENT_ROOT'].'/product_images/'.$product_id.'-'.$product_version.'_small.jpg');
	}
	echo 'SUCCESS';
?> 
Have read that GD may be an alternative but wouldn't know where to start to be honest. Used to ASP and Windows sevrers.

Any help would be most welcome.

Re: Alternative to Imagick?

Posted: 2011-03-29T02:39:43-07:00
by Bonzo
I had shared hosting and they did not want to install Imagick either.

If safe mode is off I would use Imagemagick with exec( ) as long as that is not disabled !

Lots of examples of the above method on my site. If there is a problem with safe mode and exec( ) I would recomend moving hosts.

Re: Alternative to Imagick?

Posted: 2011-03-29T02:49:56-07:00
by Bonzo
Ment to say you can use GD but it involves a lot more code and does not have as many options.
Some comparisons here: http://www.rubblewebs.co.uk/imagemagick/compair.php and I do have a few other GD examples on my site.

Re: Alternative to Imagick?

Posted: 2011-03-29T02:58:10-07:00
by webchap
Many thanks for the replies. As you can see from the code it is taking the uploaded image and creating a large and small version then uploading these images to a 'product_images' folder whilst recording the name of the images in the database against that product.

What I am really struggling with is the sheer amount of options available on lots of tutorial site, including your own excellent one. It is finding the actual right example code to use and after looking at ASP for many years, PHP looks like chinese to me at the moment lol

Lots of the examples will sort out the image re-sizig but are not referencing being uploaded to a folder with the file name recorded to the database etc.

The host does have GD installed so looks like that is the best way to go I would imagine.

There was me thinking it would be a simple upload the site to new server and job done! The jobs you think will take 5 minutes always take the longest :(

Re: Alternative to Imagick?

Posted: 2011-03-29T03:02:21-07:00
by Bonzo
The original code can be reduced but I can not look at it until later.

Check that safe mode is off and exec is not disabled otherwise its not worth looking at.

Re: Alternative to Imagick?

Posted: 2011-03-29T03:13:14-07:00
by webchap
Thanks for the help.

Just looked at the info.php file and it has this listed:
disable_functions
system, exec, shell_exec, passthru, escapeshellcmd, popen, pcntl_exec
and
safe_mode - Off
safe_mode_exec_dir - no value
safe_mode_gid - Off
safe_mode_include_dir - no value
so I guess that is a no go? :(

Re: Alternative to Imagick?

Posted: 2011-03-29T05:02:50-07:00
by Bonzo
Yes the disabled exec( ) is a problem. You will have to use GD now rather than Imagemagick or change hosts.

A bit of GD resizing code with comments - do not forget to change the directory permissions you are saving the images in.

Code: Select all

<?php
// Set the path to the image to resize
$input_image = "House.jpg";
// Get the size of the original image into an array
$size = getimagesize( $input_image );
// Set the new width of the image
$thumb_width = "200";
// Calculate the height of the new image to keep the aspect ratio
$thumb_height = ( int )(( $thumb_width/$size[0] )*$size[1] );
// Create a new true color image in the memory
$thumbnail = ImageCreateTrueColor( $thumb_width, $thumb_height );
// Create a new image from file 
$src_img = ImageCreateFromJPEG( $input_image );
// Create the resized image
ImageCopyResampled( $thumbnail, $src_img, 0, 0, 0, 0, $thumb_width, $thumb_height, $size[0], $size[1] );
// Save the image as resized.jpg
ImageJPEG( $thumbnail, "resized.jpg" );
// Clear the memory of the tempory image 
ImageDestroy( $thumbnail );
?> 

Re: Alternative to Imagick?

Posted: 2011-03-29T05:16:44-07:00
by webchap
Thanks for the reply, I did see that example.

I truly have no idea though which parts of the current code I need to rip out and which parts of the new code I need to add in and in what place.

I don't have enough PHP knowledge to know unfortunately.

With the sample code it refers to House.jpg and resized.jpg how do I get them to create random file names and insert the values into the database?

Re: Alternative to Imagick?

Posted: 2011-03-29T12:49:16-07:00
by Bonzo
Been out to daughters play tonight so just a quick reply:

Code: Select all

// If the file has been uploaded run this
if(is_uploaded_file($_FILES['image']['tmp_name']))
   {

// Put the uploaded image tempory filename into a variable   
$input_image = $_FILES['image']['tmp_name']

// Get the file dimensions of the uploaded file into an array - we are interested in the width $size[0] and height $size[1]
$size = getimagesize( $input_image );

// Setup some variables - I think it makes the code easier to read if long paths are outside the functions in a variable
$thumb_width = '180';
$thumb_save = $_SERVER['DOCUMENT_ROOT'].'/product_images/'.$product_id.'-'.$product_version.'_small.jpg';
$large_width = '250';
$large_save = $_SERVER['DOCUMENT_ROOT'].'/product_images/'.$product_id.'-'.$product_version.'_small.jpg'

// Create thumbnail
$thumb_height = ( int )(( $thumb_width/$size[0] )*$size[1] );
$thumbnail = ImageCreateTrueColor( $thumb_width, $thumb_height );
$src_img = ImageCreateFromJPEG( $input_image );
ImageCopyResampled( $thumbnail, $src_img, 0, 0, 0, 0, $thumb_width, $thumb_height, $size[0], $size[1] );
ImageJPEG( $thumbnail, $thumb_save );
ImageDestroy( $thumbnail );

// Create large
$large_height = ( int )(( $large_width/$size[0] )*$size[1] );
$large = ImageCreateTrueColor( $large_width, $large_height );
$src_img = ImageCreateFromJPEG( $input_image );
ImageCopyResampled( $large, $src_img, 0, 0, 0, 0, $large_width, $large_height, $size[0], $size[1] );
ImageJPEG( $large, $large_save );
ImageDestroy( $large );
   }
   
// Do not know what this bit below is about - would have been helpful if the original developer had added comments
// looks like it is copying and old file over a new one ?
   else if(isset($_REQUEST['product_id']) && (int)$_REQUEST['product_id'] > 0)
   {
      $old_product_version = $product_version - 1;
      copy($_SERVER['DOCUMENT_ROOT'].'/product_images/'.$product_id.'-'.$old_product_version.'_large.jpg', $_SERVER['DOCUMENT_ROOT'].'/product_images/'.$product_id.'-'.$product_version.'_large.jpg');
      copy($_SERVER['DOCUMENT_ROOT'].'/product_images/'.$product_id.'-'.$old_product_version.'_small.jpg', $_SERVER['DOCUMENT_ROOT'].'/product_images/'.$product_id.'-'.$product_version.'_small.jpg');
   }
   echo 'SUCCESS';
// To be correct you should check the file is actualy saved with something like file_exists( ) although that sometimes will not work
// so could use something like if(fopen($thumb_save, 'r')) echo "Thumbnail sucess"; else echo "Thumbnail fail"; if(fopen($thumb_save, 'r')) echo "Large sucess"; else echo "Large fail";  - UNTESTED
// You can add echos through the code to confirm variable contents especialy good to check file save paths etc. 
// e.g. echo $thumb_save; after this line $thumb_save = $_SERVER['DOCUMENT_ROOT'].'/product_images/'.$product_id.'-'.$product_version.'_small.jpg';
The resize part could be put into a user function which would reduce the amount of code. All the above is untested.

My daughter said I have to put this :lol:

Re: Alternative to Imagick?

Posted: 2011-03-29T13:14:27-07:00
by webchap
Thank you so much for taking the time to do that for me, and thank your daughter.

With the complete page here (your code instead of the previous):

Code: Select all

<?php
	$uploadedfile = $_FILES['userfile']['tmp_name'];

	//$uploadedfile_dimensions = getimagesize($uploadedfile);

	require "./admin_header.php";

	$category = mysql_real_escape_string($_REQUEST['category']);

	$title = mysql_real_escape_string($_REQUEST['title']);
	$author = mysql_real_escape_string($_REQUEST['author']);
	$designer_id = mysql_real_escape_string($_REQUEST['designer_id']);
	$designer_name = mysql_real_escape_string($_REQUEST['designer_name']);
	$description = mysql_real_escape_string($_REQUEST['description']);
	$publisher = mysql_real_escape_string($_REQUEST['publisher']);
	$pages_desctiption = mysql_real_escape_string($_REQUEST['pages_description']);
	$binding = mysql_real_escape_string($_REQUEST['binding']);
	$illustrations = mysql_real_escape_string($_REQUEST['illustrations']);
	$age_range = mysql_real_escape_string($_REQUEST['age_range']);
	$composition = mysql_real_escape_string($_REQUEST['composition']);
	$materials = mysql_real_escape_string($_REQUEST['materials']);
	$size = mysql_real_escape_string($_REQUEST['size']);
	$brand = mysql_real_escape_string($_REQUEST['brand']);
	$country_of_origin = mysql_real_escape_string($_REQUEST['country_of_origin']);

	if(isset($_REQUEST['product_id']) && (int)$_REQUEST['product_id'] > 0)
		$product_id = (int)$_REQUEST['product_id'];
	else
		list($product_id) = mysql_fetch_row(mysql_query('SELECT MAX(product_id) + 1 FROM products'));

	mysql_query('
	INSERT INTO products (
		product_id, 
		title, 
		description, 
		author, 
		publisher, 
		pages, 
		binding, 
		illustrations, 
		designer_id,
		designer_name,
		composition,
		materials,
		size,
		brand,
		country_of_origin,
		suggested_age_range
	)
	VALUES (
		'.$product_id.',
		"'.$title.'",
		"'.$description.'",
		"'.$author.'",
		"'.$publisher.'",
		"'.$pages_desctiption.'",
		"'.$binding.'",
		"'.$illustrations.'",
		"'.$designer_id.'",
		"'.$designer_name.'",
		"'.$composition.'",
		"'.$materials.'",
		"'.$size.'",
		"'.$brand.'",
		"'.$country_of_origin.'",
		"'.$age_range.'"
	)
	');

	$product_version = mysql_insert_id();

	if(!isset($_REQUEST['product_id']) || (int)$_REQUEST['product_id'] < 1)
	{
		mysql_query('
			INSERT INTO product_status (
				product_id,
				category,
				show_on_website,
				new
			)
			VALUES (
				'.$product_id.',
				"'.$category.'",
				1,
				1
			)
		');

		echo mysql_error();
	}

	for($i = 0; $i < count($_REQUEST['price']); $i++)
	{
		$variant = mysql_real_escape_string($_REQUEST['variant'][$i]);
		$price = mysql_real_escape_string($_REQUEST['price'][$i]);
		$show_item = ($_REQUEST['show_item'][$i] == 'on')? 'true':'false';

		if($price != '')
		{
			mysql_query('
				INSERT INTO prices (product_id, version, variant_description, price_inc_vat)
				VALUES (
					'.$product_id.',
					'.$product_version.',
					"'.$variant.'",
					"'.$price.'"
				)
			');
		}
	}

	// If the file has been uploaded run this
if(is_uploaded_file($_FILES['image']['tmp_name']))
   {

// Put the uploaded image tempory filename into a variable   
$input_image = $_FILES['image']['tmp_name']

// Get the file dimensions of the uploaded file into an array - we are interested in the width $size[0] and height $size[1]
$size = getimagesize( $input_image );

// Setup some variables - I think it makes the code easier to read if long paths are outside the functions in a variable
$thumb_width = '180';
$thumb_save = $_SERVER['DOCUMENT_ROOT'].'/product_images/'.$product_id.'-'.$product_version.'_small.jpg';
$large_width = '250';
$large_save = $_SERVER['DOCUMENT_ROOT'].'/product_images/'.$product_id.'-'.$product_version.'_small.jpg'

// Create thumbnail
$thumb_height = ( int )(( $thumb_width/$size[0] )*$size[1] );
$thumbnail = ImageCreateTrueColor( $thumb_width, $thumb_height );
$src_img = ImageCreateFromJPEG( $input_image );
ImageCopyResampled( $thumbnail, $src_img, 0, 0, 0, 0, $thumb_width, $thumb_height, $size[0], $size[1] );
ImageJPEG( $thumbnail, $thumb_save );
ImageDestroy( $thumbnail );

// Create large
$large_height = ( int )(( $large_width/$size[0] )*$size[1] );
$large = ImageCreateTrueColor( $large_width, $large_height );
$src_img = ImageCreateFromJPEG( $input_image );
ImageCopyResampled( $large, $src_img, 0, 0, 0, 0, $large_width, $large_height, $size[0], $size[1] );
ImageJPEG( $large, $large_save );
ImageDestroy( $large );
   }
   
   // Do not know what this bit below is about - would have been helpful if the original developer had added comments
   else if(isset($_REQUEST['product_id']) && (int)$_REQUEST['product_id'] > 0)
   {
      $old_product_version = $product_version - 1;
      copy($_SERVER['DOCUMENT_ROOT'].'/product_images/'.$product_id.'-'.$old_product_version.'_large.jpg', $_SERVER['DOCUMENT_ROOT'].'/product_images/'.$product_id.'-'.$product_version.'_large.jpg');
      copy($_SERVER['DOCUMENT_ROOT'].'/product_images/'.$product_id.'-'.$old_product_version.'_small.jpg', $_SERVER['DOCUMENT_ROOT'].'/product_images/'.$product_id.'-'.$product_version.'_small.jpg');
   }
   echo 'SUCCESS';
// To be correct you should check the file is actualy saved with something like file_exists( ) although that sometimes will not work
// so could use something like if(fopen($thumb_save, 'r')) echo "Thumbnail sucess"; else echo "Thumbnail fail"; if(fopen($thumb_save, 'r')) echo "Large sucess"; else echo "Large fail";  - UNTESTED
// You can add echos through the code to confirm variable contents especialy good to check file save paths etc. 
// e.g. echo $thumb_save; after this line $thumb_save = $_SERVER['DOCUMENT_ROOT'].'/product_images/'.$product_id.'-'.$product_version.'_small.jpg';
?>

I get syntax errors on these 2 lines flag up in Dreamweaver:

Code: Select all

$size = getimagesize( $input_image );
and

Code: Select all

$thumb_height = ( int )(( $thumb_width/$size[0] )*$size[1] );
Am thinking I may need to amend the code at the top as this is possibly referencing the Imagick?

I tried to add a new product with this full page and got this in the logs

Code: Select all

PHP Parse error:  syntax error, unexpected T_VARIABLE in /home/wozwebs/public_html/admin/save_product.php on line 120


where line 120 is

Code: Select all

$size = getimagesize( $input_image );
I don't think it's far away. Will keep meddling. Thanks again

Re: Alternative to Imagick?

Posted: 2011-03-29T13:21:35-07:00
by Bonzo
My mistake:

These lines are missing a ; all lines in php end with a ;

Code: Select all


$input_image = $_FILES['image']['tmp_name']

$large_save = $_SERVER['DOCUMENT_ROOT'].'/product_images/'.$product_id.'-'.$product_version.'_small.jpg'


Re: Alternative to Imagick?

Posted: 2011-03-29T13:58:27-07:00
by webchap
Bonzo - I can't thank you enough (and your daughter)!!

Works like a dream :)

Just tried adding a new product and it works fine and also editing a current image goes in fine too.

I owe you one! :) Very much appreciated.

Re: Alternative to Imagick?

Posted: 2011-03-29T14:02:16-07:00
by Bonzo
I am glad its all working OK - I also hope you get on well with php.