Solved

Issue width JPG upload with conversion to PNG in php

Posted on 2013-01-14
9
424 Views
Last Modified: 2013-01-25
I'm getting some odd behavior with an image upload function I have.  I can't seem to see where it is coming from and was hoping someone could take a look.

I have a function which I call to resize and convert images to png.  I have a parameter option to take the passed width and height and center/resize the passed image to that width and height width transparency to either the left and right or top and bottom.

So if I have an image (.jpg or .png) which is 400px X 200px and I pass the width and height of 200px X 200px.  I would end up with a 200px X 200px .png with the top 50px transparent and the bottom 50px transparent.

I am getting almost that exact behavior with exception to 2 end results.

1. If the image is wider then the destination width and height (ratio wise) then I get a 1px X 1px black dot in the 0px X 0px location with a black line just above my original image (save for the first pixel on the right which is transparent)

So input (820px X 520px all blue image with the function call
upload($location, 801, 543, 2)

Open in new window

)
output  (http://dansdomain.com/Test/result-wider.png)

2. If the image is taller then the destination width and height (ratio wise) then I get a .png image which is 100% as expected with exception to a black pixel at the location 1px X 1px.  

So input (790px X 600px all blue image with the function call
upload($location, 801, 543, 2)

Open in new window

)

output (http://dansdomain.com/Test/result-taller.png)

Here is my function:

if(!function_exists("upload")){
	//$image = $image file name
	//$width = intended width of resized image, if 0 it will proportion to height, overrides proportion
	//$height = intended width of resized image, if 0 it will proportion to width, overrides proportion
	//$proportion = 2,1,0;
	//------ 2 = Preserve proportions while adding a border to fill width and height  
	//------ 1 = retain proportion to fit within both given width and height
	//------ 0 = disregard proportions and resize to the exact width and height
	
	
	function upload($image, $width, $height, $proportion){
		// IS GD HERE?
		
		$gdv = get_gd_info();
		
		if (!$gdv){ 
			return FALSE;
		}
		
		// GET AN IMAGE THING
		
		$ext = trim(strtolower(end(explode('.', $image))));
		
		list($imageX, $imageY, $type) = getimagesize($image);	//gets information about new server image
				
		// GET THE LESSER OF THE RATIO OF THUMBNAIL H OR W DIMENSIONS
		$ratio_w = ($width / $imageX);
		$ratio_h = ($height / $imageY);
		$ratio   = ($ratio_w < $ratio_h) ? $ratio_w : $ratio_h;		
		
		if($width == 0){
			
			if($imageY > $height){
				$newHeight = $height;
				$newWidth = ($height/$imageY) * $imageX;	
			}else{
				$newHeight = $imageY;
				$newWidth = $imageX;	
			}
			
			$width = $newWidth;
			$height = $newHeight;
			
			// COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS
			$fromMidX = 0;
			$fromMidY = 0;
			
		}elseif($height == 0){
			
			if ($imageX > $width){
				$newWidth = $width;
				$newHeight = ($width/$imageX) * $imageY;
			}else{
				$newHeight = $imageY;
				$newWidth = $imageX;	
			}
			
			$width = $newWidth;
			$height = $newHeight;
			
			// COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS
			$fromMidX = 0;
			$fromMidY = 0;
			
		}elseif($proportion == 2){
			
			// COMPUTE THUMBNAIL IMAGE DIMENSIONS
			$newWidth = $imageX * $ratio;
			$newHeight = $imageY * $ratio;
			
			
			
			
			// COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS
			$fromMidX = ($width - $newWidth) / 2.0;
			$fromMidY = ($height - $newHeight) / 2.0;
			
			
		}elseif($proportion == 1){
			
			if ($imageX > $width){
				$newHeight = ($width/$imageX) * $imageY;
				$newWidth = $width;
			}
			if ($imageY > $height){
				$newHeight = $height;
				$newWidth = ($height/$imageY) * $imageX;
			}
			
			$fromMidY = 0;
			$fromMidX = 0;
			
		}elseif($proportion == 0){
			
			$newWidth = $width;
			$newHeight = $height;
			
			$fromMidY = 0;
			$fromMidX = 0;			
		}
		
		switch($type)
		{
			case '2' :
				$source = imagecreatefromjpeg($image);
				break;
			case '3' :
				$source = imagecreatefrompng($image);
				break;
			default : die("UNKNOWN IMAGE TYPE: $image");
		}
		
		// WHICH FUNCTIONS CAN RESIZE / RESAMPLE THE IMAGE?
		if ($gdv >= 2)
		{

			// IF GD IS AT LEVEL 2 OR ABOVE
			$target = imagecreatetruecolor($width, $height);
			
			$color = imagecolorallocatealpha($target, 255, 255, 255, 127); 
			imagefill($target, 0, 0, $color);
			imagesavealpha($target, TRUE);
			$fromMidX = ceil($fromMidX);
			$fromMidY = ceil($fromMidY);
			imagecopyresampled ($target, $source, $fromMidX, $fromMidY, 0, 0, $newWidth, $newHeight, $imageX, $imageY);
			if($fromMidX > 0){
				imagefill($target, 0, 0, $color);
			}
			if($fromMidY > 0){ 
				imagefill($target, 0, 0, $color);
			}
			
		}
		else
		{
			// IF GD IS AT A LOWER REVISION LEVEL
		   	$target = imagecreate($width, $height);
		   	imagesavealpha($target, TRUE);
				$empty = imagecolorallocatealpha($thumb,0x00,0x00,0x00,127);
				imagefill($target, 0, 0, $empty);
		   	imagecopyresized($target, $source, $fromMidX, $fromMidY, 0, 0, $newWidth, $newHeight, $imageX, $imageY);
		}
		
		// SHARPEN THE PIC
		$sharpenMatrix = array
		( array( -1.2, -1, -1.2 )
		, array( -1,   20, -1 )
		, array( -1.2, -1, -1.2 )
		)
		;
		$divisor = array_sum(array_map('array_sum', $sharpenMatrix));
		$offset  = 0;
		imageconvolution($target, $sharpenMatrix, $divisor, $offset);
	
		if(imagepng($target, $image,9)){
			imagedestroy($target);
		}
		return $image;
	}
}

Open in new window


Any help would be appreciated, Dan
0
Comment
Question by:andrewaiello
  • 5
  • 4
9 Comments
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 38777760
Let me see if I can paraphrase... Given an image of some width and height, you want to proportionally resize the image, then you want to pad the image with transparent space to fit a specific output size.  Does that cover it?
0
 
LVL 1

Author Comment

by:andrewaiello
ID: 38778383
Yes. And I actually think I got the basis of this function from something you posted in one of my previous questions on http://www.experts-exchange.com.  Thank you again.
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 38782916
I'm using your question as a teaching example in class today.  I'll have a good script for you after lunch, US Eastern time.  Best regards, ~Ray
0
 
LVL 1

Author Comment

by:andrewaiello
ID: 38782970
I wanted to add to this question.  I was playing around with the function and notice that line 121 was not necessary, so I removed it.  

I then changed lines 126 to 131 to:

if($fromMidX > 0){
				$transparent = $width - 1;
				imagefill($target, 0, 0, $color);
				imagefill($target,$transparent , 0, $color); 
			}
			if($fromMidY > 0){ 
				$transparent = $height - 1;
				imagefill($target, 0, 0, $color);
				imagefill($target, 0, $transparent, $color);
			}

Open in new window


Also, despite the fact that I had #FFFFFF specified on line 120 and cleared my cache, I was still getting #000000 being used as a fill.

I played around with it and came to replace it with:

$color = imagecolorallocatealpha($target, 255, 255, 255, 123);

Open in new window


By changing the alpha channel it changed the color used to #FFFFFF and I was able to blend the transparent padding with my background enough so it is not noticeable.  But I am still getting a solid pixel in the top left corner and a solid line across the top of the non transparent part of the image.

I also changed the coordinates used in imagefill() to various spots other than 0,0 but those solid pixels remain in the same locations.

It is sufficient for what I need, and I can move on.  But I'm still curious about this behavior.
0
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 
LVL 108

Assisted Solution

by:Ray Paseur
Ray Paseur earned 500 total points
ID: 38783816
In this code snippet the lines 233 - 275 need correct indenting.  I'm sure you will know what to do ;-)  You may want to change the code to use a new name for each thumbnail.

ImageColorAllocateAlpha has a last argument that tells the degree of transparency.  127 is totally transparent.

<?php // aiello.php
error_reporting(E_ALL);


// MANUAL REFERENCE PAGES YOU MUST UNDERSTAND TO UPLOAD FILES
// http://php.net/manual/en/features.file-upload.php
// http://php.net/manual/en/features.file-upload.common-pitfalls.php
// http://php.net/manual/en/function.move-uploaded-file.php
// http://php.net/manual/en/reserved.variables.files.php

// MANUAL PAGES THAT ARE IMPORTANT IF YOU ARE DEALING WITH LARGE FILES
// http://php.net/manual/en/ini.core.php#ini.upload-max-filesize
// http://php.net/manual/en/ini.core.php#ini.post-max-size
// http://php.net/manual/en/info.configuration.php#ini.max-input-time


// PHP 5.1+  SEE http://php.net/manual/en/function.date-default-timezone-set.php
date_default_timezone_set('America/Chicago');

// ESTABLISH THE NAME OF THE 'uploads' DIRECTORY
$uploads = 'RAY_junk';
if (!is_dir($uploads))
{
    mkdir($uploads);
}


// ESTABLISH THE BIGGEST FILE SIZE WE CAN ACCEPT - ABOUT 8 MB
$max_file_size = '8000000';

// ESTABLISH THE MAXIMUM NUMBER OF FILES WE CAN UPLOAD
$nf = 1;

// ESTABLISH THE KINDS OF FILE EXTENSIONS WE CAN ACCEPT
$file_exts = array
( 'jpg'
, 'png'
)
;

// LIST OF THE ERRORS THAT MAY BE REPORTED IN $_FILES[]["error"] (THERE IS NO #5)
$errors = array
( 0 => "Success!"
, 1 => "The uploaded file exceeds the upload_max_filesize directive in php.ini"
, 2 => "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form"
, 3 => "The uploaded file was only partially uploaded"
, 4 => "No file was uploaded"
, 5 => "UNDEFINED ERROR"
, 6 => "Missing a temporary folder"
, 7 => "Cannot write file to disk"
)
;




// IF THERE IS NOTHING IN $_POST, PUT UP THE FORM FOR INPUT
if (empty($_POST))
{
    ?>
    <h2>Upload <?php echo $nf; ?> file(s)</h2>

    <!--
        SOME THINGS TO NOTE ABOUT THIS FORM...
        ENCTYPE IN THE HTML <FORM> STATEMENT
        MAX_FILE_SIZE MUST PRECEDE THE FILE INPUT FIELD
        INPUT NAME= IN TYPE=FILE DETERMINES THE NAME YOU FIND IN $_FILES ARRAY
        ABSENCE OF ACTION= ATTRIBUTE IN FORM TAG CAUSES POST TO SAME URL
    -->

    <form name="UploadForm" enctype="multipart/form-data" method="post">
    <input type="hidden" name="MAX_FILE_SIZE" value="<?php echo $max_file_size; ?>" />
    <p>
    Find the file(s) you want to upload and click the "Upload" button below.
    </p>

    <?php // CREATE INPUT STATEMENTS FOR UP TO $n FILE NAMES
    for ($n = 0; $n < $nf; $n++)
    {
        echo "<input name=\"userfile$n\" type=\"file\" size=\"80\" /><br/>\n";
    }
    ?>
    <br/>Thumbnail Dimensions:
    <br/>Width <input name="w" />
    <br/>Height <input name="h" />
    <br/>Check this box <input autocomplete="off" type="checkbox" name="overwrite" /> to <strong>overwrite</strong> existing files.
    <input type="submit" value="Upload" />
    </form>
    <?php
    die();
}
// END OF THE FORM SCRIPT



// WE HAVE GOT SOMETHING IN $_POST - RUN THE ACTION SCRIPT
else
{
    // THERE IS POST DATA - PROCESS IT
    echo "<h2>Results: File Upload</h2>\n";

    // ACTIVATE THIS TO SEE WHAT IS COMING THROUGH
    // echo "<pre>"; var_dump($_FILES); var_dump($_POST); echo "</pre>\n";

    // ITERATE OVER THE CONTENTS OF $_FILES
    foreach ($_FILES as $my_uploaded_file)
    {
        // SKIP OVER EMPTY SPOTS - NOTHING UPLOADED
        $error_code = $my_uploaded_file["error"];
        if ($error_code == 4) continue;

        // SYNTHESIZE THE NEW FILE NAME
        $f_type    = trim(strtolower(end    (explode( '.', basename($my_uploaded_file['name'] )))));
        $f_name    = trim(strtolower(current(explode( '.', basename($my_uploaded_file['name'] )))));
        $my_new_file
        = getcwd()
        . DIRECTORY_SEPARATOR
        . $uploads
        . DIRECTORY_SEPARATOR
        . $f_name
        . '.'
        . $f_type
        ;
        $my_file
        = $uploads
        . DIRECTORY_SEPARATOR
        . $f_name
        . '.'
        . $f_type;

        // OPTIONAL TEST FOR ALLOWABLE EXTENSIONS
        if (!in_array($f_type, $file_exts)) die("Sorry, $f_type files not allowed");

        // IF THERE ARE ERRORS
        if ($error_code != 0)
        {
            $error_message = $errors[$error_code];
            die("Sorry, Upload Error Code: $error_code: $error_message");
        }

        // GET THE FILE SIZE
        $file_size = number_format($my_uploaded_file["size"]);

        // IF THE FILE IS NEW (DOES NOT EXIST)
        if (!file_exists($my_new_file))
        {
            // IF THE MOVE FUNCTION WORKED CORRECTLY
            if (move_uploaded_file($my_uploaded_file['tmp_name'], $my_new_file))
            {
                $upload_success = 1;
            }
            // IF THE MOVE FUNCTION FAILED
            else
            {
                $upload_success = -1;
            }
        }

        // IF THE FILE ALREADY EXISTS
        else
        {
            echo "<br/><b><i>$my_file</i></b> already exists.\n";

            // SHOULD WE OVERWRITE THE FILE? IF NOT
            if (empty($_POST["overwrite"]))
            {
                $upload_success = 0;
            }
            // IF WE SHOULD OVERWRITE THE FILE, TRY TO MAKE A BACKUP
            else
            {
                $now    = date('Y-m-d');
                $my_bak = $my_new_file . '.' . $now . '.bak';
                if (!copy($my_new_file, $my_bak))
                {
                    echo "<br/><strong>Attempted Backup Failed!</strong>\n";
                }
                if (move_uploaded_file($my_uploaded_file['tmp_name'], $my_new_file))
                {
                    $upload_success = 2;
                }
                else
                {
                    $upload_success = -1;
                }
            }
        }

        // REPORT OUR SUCCESS OR FAILURE
        if ($upload_success == 2) { echo "<br/>It has been overwritten.\n"; }
        if ($upload_success == 1) { echo "<br/><strong>$my_file</strong> has been saved.\n"; }
        if ($upload_success == 0) { echo "<br/><strong>It was NOT overwritten.</strong>\n"; }
        if ($upload_success < 0)  { echo "<br/><strong>ERROR: $my_file NOT SAVED - SEE WARNING FROM move_uploaded_file() COMMAND</strong>\n"; }
        if ($upload_success > 0)
        {
            echo "$file_size bytes uploaded.\n";
            if (!chmod ($my_new_file, 0755))
            {
                echo "<br/>chmod(0755) FAILED: fileperms() = ";
                echo substr(sprintf('%o', fileperms($my_new_file)), -4);
            }
            echo "<br/><a target=\"_blank\" href=\"$my_file\">See the file $my_file</a>\n";
        }
        
        // RESIZE AN IMAGE TO FIT INSIDE A DEFINED TRANSPARENT SPACE
        $image_url = $my_file;
        
        // ACQUIRE THE DIMENSIONS - MAY NEED SOME SANITY TESTS?
        $thumb_w   = $_POST["w"];
        $thumb_h   = $_POST["h"];

        // CREATE THE THUMBNAIL IMAGE RESOURCE AND FILL IN TRANSPARENT
        $thumb = imageCreateTrueColor($thumb_w, $thumb_h);
        imageSaveAlpha($thumb, TRUE);
        $empty = imageColorAllocateAlpha($thumb,0,0,0,127);
        imageFill($thumb, 0, 0, $empty);

        // GET ORIGINAL IMAGE DIMENSIONS
        $array = getImageSize($image_url);
        if ($array)
        {
            list($image_w, $image_h) = $array;
        }
        else
        {
            die("NO IMAGE $image_url");
        }

// ACQUIRE THE ORIGINAL IMAGE
$image_ext = trim(strtoupper(end(explode('.', $image_url))));
switch(strtoupper($image_ext))
{
    case 'JPG' :
    case 'JPEG' :
        $image = imagecreatefromjpeg($image_url);
        break;

    case 'PNG' :
        $image = imagecreatefrompng($image_url);
        break;

    default : die("UNKNOWN IMAGE TYPE: $image_url");
}

// GET THE LESSER OF THE RATIO OF THUMBNAIL H OR W DIMENSIONS
$ratio_w = ($thumb_w / $image_w);
$ratio_h = ($thumb_h / $image_h);
$ratio   = ($ratio_w < $ratio_h) ? $ratio_w : $ratio_h;

// COMPUTE THUMBNAIL IMAGE DIMENSIONS
$thumb_w_resize = $image_w * $ratio;
$thumb_h_resize = $image_h * $ratio;

// COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS
$thumb_w_offset = ($thumb_w - $thumb_w_resize) / 2.0;
$thumb_h_offset = ($thumb_h - $thumb_h_resize) / 2.0;

// COPY THE IMAGE TO THE CENTER OF THE THUMBNAIL
imageCopyResampled
( $thumb
, $image
, $thumb_w_offset
, $thumb_h_offset
, 0
, 0
, $thumb_w_resize
, $thumb_h_resize
, $image_w
, $image_h
)
;

        // (OPTIONAL) SHOW THE NEW THUMB IMAGE
        // header('Content-type: image/png');
        imagePng($thumb, getcwd() . "/$uploads/thumbnail.png");

        // RELEASE THE MEMORY USED BY THE RESOURCES
        imageDestroy($thumb);
        imageDestroy($image);

        // CREATE AN IMAGE LINK FOR THE BROWSER
        echo "<br/><a target=\"_blank\" href=\"/$uploads/thumbnail.png\">See the Thumb /$uploads/thumbnail.png</a>\n";

    // END FOREACH ITERATOR - EACH ITERATION PROCESSES ONE FILE
    }
}

Open in new window

HTH, ~Ray
0
 
LVL 1

Author Comment

by:andrewaiello
ID: 38802014
I just tried the script you posted, and it does exactly what I was trying to do.  There are no stray pixels or anything.

I still have to compare it to what I have to see where I am going wrong. I also will have to go over the links in your comments at the top of the script.  

I just want to ask, why do you check the file extension when deciding how to process the image (imagecreatefromjpeg() or imagecreatefrompng()) and not by the mime type.

I just don't know if it is preference or if there is a specific reason.

Thank you for all your help once again, Dan.
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 38802048
No special reason.  I suppose there would be arguments that the mime type was somehow more "accurate" but I've used this method for years and I've never seen anybody send me an obscured file name.

If I get time, I'll add the sharpening back in and post a new version with better overwrite handling.

Best regards, ~Ray
0
 
LVL 108

Accepted Solution

by:
Ray Paseur earned 500 total points
ID: 38802095
<?php // RAY_image_upload_and_thumbnail.php
error_reporting(E_ALL);


// MANUAL REFERENCE PAGES YOU MUST UNDERSTAND TO UPLOAD FILES
// http://php.net/manual/en/features.file-upload.php
// http://php.net/manual/en/features.file-upload.common-pitfalls.php
// http://php.net/manual/en/function.move-uploaded-file.php
// http://php.net/manual/en/reserved.variables.files.php

// MANUAL PAGES THAT ARE IMPORTANT IF YOU ARE DEALING WITH LARGE FILES
// http://php.net/manual/en/ini.core.php#ini.upload-max-filesize
// http://php.net/manual/en/ini.core.php#ini.post-max-size
// http://php.net/manual/en/info.configuration.php#ini.max-input-time


// PHP 5.1+  SEE http://php.net/manual/en/function.date-default-timezone-set.php
date_default_timezone_set('America/Chicago');

// ESTABLISH THE NAME OF THE 'uploads' DIRECTORY
$uploads = 'RAY_junk';
if (!is_dir($uploads))
{
    mkdir($uploads);
}


// ESTABLISH THE BIGGEST FILE SIZE WE CAN ACCEPT - ABOUT 8 MB
$max_file_size = '8000000';

// ESTABLISH THE MAXIMUM NUMBER OF FILES WE CAN UPLOAD
$nf = 3;

// ESTABLISH THE KINDS OF FILE EXTENSIONS WE CAN ACCEPT
$file_exts = array
( 'jpg'
, 'png'
)
;

// LIST OF THE ERRORS THAT MAY BE REPORTED IN $_FILES[]["error"] (THERE IS NO #5)
$errors = array
( 0 => "Success!"
, 1 => "The uploaded file exceeds the upload_max_filesize directive in php.ini"
, 2 => "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form"
, 3 => "The uploaded file was only partially uploaded"
, 4 => "No file was uploaded"
, 5 => "UNDEFINED ERROR"
, 6 => "Missing a temporary folder"
, 7 => "Cannot write file to disk"
)
;




// IF THERE IS NOTHING IN $_POST, PUT UP THE FORM FOR INPUT
if (empty($_POST))
{
    ?>
    <h2>Upload <?php echo $nf; ?> file(s)</h2>

    <!--
        SOME THINGS TO NOTE ABOUT THIS FORM...
        ENCTYPE IN THE HTML <FORM> STATEMENT
        MAX_FILE_SIZE MUST PRECEDE THE FILE INPUT FIELD
        INPUT NAME= IN TYPE=FILE DETERMINES THE NAME YOU FIND IN $_FILES ARRAY
        ABSENCE OF ACTION= ATTRIBUTE IN FORM TAG CAUSES POST TO SAME URL
    -->

    <form name="UploadForm" enctype="multipart/form-data" method="post">
    <input type="hidden" name="MAX_FILE_SIZE" value="<?php echo $max_file_size; ?>" />
    <p>
    Find the file(s) you want to upload and click the "Upload" button below.
    </p>

    <?php // CREATE INPUT STATEMENTS FOR UP TO $n FILE NAMES
    for ($n = 0; $n < $nf; $n++)
    {
        echo "<input name=\"userfile$n\" type=\"file\" size=\"80\" /><br/>" . PHP_EOL;
    }
    ?>
    <br/>Thumbnail Dimensions:
    <br/>Width <input name="w" />
    <br/>Height <input name="h" />
    <br/>Check this box <input autocomplete="off" type="checkbox" name="overwrite" /> to <strong>overwrite</strong> existing files.
    <input type="submit" value="Upload" />
    </form>
    <?php
    die();
}
// END OF THE FORM SCRIPT



// WE HAVE GOT SOMETHING IN $_POST - RUN THE ACTION SCRIPT
else
{
    // THERE IS POST DATA - PROCESS IT
    echo "<h2>Results: File Upload</h2>\n";

    // ACTIVATE THIS TO SEE WHAT IS COMING THROUGH
    // echo "<pre>"; var_dump($_FILES); var_dump($_POST); echo "</pre>" . PHP_EOL;

    // ITERATE OVER THE CONTENTS OF $_FILES
    foreach ($_FILES as $my_uploaded_file)
    {
        // SKIP OVER EMPTY SPOTS - NOTHING UPLOADED
        $error_code = $my_uploaded_file["error"];
        if ($error_code == 4) continue;

        // SYNTHESIZE THE NEW FILE NAME
        $f_type    = trim(strtolower(end    (explode( '.', basename($my_uploaded_file['name'] )))));
        $f_name    = trim(strtolower(current(explode( '.', basename($my_uploaded_file['name'] )))));

        // USE THIS FOR WRITING ON THE SERVER
        $my_new_file
        = getcwd()
        . DIRECTORY_SEPARATOR
        . $uploads
        . DIRECTORY_SEPARATOR
        . $f_name
        . '.'
        . $f_type
        ;

        // USE THIS FOR WRITING THE THUMBNAIL ON THE SERVER
        $my_new_tnail
        = getcwd()
        . DIRECTORY_SEPARATOR
        . $uploads
        . DIRECTORY_SEPARATOR
        . 'tn_'
        . $f_name
        . '.png'
        ;

        // USE THIS FOR PREPARING A URL LINK OR CALLING PHP FUNCTIONS
        $my_file
        = $uploads
        . DIRECTORY_SEPARATOR
        . $f_name
        . '.'
        . $f_type
        ;

        // USE THIS FOR PREPARING A URL LINK OR CALLING PHP FUNCTIONS
        $my_tnail
        = $uploads
        . DIRECTORY_SEPARATOR
        . 'tn_'
        . $f_name
        . '.png'
        ;

        // OPTIONAL TEST FOR ALLOWABLE EXTENSIONS
        if (!in_array($f_type, $file_exts)) die("Sorry, $f_type files not allowed");

        // IF THERE ARE ERRORS
        if ($error_code != 0)
        {
            $error_message = $errors[$error_code];
            die("Sorry, Upload Error Code: $error_code: $error_message");
        }

        // GET THE FILE SIZE
        $file_size = number_format($my_uploaded_file["size"]);

        // IF THE FILE IS NEW (DOES NOT EXIST)
        if (!file_exists($my_new_file))
        {
            // IF THE MOVE FUNCTION WORKED CORRECTLY
            if (move_uploaded_file($my_uploaded_file['tmp_name'], $my_new_file))
            {
                $upload_success = 1;
            }
            // IF THE MOVE FUNCTION FAILED
            else
            {
                $upload_success = -1;
            }
        }

        // IF THE FILE ALREADY EXISTS
        else
        {
            echo "<br/><b><i>$my_file</i></b> already exists" . PHP_EOL;;

            // SHOULD WE OVERWRITE THE FILE? IF NOT
            if (empty($_POST["overwrite"]))
            {
                $upload_success = 0;
            }
            // IF WE SHOULD OVERWRITE THE FILE, TRY TO MAKE A BACKUP
            else
            {
                $now    = date('Y-m-d');
                $my_bak = $my_new_file . '.' . $now . '.bak';
                if (!copy($my_new_file, $my_bak))
                {
                    echo "<br/><strong>Attempted Backup Failed!</strong>" . PHP_EOL;
                }
                if (move_uploaded_file($my_uploaded_file['tmp_name'], $my_new_file))
                {
                    $upload_success = 2;
                }
                else
                {
                    $upload_success = -1;
                }
            }
        }

        // REPORT OUR SUCCESS OR FAILURE
        if ($upload_success == 2) { echo "<br/>It has been overwritten.\n"; }
        if ($upload_success == 1) { echo "<br/><strong>$my_file</strong> has been saved.\n"; }
        if ($upload_success == 0) { echo "<br/><strong>It was NOT overwritten.</strong>\n"; }
        if ($upload_success < 0)  { echo "<br/><strong>ERROR: $my_file NOT SAVED - SEE WARNING FROM move_uploaded_file() COMMAND</strong>\n"; }
        if ($upload_success > 0)
        {
            echo "$file_size bytes uploaded.\n";
            if (!chmod ($my_new_file, 0755))
            {
                echo "<br/>chmod(0755) FAILED: fileperms() = ";
                echo substr(sprintf('%o', fileperms($my_new_file)), -4);
            }
            echo "<br/><a target=\"_blank\" href=\"$my_file\">See the file $my_file</a>\n";
        }
        // IF NO UPLOAD, DO NOT OVERWRITE ANY EXISTING THUMBNAIL
        else
        {
            die();
        }

        // RESIZE AN IMAGE TO FIT INSIDE A DEFINED TRANSPARENT SPACE
        $image_url = $my_file;

        // ACQUIRE THE DIMENSIONS - MAY NEED SOME SANITY TESTS?
        $thumb_w   = $_POST["w"];
        $thumb_h   = $_POST["h"];

        // CREATE THE THUMBNAIL IMAGE RESOURCE AND FILL IN TRANSPARENT
        $thumb = imageCreateTrueColor($thumb_w, $thumb_h);
        imageSaveAlpha($thumb, TRUE);
        $empty = imageColorAllocateAlpha($thumb,0,0,0,127);
        imageFill($thumb, 0, 0, $empty);

        // GET ORIGINAL IMAGE DIMENSIONS
        $array = getImageSize($my_file);
        if ($array)
        {
            list($image_w, $image_h) = $array;
        }
        else
        {
            die("NO IMAGE $my_file");
        }

        // ACQUIRE THE ORIGINAL IMAGE
        $image_ext = trim(strtoupper(end(explode('.', $my_file))));
        switch(strtoupper($image_ext))
        {
            case 'JPG' :
            case 'JPEG' :
                $image = imagecreatefromjpeg($image_url);
                break;

            case 'PNG' :
                $image = imagecreatefrompng($image_url);
                break;

            default : die("UNKNOWN IMAGE TYPE: $my_file");
        }

        // GET THE LESSER OF THE RATIO OF THUMBNAIL H OR W DIMENSIONS
        $ratio_w = ($thumb_w / $image_w);
        $ratio_h = ($thumb_h / $image_h);
        $ratio   = ($ratio_w < $ratio_h) ? $ratio_w : $ratio_h;

        // COMPUTE THUMBNAIL IMAGE DIMENSIONS
        $thumb_w_resize = $image_w * $ratio;
        $thumb_h_resize = $image_h * $ratio;

        // COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS
        $thumb_w_offset = ($thumb_w - $thumb_w_resize) / 2.0;
        $thumb_h_offset = ($thumb_h - $thumb_h_resize) / 2.0;

        // COPY THE IMAGE TO THE CENTER OF THE THUMBNAIL
        imageCopyResampled
        ( $thumb
        , $image
        , $thumb_w_offset
        , $thumb_h_offset
        , 0
        , 0
        , $thumb_w_resize
        , $thumb_h_resize
        , $image_w
        , $image_h
        )
        ;
        // SHARPEN THE THUMBNAIL
		$sharpenMatrix = array
		( array( -1.2, -1, -1.2 )
		, array( -1,   20, -1 )
		, array( -1.2, -1, -1.2 )
		)
		;
		$divisor = array_sum(array_map('array_sum', $sharpenMatrix));
		$offset  = 0;
		imageconvolution($thumb, $sharpenMatrix, $divisor, $offset);

        // (OPTIONAL) SHOW THE NEW THUMB IMAGE DIRECTLY IN BROWSER
        // header('Content-type: image/png');
        // imagePng($thumb);

        // WRITE THE THUMBNAIL TO DISK
        imagePng($thumb, $my_new_tnail);

        // RELEASE THE MEMORY USED BY THE IMAGE RESOURCES
        imageDestroy($thumb);
        imageDestroy($image);

        // CREATE AN IMAGE LINK FOR THE BROWSER
        echo '<br/><a target="_blank" href="' . $my_tnail . '">See the Thumb ' . $my_tnail . '</a>' . PHP_EOL;

    // END FOREACH ITERATOR - EACH ITERATION PROCESSES ONE FILE
    }
}

Open in new window

0
 
LVL 1

Author Closing Comment

by:andrewaiello
ID: 38818842
I accepted as a multiple solution because both posts answer my question accurately.  The 2nd one just has a few more features added to it.  Both posts are extremely detailed with links to the PHP manuals for all used functions along with reference docs related to the subject.  

Thank you Ray.
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Popularity Can Be Measured Sometimes we deal with questions of popularity, and we need a way to collect opinions from our clients.  This article shows a simple teaching example of how we might elect a favorite color by letting our clients vote for …
Consider the following scenario: You are working on a website and make something great - something that lets the server work with information submitted by your users. This could be anything, from a simple guestbook to a e-Money solution. But what…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
The viewer will learn how to dynamically set the form action using jQuery.

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now