There must be a better way to copy images and resize images

Hello PointSiters,

I use this script to pull across images and reszie them. However I think it might me a bit inefficient.

Is this a job for Perl.

<html>
<head>
<meta http-equiv="refresh" content="10">
</head>
</html>
<body>
<?
include "connect.inc.php";
include "config.inc.php";

// How many left
$query="SELECT property.property_id, property_photo_id, property_photo_url from property, property_photo WHERE
property.property_id = property_photo.property_id
AND property_photo_processed = '0'";
$result=mysql_query($query);
$rows = mysql_num_rows($result);

echo $rows.' photos left to process <br />';


$query="SELECT property.property_id, property_photo_id, property_photo_url from property, property_photo WHERE
property.property_id = property_photo.property_id
AND property_photo_processed = '0' LIMIT 4";
$result=mysql_query($query);

while ($array=mysql_fetch_assoc($result)) {

$property_photo_id = $array['property_photo_id'];
$property_id = $array['property_id'];
$property_photo_url = $array['property_photo_url'];


echo "property photo id is $property_photo_id <br>";
//if folder doesn't exist create

if (file_exists("../property_pics/$property_id") && is_dir("../property_pics/$property_id")) {
		print '<br>'.$property_id . ' is a directory!';
		}
		else {
		print '<br>'.$property_id . ' is not directory Creating';

		mkdir("../property_pics/$property_id",0777);
		mkdir("../property_pics/$property_id/700",0777);
		mkdir("../property_pics/$property_id/580",0777);
		mkdir("../property_pics/$property_id/400",0777);
		mkdir("../property_pics/$property_id/100",0777);

		chmod("../property_pics/$property_id", 0777);
		chmod("../property_pics/$property_id/700", 0777);
		chmod("../property_pics/$property_id/580", 0777);
		chmod("../property_pics/$property_id/400", 0777);
		chmod("../property_pics/$property_id/100", 0777);
		
		}
		
	//write original image
	$content = file_get_contents($property_photo_url);
	
	
	$dir = dirname($_SERVER['SCRIPT_FILENAME']);
	
	$filename = $property_id.'-'.$property_photo_id.'.jpg';
	$file = $dir.'/../property_pics/'.$property_id.'/'.$filename;
	
	
	$fp = fopen($dir.'/../property_pics/'.$property_id.'/'.$property_id.'-'.$property_photo_id.'.jpg', 'w');
	fwrite($fp, $content);
	fclose($fp);
	
	$file_type = exif_imagetype($file);
	if ($file_type != IMAGETYPE_JPEG) {
	    echo "The picture is not a jpeg <br /> it is a $file_type";
	}
	else {
		echo 'The picture is a jpeg <br />';
	}
	
	echo "<img src=\\"$site_url/property_pics/$property_id/$property_id-$property_photo_id.jpg\\"><br>";
	
	
	// resize picture
	
	//Saves 700px version
        $save = "../property_pics/$property_id/700/$property_id-$property_photo_id.jpg";
        //$file = "pics/$property_id/".$imagepath; //This is the original file
        list($width, $height) = getimagesize($file) ;
        $modwidth = 700;
        $diff = $width / $modwidth;
        $modheight = $height / $diff;
        $tn = imagecreatetruecolor($modwidth, $modheight) ;
        $image = imagecreatefromjpeg($file) ;
        imagecopyresampled($tn, $image, 0, 0, 0, 0, $modwidth, $modheight, $width, $height) ;
        imagejpeg($tn, $save, 100) ;
        echo "700px<img src=\\"$site_url/property_pics/$property_id/700/$property_id-$property_photo_id.jpg\\"><br />";
	
	
	//Saves 580px version
        $save = "../property_pics/$property_id/580/$property_id-$property_photo_id.jpg";
        //$file = "pics/$property_id/".$imagepath; //This is the original file
        list($width, $height) = getimagesize($file) ;
        $modwidth = 580;
        $diff = $width / $modwidth;
        $modheight = $height / $diff;
        $tn = imagecreatetruecolor($modwidth, $modheight) ;
        $image = imagecreatefromjpeg($file) ;
        imagecopyresampled($tn, $image, 0, 0, 0, 0, $modwidth, $modheight, $width, $height) ;
        imagejpeg($tn, $save, 100) ;
        echo "580px<img src=\\"$site_url/property_pics/$property_id/580/$property_id-$property_photo_id.jpg\\"><br />";
	
	
	
	
	//Saves 400px version
        $save = "../property_pics/$property_id/400/$property_id-$property_photo_id.jpg";
        //$file = "pics/$property_id/".$imagepath; //This is the original file
        list($width, $height) = getimagesize($file) ;
        $modwidth = 400;
        $diff = $width / $modwidth;
        $modheight = $height / $diff;
        $tn = imagecreatetruecolor($modwidth, $modheight) ;
        $image = imagecreatefromjpeg($file) ;
        imagecopyresampled($tn, $image, 0, 0, 0, 0, $modwidth, $modheight, $width, $height) ;
        imagejpeg($tn, $save, 100) ;
        echo "400px<img src=\\"$site_url/property_pics/$property_id/400/$property_id-$property_photo_id.jpg\\"><br />";


 	


	   //Saves 100px version
        $save = "../property_pics/$property_id/100/$property_id-$property_photo_id.jpg";
	list($width, $height) = getimagesize($file) ;
        $modheight = 100;
        $diff = $height / $modheight;
        $modwidth = $width / $diff;
        $tn = imagecreatetruecolor($modwidth, $modheight) ;
        $image = imagecreatefromjpeg($file) ;
        imagecopyresampled($tn, $image, 0, 0, 0, 0, $modwidth, $modheight, $width, $height) ;
        imagejpeg($tn, $save, 100) ;
	echo "100px<img src=\\"$site_url/property_pics/$property_id/100/$property_id-$property_photo_id.jpg\\"><br />";
	
	
	
              $property_photo_filename = "$property_id-$property_photo_id.jpg";
              $update_query = "UPDATE property_photo SET property_photo_filename = '$property_photo_filename', property_photo_processed = '1' WHERE property_photo_id = '$property_photo_id'";
              echo "update query is $update_query<br>";
              mysql_query($update_query);
             //change directory back
             chmod("../property_pics/$property_id", 0755);

}


?>
</body>
</html>

In your case if you have imagemagick installed you could do all the resizing on one line reading the input file once. I wonder if the same can be done with GD?


<?php
$cmd = " input.jpg \\( -clone 0 -thumbnail x480 -write 480_wide.jpg +delete \\)".
" \\( -clone 0 -thumbnail x250 -write 250_wide.jpg +delete \\) ".
" \\( -clone 0 -thumbnail x100 -write 100_wide.jpg +delete \\) -thumbnail 64x64! null: ";
exec("convert $cmd 64_square.jpg ");
?>

I do not know why but on some systems you need the null: at the end and on others the null: causes problems!

OK that’s good, but it doesn’t really get to the heart of the problem.

I have 44000 images to process.

I am running the script everytime the page refreshes (Every 10 seconds).

Is there a quicker way to do this?

Have you considered using a service like Sencha io src to handle the resizing for you at the time of request? I don’t know all the little details but that seems like it would be much simpler. Either use a service like that or create your own so that the images are resized when a particular size is requested. Upon first request cache and save as a physical copy on disk which is referenced there after.

As for using exec unless you know that you can execute commands from php than that seems like a bad idea. I don’t think most hosting providers allow that. I guess the practicality would depend on environment/server set-up details.

There is also a little more clever way this can be done though some sacrifies need to be made. The first is to apply the images as backgrounds to divs rather than using the image tag. The second is implementing all variations of background-size CSS property. Older IE versions do support it in filter format. Than you can merely size a div with CSS, apply the image as a background and have CSS resize it to fit within the allocated area defined by the div without any stretching. The technique works perfectly for images of all sizes, vertical or horizontal orientation. Depends on what you are willing to sacrifice though.

I think any one of those methods are better than filling up disk space with variations and having to manage them. Though I don’t really know any of the hard details. So all I can really go on is my experience with achieving the same goal.

OK. Am a bit out of my element on this one, but I woudl figure if you really are running resizing script more than TWICE. That it woudl be inefficient even with only one line of code.

Have you considered resizing the images at a specific moment ( upload), or better yet:
if (!file_exist(‘img_thmb.jpg’) && file_exist(‘img.jpg’)){ run resizing scrip which converts big image into thumb, and saves it in the resized images folder, then returns the thumbnail;}
elseif(file_exist(‘img.jpg’)){return the image from he thumbs folder;}
else { there is o image at all… do you ant to upload it?}

hope that helps

The images already exist. So a script is being created to crawl them and resize. Unless you are referring to building an upload form to manually upload 44,000 :confused: – that would be crazy.

Left the computer on all night…38854 photos left to process.

The photos are being pulled from web locations…there is no uploading involved.

How about just copying the photos, is there a faster way to do that than my refresh method?

Have you considered leaving the images as-is on the sever and then using GD_LIB to resize/resample them on the fly, just when they are being displayed? Or perhaps your requirement for resizing the images is different…

Jeff Cohan

The fastest solution is going to be to execute a script locally on the machine the hosts the images. As long as this is a one time deal, best to start thinking about this as a non web project, though a language such as PHP can still be used. You’ll want to launch your code from command line rather than through a web browser.

Perl, PHP, etc, all the same. Just get yourself into the command line scene and away from the web browser.

Rather than running this as a script that runs everytime the page reloads, would it be possible to run this as a cron job?