PHP image uploads - moving from one type to many

889

Currently I'm able to upload jpg files, and I'm saving them as jpg files. Obviously I'm unable to upload/save png files as it's hard-set to jpg. I'm trying to work out how I can move from jpg only to allow png, jpg and jpeg.

public static function createAvatar()
{
    // check if upload fits all rules
    AvatarModel::validateImageFile();

    // create a jpg file in the avatar folder, write marker to database
    $target_file_path = Config::get('PATH_AVATARS') . Session::get('user_id');
    AvatarModel::resizeAvatarImage($_FILES['avatar_file']['tmp_name'], $target_file_path, Config::get('AVATAR_SIZE'), Config::get('AVATAR_SIZE'), Config::get('AVATAR_JPEG_QUALITY'));
    AvatarModel::writeAvatarToDatabase(Session::get('user_id'));
    Session::set('user_avatar_file', AvatarModel::getPublicUserAvatarFilePathByUserId(Session::get('user_id')));
    Session::add('feedback_positive', Text::get('FEEDBACK_AVATAR_UPLOAD_SUCCESSFUL'));
    return true;
}

public static function resizeAvatarImage($source_image, $destination, $final_width = 130, $final_height = 130, $quality = 8)
{
    list($width, $height) = getimagesize($source_image);

    if (!$width || !$height) {
        return false;
    }

    //saving the image into memory (for manipulation with GD Library)
    $myImage = imagecreatefromjpeg($source_image);

    // calculating the part of the image to use for thumbnail
    if ($width > $height) {
        $y = 0;
        $x = ($width - $height) / 2;
        $smallestSide = $height;
    } else {
        $x = 0;
        $y = ($height - $width) / 2;
        $smallestSide = $width;
    }

    // copying the part into thumbnail, maybe edit this for square avatars
    $thumb = imagecreatetruecolor($final_width, $final_height);
    imagecopyresampled($thumb, $myImage, 0, 0, $x, $y, $final_width, $final_height, $smallestSide, $smallestSide);

    // add '.jpg' to file path, save it as a .jpg file with our $destination_filename parameter
    $destination .= '.jpg';
    imagejpeg($thumb, $destination, $quality);

    // delete "working copy"
    imagedestroy($thumb);

    if (file_exists($destination)) {
        return true;
    }
    // default return
    return false;
}

public static function writeAvatarToDatabase($user_id)
{
    $database = DatabaseFactory::getFactory()->getConnection();

    $query = $database->prepare("UPDATE users SET user_has_avatar = TRUE WHERE user_id = :user_id LIMIT 1");
    $query->execute(array(':user_id' => $user_id));
}

This particular part is where the issue lies

    $destination .= '.jpg';
    imagejpeg($thumb, $destination, $quality);

I've tried adding a switch on the file type and then doing imagejpeg/png/jpg(,,,) depending which filetype the file has and it didn't work as it seemed to be trying to pass a .tmp file.

Any ideas?

886

Answer

Solution:

You will want to create the image from the beginning as the intended file. Here is a class I use, and then added into your class. You can copy from the one class to the other, but you can see where you need to change things at least:

class   AvatarModel
    {
        public static function resizeAvatarImage($source_image, $destination, $final_width = 130, $final_height = 130, $quality = 8)
            {
                // Initiate class
                $ImageMaker =   new ImageFactory();

                // Here is just a test landscape sized image
                $source_image   =   'http://media1.santabanta.com/full6/Outdoors/Landscapes/landscapes-246a.jpg';

                // This will save the file to disk. $destination is where the file will save and with what name
            //  $destination    =   'image60px.jpg';
            //  $ImageMaker->Thumbnailer($source_image,$final_width,$final_height,$destination,$quality);

                // This example will just display to browser, not save to disk
                 $ImageMaker->Thumbnailer($source_image,$final_width,$final_height,false,$quality);
            }
    }

class ImageFactory
    {
        public      $destination;

        protected   $original;

        public  function FetchOriginal($file)
            {
                $size                       =   getimagesize($file);
                $this->original['width']    =   $size[0];
                $this->original['height']   =   $size[1];
                $this->original['type']     =   $size['mime'];
                return $this;
            }

        public  function Thumbnailer($thumb_target = '', $width = 60,$height = 60,$SetFileName = false, $quality = 80)
            {
                // Set original file settings
                $this->FetchOriginal($thumb_target);
                // Determine kind to extract from
                if($this->original['type'] == 'image/gif')
                    $thumb_img  =   imagecreatefromgif($thumb_target);
                elseif($this->original['type'] == 'image/png') {
                        $thumb_img  =   imagecreatefrompng($thumb_target);
                        $quality    =   7;
                    }
                elseif($this->original['type'] == 'image/jpeg')
                        $thumb_img  =   imagecreatefromjpeg($thumb_target);
                else
                    return false;
                // Assign variables for calculations
                $w  =   $this->original['width'];
                $h  =   $this->original['height'];
                // Calculate proportional height/width
                if($w > $h) {
                        $new_height =   $height;
                        $new_width  =   floor($w * ($new_height / $h));
                        $crop_x     =   ceil(($w - $h) / 2);
                        $crop_y     =   0;
                    }
                else {
                        $new_width  =   $width;
                        $new_height =   floor( $h * ( $new_width / $w ));
                        $crop_x     =   0;
                        $crop_y     =   ceil(($h - $w) / 2);
                    }
                // New image
                $tmp_img = imagecreatetruecolor($width,$height);
                // Copy/crop action
                imagecopyresampled($tmp_img, $thumb_img, 0, 0, $crop_x, $crop_y, $new_width, $new_height, $w, $h);
                // If false, send browser header for output to browser window
                if($SetFileName == false)
                    header('Content-Type: '.$this->original['type']);
                // Output proper image type
                if($this->original['type'] == 'image/gif')
                    imagegif($tmp_img);
                elseif($this->original['type'] == 'image/png')
                    ($SetFileName !== false)? imagepng($tmp_img, $SetFileName, $quality) : imagepng($tmp_img);
                elseif($this->original['type'] == 'image/jpeg')
                    ($SetFileName !== false)? imagejpeg($tmp_img, $SetFileName, $quality) : imagejpeg($tmp_img);
                // Destroy set images
                if(isset($thumb_img))
                    imagedestroy($thumb_img); 
                // Destroy image
                if(isset($tmp_img))
                    imagedestroy($tmp_img);
            }
    }

    AvatarModel::resizeAvatarImage();

People are also looking for solutions to the problem: php - Docker-compose volume changed update slowly (how to fix)

Source

Didn't find the answer?

Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.

Ask a Question

Write quick answer

Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.

Similar questions

Find the answer in similar questions on our website.