skip to Main Content

I’m trying to upload image via PHP, but I’m unable to upload an image with 100% quality.

The code I’m actually using

class imaging
{

    // Variables
    private $img_input;
    private $img_output;
    private $img_src;
    private $format;
    private $quality = 100;
    private $x_input;
    private $y_input;
    private $x_output;
    private $y_output;
    private $resize;

    // Set image
    public function upload($orig, $name, $path)
    {
        move_uploaded_file($orig, __DIR__ . "/../uploads/" . $path . 'orig_' . $name);
    }

    public function set_img($img)
    {
        //$img = __DIR__ . '/../uploads/' . $img;

        $img = '../uploads/' . $img;

        // Find format
        $ext = strtoupper(pathinfo($img, PATHINFO_EXTENSION));

        // JPEG image
        if(is_file($img) && ($ext == "JPG" OR $ext == "JPEG"))
        {
            $this->format = $ext;
            $this->img_input = ImageCreateFromJPEG($img);
            $this->img_src = $img;

        }

        // PNG image
        elseif(is_file($img) && $ext == "PNG")
        {

            $this->format = $ext;
            $this->img_input = ImageCreateFromPNG($img);
            $this->img_src = $img;

        }

        // GIF image
        elseif(is_file($img) && $ext == "GIF")
        {

            $this->format = $ext;
            $this->img_input = ImageCreateFromGIF($img);
            $this->img_src = $img;

        }

        // Get dimensions
        $this->x_input = imagesx($this->img_input);
        $this->y_input = imagesy($this->img_input);
    }

    // Set maximum image size (pixels)
    public function set_size($size = 100)
    {
        // Wide
        if($this->x_input >= $this->y_input && $this->x_input > $size)
        {
            $this->x_output = $size;
            $this->y_output = ($this->x_output / $this->x_input) * $this->y_input;

            $this->resize = TRUE;
        }

        // Tall
        elseif($this->y_input > $this->x_input && $this->y_input > $size)
        {
            $this->y_output = $size;
            $this->x_output = ($this->y_output / $this->y_input) * $this->x_input;

            $this->resize = TRUE;
        }

        // Don't resize
        else { $this->resize = FALSE; }

    }

    // Set image quality (JPEG only)
    public function set_quality($quality)
    {

        if(is_int($quality))
        {

            $this->quality = $quality;

        }

    }

    // Save image
    public function save_img($path)
    {

        // Resize
        if($this->resize)
        {

            $this->img_output = ImageCreateTrueColor($this->x_output, $this->y_output);
            ImageCopyResampled($this->img_output, $this->img_input, 0, 0, 0, 0, $this->x_output, $this->y_output, $this->x_input, $this->y_input);

        }

        // Save JPEG
        if($this->format == "JPG" OR $this->format == "JPEG")
        {

            if($this->resize) { imageJPEG($this->img_output, __DIR__ . "/../uploads/" . $path, $this->quality); }
            else { copy($this->img_src, __DIR__ . "/../uploads/" . $path); }

        }

        // Save PNG
        elseif($this->format == "PNG")
        {

            if($this->resize) { imagePNG($this->img_output, __DIR__ . "/../uploads/" . $path, 9); }
            else { copy($this->img_src, __DIR__ . "/../uploads/" . $path); }

        }

        // Save GIF
        elseif($this->format == "GIF")
        {

            if($this->resize) { imageGIF($this->img_output, __DIR__ . "/../uploads/" . $path); }
            else { copy($this->img_src, __DIR__ . "/../uploads/" . $path); }

        }

    }

    // Get width
    public function get_width()
    {

        return $this->x_input;

    }

    // Get height
    public function get_height()
    {

        return $this->y_input;

    }

    // Clear image cache
    public function clear_cache()
    {

        @ImageDestroy($this->img_input);
        @ImageDestroy($this->img_output);

    }

}

And calling upload

$img = new imaging;
$img->upload($src['tmp_name'], $name, $dir);
$img->set_img($dir . 'orig_' . $name); // upload original file
$img->set_quality(100);

// Small thumbnail
$img->set_size(700);                   // upload thumbnail
$img->save_img($dir . $name);

// Finalize
$img->clear_cache();

Result isn’t very good, instead of setting quality=100. Original file (width cca 1100px) is uploaded correctly (no resize on server), when I open it in Photoshop, resize to 700px width and compare with 700px thumb resized in PHP, there is very big difference in quality.

See both images, original resized in Photoshop (top) and resize image via PHP (bottom) – texts, images, etc. are blurred, colors aren’t bright.

Orig size
enter image description here

200% zoom in Photoshop
enter image description here

Any ideas? Thanks for your replies 🙂

4

Answers


  1. I’m gonna answer here because I don’t have enough reputation to make a comment.

    To resize the image, i think it’s better to use the command imagescale. It’s better that use ImageCreateTrueColor + ImageCopyResampled.

    So I’d do it

            // Resize
            if($this->resize)
            {
                $this->img_output = imagescale($this->img_input, $this->x_output, $this->y_output);
    
            }
    

    But there are some other things that you also may change:

    • I created the method create_thumbnail() and you’ll pass it the path to the image, the path where save the new image and optionally the size (Default 100).
    • To have the width and the height, you don’t need to create the image. You can do it with the method getimagesize and like this, you’ll save a lot of resources.
    • When you call the method to resize, it will resize the image if it needed.
    • And when you are going to save the image, you can know if the image has been resized or not and so you’ll copy it or not.

    Also, I’ve tried to not repeat any code and optimising the resources.

    EDIT: Also you can clear the cache and the end of the process.

    class imaging
    {
    
        // Variables
        private $img_input;
        private $img_output;
        private $img_src;
        private $format;
        private $quality = 100;
        private $x_input;
        private $y_input;
        private $x_output;
        private $y_output;
        private $resize;
    
        // Set image
        public function upload($orig, $name, $path)
        {
            move_uploaded_file($orig, __DIR__ . "/../uploads/" . $path . 'orig_' . $name);
        }
    
            // Set image quality (JPEG only)
        public function set_quality($quality)
        {
    
            if(is_int($quality))
            {
    
                $this->quality = $quality;
    
            }
    
        }
    
        // Set maximum image size (pixels)
        private function resize($size = 100)
        {   
            $resize = FALSE; 
            // Wide
            if($this->x_input >= $this->y_input && $this->x_input > $size)
            {
                $this->x_output = $size;
                $this->y_output = ($this->x_output / $this->x_input) * $this->y_input;
    
                $resize = TRUE;
            }
    
            // Tall
            elseif($this->y_input > $this->x_input && $this->y_input > $size)
            {
                $this->y_output = $size;
                $this->x_output = ($this->y_output / $this->y_input) * $this->x_input;
    
                $resize = TRUE;
            }
    
            if($resize){
    
                switch ($this->format) {
                    case 'JPEG':
                    case 'JPG':
                        $this->img_input = ImageCreateFromJPEG($img);
                        break;
                    case 'PNG':
                        $this->img_input = ImageCreateFromPNG($img);
                        break;
                    case 'GIF':
                        $this->img_input = ImageCreateFromGIF($img);
                        break;
                    
                    default:
                        throw new Exception("This extension " . $ext . " it's not compatible.");
                        
                        break;
                }
    
            }
    
        }
    
        // Save image
        public function save_img($path)
        {
            // We have resized the image
            if($this->img_input){
                switch ($this->format) {
                    case 'JPEG':
                    case 'JPG':
                        imageJPEG($this->img_output, __DIR__ . "/../uploads/" . $path, $this->quality);
                        break;
                    case 'PNG':
                        imagePNG( $this->img_output, __DIR__ . "/../uploads/" . $path, 9);
                        break;
                    case 'GIF':
                        imageGIF( $this->img_output, __DIR__ . "/../uploads/" . $path);
                        break;
                    
                    default:
                        throw new Exception("This extension " . $ext . " it's not compatible.");
                        
                        break;
                }
            }else{
                copy($this->img_src, __DIR__ . "/../uploads/" . $path);
            }
    
        }
    
        public function create_thumbnail($imgSrc, $savePath, $size = 100)
        {
            $this->img_src = '../uploads/' . $img;
    
            if(file_exists($this->img_src)){
                list($this->x_input, $this->y_input) = getimagesize($imageSrc);
                $this->format = strtoupper(pathinfo($img, PATHINFO_EXTENSION));
                $this->resize($size);
                $this->save_img($savePath);
                $this->clear_cache();
            }else{
                throw new Exception("Image not found in " . $imdSrc);
            }
    
        }
    
        // Get width
        public function get_width()
        {
    
            return $this->x_input;
    
        }
    
        // Get height
        public function get_height()
        {
    
            return $this->y_input;
    
        }
    
        // Clear image cache
        public function clear_cache()
        {
    
            @ImageDestroy($this->img_input);
            @ImageDestroy($this->img_output);
    
        }
    
    }
    
    Login or Signup to reply.
  2. You can give this package a try http://image.intervention.io/getting_started/introduction . http://image.intervention.io/getting_started/installation, here it has all the configuration instruction.
    It should work correctly and very easy to setup with composer.

    Login or Signup to reply.
  3. I suggest you to use Intervention Image Library for image handling and manipulation. I have this type of issue in past and switching to a different library solved the issue.

    Secondly, the use of this library is extremely simple which is already available on website.

    Login or Signup to reply.
  4. I will recommend

    convert your image into base64 then update the base64 string then on server side again covert that base64 string into image. you will find the method for conversion

    image to base64: https://stackoverflow.com/a/13758760/11956865

    base64 to image: https://stackoverflow.com/a/15153931/11956865

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search