Jump to content

Modifying a file before upload


Go to solution Solved by requinix,

Recommended Posts

I’ve written several “test” pages to sample code from other sources.  Each one of my test program works just fine but with certain assumptions like the file is already on the server.  Then I’m trying to compile the code all together to accomplish what I want it to do.

 

Here is what I want to accomplish:

1.       I have form where an admin can select an image.

2.       Because the image is taken on an iPhone, I want to pull the EXIF data, rotate it 90 degrees so it appears correctly on the website.

3.       I want to resize the image.

4.       I now want to upload that image.

 

My first question is:  Is it possible to do everything in this order?  I presume when you select an image in a form, it’s a temp file not yet uploaded so you can manipulate the file first.  The reason why step 2 is before step 3, is because the resizing of the image apparently wipes out the EXIF data and then there is no way to auto correct the image.  I would also like to upload a much smaller file to save on upload time and also meet upload size requirements.

 

So here is the form (yes I’m using tables for now instead of <div>):

<form method="POST" action="edit.php?id=<?=$ID; ?>" enctype="multipart/form-data">
        <table border='1' cellpadding='3' cellspacing='0'>
        <tr>
            <th>Select Document To Be Uploaded</th>
        </tr>
        <tr>
            <td>
                <input type="radio" name="ImageType" value="License" />Drivers License<br />
                <input type="radio" name="ImageType" value="Insurance" />Vehicle Insurance<br />
                <input type="radio" name="ImageType" value="Registration" />Vehicle Registration<br />
                <input type="radio" name="ImageType" value="Background" />Background Check<br />
            </td>
        </tr>
        <tr>
            <td align="center">
                <input type="file" name="FileUploaded" />
            </td>
        </tr>
        <tr>
            <td align="center">
                <input value="Upload" type="submit" />
            </td>
        </tr>
        </table>
        </form>

At the beginning of this long page of code I have the following:

// After a file has been submitted
if(!empty($_FILES['FileUploaded']['tmp_name'])){
 
    $Image = $_FILES['FileUploaded']['tmp_name'];
 
    exif($Image);  
}

So I’m calling the function exif.  The page stops rendering at this point and I’m not sure why.

 

Here is the function exif (which when testing with an image on the server already it was working fine):

function exif($file) {
    //This line reads the EXIF data and passes it into an array
    $exif = exif_read_data($file);
   
    //We're only interested in the orientation
    $exif_orient = isset($exif['Orientation'])?$exif['Orientation']:0;
    $rotateImage = 0;
    //We convert the exif rotation to degrees for further use
    if (6 == $exif_orient) {
        $rotateImage = 90;
        $imageOrientation = 1;
    } elseif (3 == $exif_orient) {
        $rotateImage = 180;
        $imageOrientation = 1;
    } elseif (8 == $exif_orient) {
        $rotateImage = 270;
        $imageOrientation = 1;
    }
    //if the image is rotated
    if ($rotateImage) {
    //WordPress 3.5+ have started using Imagick, if it is available since there is a noticeable difference in quality
    //Why spoil beautiful images by rotating them with GD, if the user has Imagick
        if (class_exists('Imagick')) {
            $imagick = new Imagick();
            $imagick->readImage($file);
            $imagick->rotateImage(new ImagickPixel(), $rotateImage);
            $imagick->setImageOrientation($imageOrientation);
            $imagick->writeImage($file);
            $imagick->clear();
            $imagick->destroy();
        }  
    }
    // The image orientation is fixed, pass it back for further processing
    return $file;
}

Previously I did a exif(“testfile.jpg”) which testfile.jpg already existed on the server and it worked fine.  But I’m missing something (probably obvious) when trying to upload a file here from the form.

 

Any help here would be greatly appreciated.

Edited by TapeGun007
Link to comment
https://forums.phpfreaks.com/topic/302918-modifying-a-file-before-upload/
Share on other sites

You can't modify the file before it's uploaded. You could display the image to the user and let them indicate the proper orientation, eg. by giving them arrows to rotate.

 

don't understand why you can't just use the exif data after the upload though...

Ok, thank you for that!  It's unfortunate, but at least I know how to proceed.

 

I can use the EXIF data after the upload.  I just wanted to resize the image before upload which apparently strips the EXIF data.  So I wanted to correct the image orientation first, then resize it, then upload.

 

Now I have to simply upload the image, then correct the orientation, then resize it.  I think HTTP uploads however have a limit of 2 MB by default.  So I really wanted to resize the image before upload so I never crossed the 2MB limitation.

Edited by TapeGun007

I just wanted to resize the image before upload which apparently strips the EXIF data.

Depends how you're doing the resizing. I'd expect decent image editing software would let you keep EXIF data from the original.

 

But... if you're resizing before the upload, why not fix the orientation at the same time? So I guess it boils down to how you're doing this resizing before the upload?

 

I think HTTP uploads however have a limit of 2 MB by default.  So I really wanted to resize the image before upload so I never crossed the 2MB limitation.

You could always change that limit, of course. Unless you're using a shared hosting service, then they might not let you do that.

But... if you're resizing before the upload, why not fix the orientation at the same time? So I guess it boils down to how you're doing this resizing before the upload?

 

 

I'm confused, I thought you said I cannot modify the image before upload?

 

I was using the following code to resize the image (that I got from a google search).  I have not modified it such as fixing orientation, I still have to figure out where that would go:

 

 

<?php
# ========================================================================#
   #  Requires : Requires PHP5, GD library.
   #  Usage Example:
   #                     include("resize_class.php");
   #                     $resizeObj = new resize('images/cars/large/input.jpg');
   #                     $resizeObj -> resizeImage(150, 100, 0);
   #                     $resizeObj -> saveImage('images/cars/large/output.jpg', 100);
   # ========================================================================#
 
 
        class resize
        {
            // *** Class variables
            private $image;
            private $width;
            private $height;
            private $imageResized;
 
            function __construct($fileName)
            {
                // *** Open up the file
                $this->image = $this->openImage($fileName);
 
                // *** Get width and height
                $this->width  = imagesx($this->image);
                $this->height = imagesy($this->image);
            }
 
            ## --------------------------------------------------------
 
            private function openImage($file)
            {
                // *** Get extension
                $extension = strtolower(strrchr($file, '.'));
 
                switch($extension)
                {
                    case '.jpg':
                    case '.jpeg':
                        $img = @imagecreatefromjpeg($file);
                        break;
                    case '.gif':
                        $img = @imagecreatefromgif($file);
                        break;
                    case '.png':
                        $img = @imagecreatefrompng($file);
                        break;
                    default:
                        $img = false;
                        break;
                }
                return $img;
            }
 
            ## --------------------------------------------------------
 
            public function resizeImage($newWidth, $newHeight, $option="auto")
            {
                // *** Get optimal width and height - based on $option
                $optionArray = $this->getDimensions($newWidth, $newHeight, $option);
 
                $optimalWidth  = $optionArray['optimalWidth'];
                $optimalHeight = $optionArray['optimalHeight'];
 
 
                // *** Resample - create image canvas of x, y size
                $this->imageResized = imagecreatetruecolor($optimalWidth, $optimalHeight);
                imagecopyresampled($this->imageResized, $this->image, 0, 0, 0, 0, $optimalWidth, $optimalHeight, $this->width, $this->height);
 
 
                // *** if option is 'crop', then crop too
                if ($option == 'crop') {
                    $this->crop($optimalWidth, $optimalHeight, $newWidth, $newHeight);
                }
            }
 
            ## --------------------------------------------------------
 
            private function getDimensions($newWidth, $newHeight, $option)
            {
 
               switch ($option)
                {
                    case 'exact':
                        $optimalWidth = $newWidth;
                        $optimalHeight= $newHeight;
                        break;
                    case 'portrait':
                        $optimalWidth = $this->getSizeByFixedHeight($newHeight);
                        $optimalHeight= $newHeight;
                        break;
                    case 'landscape':
                        $optimalWidth = $newWidth;
                        $optimalHeight= $this->getSizeByFixedWidth($newWidth);
                        break;
                    case 'auto':
                        $optionArray = $this->getSizeByAuto($newWidth, $newHeight);
                        $optimalWidth = $optionArray['optimalWidth'];
                        $optimalHeight = $optionArray['optimalHeight'];
                        break;
                    case 'crop':
                        $optionArray = $this->getOptimalCrop($newWidth, $newHeight);
                        $optimalWidth = $optionArray['optimalWidth'];
                        $optimalHeight = $optionArray['optimalHeight'];
                        break;
                }
                return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
            }
 
            ## --------------------------------------------------------
 
            private function getSizeByFixedHeight($newHeight)
            {
                $ratio = $this->width / $this->height;
                $newWidth = $newHeight * $ratio;
                return $newWidth;
            }
 
            private function getSizeByFixedWidth($newWidth)
            {
                $ratio = $this->height / $this->width;
                $newHeight = $newWidth * $ratio;
                return $newHeight;
            }
 
            private function getSizeByAuto($newWidth, $newHeight)
            {
                if ($this->height < $this->width)
                // *** Image to be resized is wider (landscape)
                {
                    $optimalWidth = $newWidth;
                    $optimalHeight= $this->getSizeByFixedWidth($newWidth);
                }
                elseif ($this->height > $this->width)
                // *** Image to be resized is taller (portrait)
                {
                    $optimalWidth = $this->getSizeByFixedHeight($newHeight);
                    $optimalHeight= $newHeight;
                }
                else
                // *** Image to be resizerd is a square
                {
                    if ($newHeight < $newWidth) {
                        $optimalWidth = $newWidth;
                        $optimalHeight= $this->getSizeByFixedWidth($newWidth);
                    } else if ($newHeight > $newWidth) {
                        $optimalWidth = $this->getSizeByFixedHeight($newHeight);
                        $optimalHeight= $newHeight;
                    } else {
                        // *** Sqaure being resized to a square
                        $optimalWidth = $newWidth;
                        $optimalHeight= $newHeight;
                    }
                }
 
                return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
            }
 
            ## --------------------------------------------------------
 
            private function getOptimalCrop($newWidth, $newHeight)
            {
 
                $heightRatio = $this->height / $newHeight;
                $widthRatio  = $this->width /  $newWidth;
 
                if ($heightRatio < $widthRatio) {
                    $optimalRatio = $heightRatio;
                } else {
                    $optimalRatio = $widthRatio;
                }
 
                $optimalHeight = $this->height / $optimalRatio;
                $optimalWidth  = $this->width  / $optimalRatio;
 
                return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
            }
 
            ## --------------------------------------------------------
 
            private function crop($optimalWidth, $optimalHeight, $newWidth, $newHeight)
            {
                // *** Find center - this will be used for the crop
                $cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 );
                $cropStartY = ( $optimalHeight/ 2) - ( $newHeight/2 );
 
                $crop = $this->imageResized;
                //imagedestroy($this->imageResized);
 
                // *** Now crop from center to exact requested size
                $this->imageResized = imagecreatetruecolor($newWidth , $newHeight);
                imagecopyresampled($this->imageResized, $crop , 0, 0, $cropStartX, $cropStartY, $newWidth, $newHeight , $newWidth, $newHeight);
            }
 
            ## --------------------------------------------------------
 
            public function saveImage($savePath, $imageQuality="100")
            {
                // *** Get extension
                $extension = strrchr($savePath, '.');
                   $extension = strtolower($extension);
 
                switch($extension)
                {
                    case '.jpg':
                    case '.jpeg':
                        if (imagetypes() & IMG_JPG) {
                            imagejpeg($this->imageResized, $savePath, $imageQuality);
                        }
                        break;
 
                    case '.gif':
                        if (imagetypes() & IMG_GIF) {
                            imagegif($this->imageResized, $savePath);
                        }
                        break;
 
                    case '.png':
                        // *** Scale quality from 0-100 to 0-9
                        $scaleQuality = round(($imageQuality/100) * 9);
 
                        // *** Invert quality setting as 0 is best, not 9
                        $invertScaleQuality = 9 - $scaleQuality;
 
                        if (imagetypes() & IMG_PNG) {
                             imagepng($this->imageResized, $savePath, $invertScaleQuality);
                        }
                        break;
 
                    // ... etc
 
                    default:
                        // *** No extension - No save.
                        break;
                }
 
                imagedestroy($this->imageResized);
            }
 
 
            ## --------------------------------------------------------
 
        }
?>

    // *** 1) Initialise / load image
    $resizeObj = new resize('testimage.jpg');
 
    // *** 2) Resize image (options: exact, portrait, landscape, auto, crop)
    $resizeObj -> resizeImage(200, 200);
 
    // *** 3) Save image
    $resizeObj -> saveImage('testimage.jpg', 1000);

  • Solution

I'm confused, I thought you said I cannot modify the image before upload?

You can't. You're the one who talked about resizing before the upload, which I took to mean you were doing something manually. It doesn't make sense but that's the only logical conclusion I could make.

That resize class runs in PHP, which is on the server, which means you would have to use it to resize after the upload.

 

And by "upload" I mean the technical mechanism of a user using their browser to submit a form containing a file-type input, wherein the file data gets sent to your server and processed by your PHP code.

Okay, so, I guess with that cleared up, there's the issue of orientation still maybe needing some clarification.

 

Yes, resizing with GD will destroy EXIF data. So you check the orientation before resizing, load up the image, fix the orientation if needed, and finally resize and save to wherever.

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.