Image resize problems

Discussion in 'PHP' started by Jeremy Benson, Nov 28, 2013.

  1. #1
    Hey,

    I've been going crazy trying to find a class that would resize images the way I'd like. I got close with PHPThumb, and Thumbfactory, but despite the docs in various places neither versions would work for me. The forums seem to be down, so I decided to start coding a simple class. I can't seem to get a re-sized image through. Was wondering if someone could tell me where my variable are, and if I'm using the functions wrong...

    The purpose of the class is to re-size and overwrite the original.

    Registration.PHP
    
    $profileThumb = new imgResize($_FILES['userProfileImage']['name'], $fileType, $destination);
             
             $profileThumb->getOrigDim();
             
             $profileThumb->setThumbDimensions(80,100);
             
             $profileThumb->createThumb();   
    
    PHP:
    resize class

    
    <?php
    
    class imgResize{
    
       protected $name;
       protected $fileType;
       protected $destination;
       protected $originalDimensions;
       protected $thumbWidth;
       protected $thumbHeight;   
       
       public function __construct($fn, $ft, $fd)
       {
       
         $this->name = $fn;
         $this->fileType = $ft;
         $this->destination = $fd;
       
       }
         
       public function getOrigDim()
       {
       
         $this->originalImgDim = getimagesize($this->destination . $this->name);
    
       
       }
       
       public function setThumbDimensions($width, $height)
       {
       
         $this->thumbWidth = $width;
         $this->thumbHeight = $height;
       
       }
       
       public function createThumb()
       
       {   
         //create original resource
         $origResource = $this->createOrigResource();
         //create thumb resource
         $thumbResource = $this->createThumbResource();
         //Create thumbnail image
         imagecopyresampled($thumbResource, $origResource, 0, 0, 0, 0, $this->thumbWidth, $this->thumbHeight,$this->originalDimensions[0],$this->originalDimensions[1]);
         // delete resources
         imagedestroy($origResource);
         imagedestroy($thumbResource);
       }
       
       protected function createOrigResource()
       {
       
         if($this->fileType == ".jpg" || $this->fileType == ".jpeg"){
             
           $originalResource =   imagecreatefromjpeg($this->destination . $this->name);
             
         }elseif($this->fileType == ".png" || $this->fileType == ".jpeg"){
             
           $originalResource =   imagecreatefrompng($this->destination . $this->name);
    
         }elseif($this->fileType == ".gif"){
             
           $originalResource =   imagecreatefromgif($this->destination . $this->name);
         }
    
         return $originalResource;
       
       }
    
       protected function createThumbResource()
       
       {
       
       
         $cropResource = imagecreatetruecolor($this->thumbWidth, $this->thumbHeight);
         return $cropResource;
       
       }
       
       
    
    }
    
    
    ?>
    
    PHP:
     
    Jeremy Benson, Nov 28, 2013 IP
  2. nico_swd

    nico_swd Prominent Member

    Messages:
    4,153
    Likes Received:
    344
    Best Answers:
    18
    Trophy Points:
    375
    #2
    The file at $this->destination.$this->name won't exist until you copy it there (or have it saved by imagejpeg), so your class can't open it. Try to read the file from $_FILES['userProfileImage']['tmp_name'] instead. Use the destination and original file name for saving.
     
    nico_swd, Nov 28, 2013 IP
  3. Jeremy Benson

    Jeremy Benson Well-Known Member

    Messages:
    364
    Likes Received:
    4
    Best Answers:
    0
    Trophy Points:
    123
    #3
    Shoot. I left out some code in the first block. The image was already moved to the destination folder...I should have posted that whole block instead of the object down, lol... The file should be in the folder when the class calls its functions..

    
     
    $destination = "C:/wamp/www/user/$sesUserName/images/profileimage/";
         
           $fileReg = "(.jpg|.jpeg|.png|.gif)";
           
           $fileType = strstr($_FILES['userProfileImage']['name'], '.');
           
           if(preg_match($fileReg, $fileType)){
                 
             $_FILES['userProfileImage']['name'] = "profileimage" . $fileType;
           
             move_uploaded_file($_FILES['userProfileImage']['tmp_name'], $destination . $_FILES['userProfileImage']['name']);
             
             $profileThumb = new imgResize($_FILES['userProfileImage']['name'], $fileType, $destination);
             
             $profileThumb->getOrigDim();
             
             $profileThumb->setThumbDimensions(80,100);
             
             $profileThumb->createThumb();         
                     
           }
    
    
    PHP:
     
    Jeremy Benson, Nov 28, 2013 IP
  4. Jeremy Benson

    Jeremy Benson Well-Known Member

    Messages:
    364
    Likes Received:
    4
    Best Answers:
    0
    Trophy Points:
    123
    #4
    On a side note should this function here have fileType appended within the parameters?

    
    $this->originalImgDim = getimagesize($this->destination . $this->name);
    
    PHP:
     
    Jeremy Benson, Nov 28, 2013 IP
  5. nico_swd

    nico_swd Prominent Member

    Messages:
    4,153
    Likes Received:
    344
    Best Answers:
    18
    Trophy Points:
    375
    #5
    I wouldn't move the uploaded file before creating the thumbnail. Let it stay in the /tmp directory, then load its contents, and save it using the GD library.

    http://www.php.net/manual/en/function.imagejpeg.php
    
    if (@imagejpeg($resource, $destination, 80))
    {
        // File has been saved
    }
    
    PHP:
    And a little improvement to your regex:
    
    $fileReg = "~(.jpg|.jpeg|.png|.gif)$~i";
    
    PHP:
    (Makes sure the extension is at the end of the file, so file.jpg.php wouldn't pass through, and makes it case-insensitive.)

    EDIT: I was a little too fast checking your code. Since you're using strstr() you'll probably be fine. I would still add the "i" modifier, though.
     
    nico_swd, Nov 28, 2013 IP
  6. Jeremy Benson

    Jeremy Benson Well-Known Member

    Messages:
    364
    Likes Received:
    4
    Best Answers:
    0
    Trophy Points:
    123
    #6
    I'm not sure how to work that function in. The doc says it creates an image from a given file, but does that file have to be a jpeg, or does it create jpeg out of any file...

    sorry, I have a one track mind sometimes, and find it extremely hard to understand this, lol...

    That's why I can never seem to get other classes working... only thing that I can seem to get working is code I wrote myself... I had done this right once the procedural way... and then decided to move my code to a class, but can't make it work, lol..

    I'm a bit confused about making resources in a class.... how can you make a data member a resource and then remove it from memory, or does that happen when the object goes out of scope?
     
    Jeremy Benson, Nov 28, 2013 IP
  7. Jeremy Benson

    Jeremy Benson Well-Known Member

    Messages:
    364
    Likes Received:
    4
    Best Answers:
    0
    Trophy Points:
    123
    #7
    I think I just clued in to some of that. I know what I have to do here...

    1.resource of the original from temp directory.
    2. destination to save to.
    3. quality.

    uhh...I think I can rewrite my class, but I'll have to use some different variables and thinking...

    am I on the right track here from what you've given me?
     
    Jeremy Benson, Nov 28, 2013 IP
  8. nico_swd

    nico_swd Prominent Member

    Messages:
    4,153
    Likes Received:
    344
    Best Answers:
    18
    Trophy Points:
    375
    #8
    Yes, that's how it should work. imagejpeg() saves any resource (whether it's from a .png or .gif) to jpg. You can also save files in other formats using imagepng() etc, but I would probably save them all as jpegs.

    So what you have to pass to your class constructor is the "tmp_name" instead of the "name", and you then save it to the destination from there.
     
    nico_swd, Nov 28, 2013 IP
  9. Jeremy Benson

    Jeremy Benson Well-Known Member

    Messages:
    364
    Likes Received:
    4
    Best Answers:
    0
    Trophy Points:
    123
    #9
    I re-wrote my class to make it a bit more oop friendly, thanks to your specifications, but I ran into a snag... I'm not sure if I'm using the right functions to create my resources...I'm sure I am, and I'm not sure how to move the create file with the imagejpeg and so on functions because I'm not sure what the newly created files are called, lol.

    implementation

    
    
    $moveDestination = "C:/wamp/www/user/$sesUserName/images/profileimage/";
        
           $fileReg = "~(.jpg|.jpeg|.png|.gif)$~i";
          
           $fileType = strstr($_FILES['userProfileImage']['name'], '.');
          
           if(preg_match($fileReg, $fileType)){
                              
             $profileThumb = new imgResize($fileType, "profileimage", $moveDestination);
            
             $profileThumb->setThumbDimension(50,50); // remember to change dimenstions.
            
             $profileThumb->createThumb();
            
          }
    
    
    PHP:
    Class
    
    <?php
    
    class imgResize{
    
       protected $name;
       protected $fileType;
       protected $destination;
       protected $moveDestination;
       protected $originalDimensions;
       protected $thumbWidth;
       protected $thumbHeight;  
      
       public function __construct($ft, $n, $md)
       {
      
         //get the mimetype for $fileType
        
         $this->fileType = $ft;
            
         //rename the file with given extension.
        
         $_FILES['userProfileImage']['name'] = "$n" . $this->fileType;
    
         //get the original file dimensions
        
         $this->originalDimension = getimagesize($_FILES['userProfileImage']['tmp_name']);
        
         //set the move destination
        
         $this->moveDestination = $md;
       }
      
       public function setThumbDimension($h,$w)
       {
      
         $this->thumbWidth = $w;
         $this->thumbHeight = $h;
      
       }
      
      
       public function createThumb()
       {
      
         //resource of the original
         $originalResource;
        
         if($this->fileType == ".jpg" || $this->fileType == ".jpeg")
         {
        
           $originalResource = imagecreatefromjpeg($_FILES['userProfileImage']['tmp_name']);
        
         }elseif($this->fileType == ".png"){
        
           $originalResource = imagecreatefrompng($_FILES['userProfileImage']['tmp_name']);
        
         }elseif($this->fileType == ".gif"){
        
           $originalResource = imagecreatefromgif($_FILES['userProfileImage']['tmp_name']);
         }
        
         //resource of the thumbnail
        
         $thumbResource = imagecreatetruecolor($this->thumbWidth, $this->thumbHeight);
    
         //create the thumb with imagecopy resampled
        
         imagecopyresampled($thumbResource, $originalResource, 0, 0, 0, 0, $this->thumbWidth, $this->thumbHeight , $this->originalDimension[0], $this->originalDimension[1]);
        
         // save uploaded file
        
         if($this->fileType == ".jpg" || $this->fileType == ".jpeg"){
        
           imagejpeg($thumbResource, $this->moveDestination);
          
         }elseif($this->fileType == ".png"){
        
           imagepng($thumbResource, $this->moveDestination);
    
        
         }elseif($this->fileType == ".gif"){
        
           imagegif($thumbResource, $this->moveDestination);
         }
        
         // destrory the resources with imagedestroy function
        
         imagedestroy($originalResource);
         imagedestroy($thumbResource);
    
       }  
      
    }
    
    ?>
    
    
    PHP:
     
    Jeremy Benson, Nov 29, 2013 IP
  10. Jeremy Benson

    Jeremy Benson Well-Known Member

    Messages:
    364
    Likes Received:
    4
    Best Answers:
    0
    Trophy Points:
    123
    #10
    hmm, anyone have any idea what's wrong here, lol, stumped until I can figure out how to move that image.

    any help would be greatly appreciated.
     
    Jeremy Benson, Dec 3, 2013 IP
  11. nico_swd

    nico_swd Prominent Member

    Messages:
    4,153
    Likes Received:
    344
    Best Answers:
    18
    Trophy Points:
    375
    #11
    $this->moveDestination points to a directory, and not a file.

    And try to avoid abbreviated variable names like $md, $ft, etc... They're not very helpful.
     
    nico_swd, Dec 3, 2013 IP
  12. Jeremy Benson

    Jeremy Benson Well-Known Member

    Messages:
    364
    Likes Received:
    4
    Best Answers:
    0
    Trophy Points:
    123
    #12
    I thought moveDestination was supposed to point to a directory.

    imagejpeg($thumbResource, $this->moveDestination);

    wouldn't the first argument be the resource, and the second the directory to move it to?

    lol, I'm pretty confused now...not even sure what the codes doing, lol.
     
    Jeremy Benson, Dec 4, 2013 IP
  13. nico_swd

    nico_swd Prominent Member

    Messages:
    4,153
    Likes Received:
    344
    Best Answers:
    18
    Trophy Points:
    375
    #13
    Hehe, no, you have to specify the path and the filename. imagejpeg($resource, 'path/to/file/image.jpg', 80);
     
    nico_swd, Dec 4, 2013 IP
  14. Jeremy Benson

    Jeremy Benson Well-Known Member

    Messages:
    364
    Likes Received:
    4
    Best Answers:
    0
    Trophy Points:
    123
    #14
    Ah, shoot. Now I'm starting to get it, lol

    but I'm still confused...When I create a resource with $thumbResource = imagecreatetruecolor($this->thumbWidth, $this->thumbHeight); it isn't given a name it just creates a square black image, but not sure what it calls it... so image imagejpeg($resource, path, 80) takes the resource from imagecreatetruecolor as the first argument, and path to what file as the second? the original file held in $_FILES?

    If its the second case why do I even bother making a resource of the original..arg, lol...

    any way you can clear my confusion?
     
    Jeremy Benson, Dec 4, 2013 IP
  15. nico_swd

    nico_swd Prominent Member

    Messages:
    4,153
    Likes Received:
    344
    Best Answers:
    18
    Trophy Points:
    375
    #15
    You need to create a resource of the file so you can resize it. Then you call imagejpeg() to save the resource to a file on the disk. The path in the second argument is where you want to save it. So not the one from the $_FILES array. It should be "$this->moveDestination + file name".

    The whole process is as follows:
    1. User uploads file.
    2. You create an image resource of the temporary file without moving it. (imagecreatefromjpeg($_FILES['userProfileImage']['tmp_name']);)
    3. You create a blank image resource with the wanted dimensions of the new file. (imagecreatetruecolor($this->thumbWidth, $this->thumbHeight);)
    4. You create a copy of the first resource to the new one with the new dimensions. (imagecopyresampled($thumbResource, $originalResource, 0 ...)
    5. You call imagejpeg() to save the resource to a file. (imagejpeg($thumbResource, $this->moveDestination . $aFancyName)

    You're just missing the last step.
     
    nico_swd, Dec 4, 2013 IP
  16. Jeremy Benson

    Jeremy Benson Well-Known Member

    Messages:
    364
    Likes Received:
    4
    Best Answers:
    0
    Trophy Points:
    123
    #16
    Okay, just wondering. In the last step imagejpeg($thumbResource, $this->moveDestination . $aFancyName) can the name be anything? This is a save name right? Not an actual file name?
     
    Jeremy Benson, Dec 9, 2013 IP
  17. nico_swd

    nico_swd Prominent Member

    Messages:
    4,153
    Likes Received:
    344
    Best Answers:
    18
    Trophy Points:
    375
    #17
    It's the name of the uploaded file. The file you save on the disk, so it can be anything you like. The rest of the names (tmp name, original file name) don't matter at this point anymore.
     
    nico_swd, Dec 9, 2013 IP
  18. Jeremy Benson

    Jeremy Benson Well-Known Member

    Messages:
    364
    Likes Received:
    4
    Best Answers:
    0
    Trophy Points:
    123
    #18
    Ah, I got it. Works like charm...lol... re-sizes a bit bad, but it gets the job done for now. Thanks again. :)
     
    Jeremy Benson, Dec 10, 2013 IP
  19. eritrea1

    eritrea1 Active Member

    Messages:
    182
    Likes Received:
    9
    Best Answers:
    2
    Trophy Points:
    70
    #19
    I want to just throw my two cents here.

    Your code could get clearer if you change this:

    protected function createOrigResource()
      {
     
        if($this->fileType == ".jpg" || $this->fileType == ".jpeg"){
           
          $originalResource =  imagecreatefromjpeg($this->destination . $this->name);
           
        }elseif($this->fileType == ".png" || $this->fileType == ".jpeg"){
           
          $originalResource =  imagecreatefrompng($this->destination . $this->name);
        }elseif($this->fileType == ".gif"){
           
          $originalResource =  imagecreatefromgif($this->destination . $this->name);
        }
        return $originalResource;
     
      }
    Code (markup):
    to
    $newFileName = '...';

    private function getFileExtension($fileName){
        return ".".strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
    }
    $fileExtension = $this->getFileExtensions($_FILES['tmp_name'])
     switch ($fileExtension) {
                    case 'jpeg':
                    case 'jpg':
                        imagejpeg($tmp, $this->allowedUploadDirectory . $newFileName, 100);
                        break;
                    case 'png':
                        imagepng($tmp, $this->allowedUploadDirectory . $newFileName, 0);
                        break;
                    case 'gif':
                        imagegif($tmp, $this->allowedUploadDirectory . $newFileName);
                        break;
                    default:
                        exit;
                        break;
                }
                return $this->allowedUploadDirectory;
            }
    
    Code (markup):
    I copy/pasted from my class here, https://github.com/simon-eQ/ImageUploader which is currently in the making. But, the whole point is that, you might be better of not using if/else/elseif .. plus && || and just use something simple and efficient like the above.
     
    eritrea1, Dec 10, 2013 IP