1

I have already mentioned below that There is answer in stackoverflow but that didn't work for me because that answer is like imagecreatetruecolor($width, $height) but In my code I don't have width and height. My code is totally different. Please Kindly remove this duplicate tag.
I am trying to compress image during upload, It compress fine for jpg images but when i upload png transparent image then it saves with black background, I have googled a lot but didn't find any perfect solution according to my code. There was answer of imagecreatetruecolor($width, $height), But there is no width and height variables in my code, I am totally confused and stuck.
Here is my function code:

public function updateProfilePic($file, $userid) {
    $filename = $file['user_img']['name'];
    $filetmp = $file['user_img']['tmp_name'];
    $valid_ext = array('png', 'jpeg', 'jpg');
    $location = "user/profilepic/" . $filename;
    $file_extension = pathinfo($location, PATHINFO_EXTENSION);
    $file_extensionstr = strtolower($file_extension);

    if(!empty($filename)){
        if (in_array($file_extensionstr, $valid_ext)) {
            $this->compressImage($filetmp, $location, 50);
            // Here I am trying to compress image

            return $this->updateProfilePicture($filename, $userid);
        } else {
            $msg = 'Invalid file type. You can upload only:-' . implode(', ', $valid_ext) . '';
            return $msg;
        }
    } else {
        $msg = 'Please upload your profile picture.';
        return $msg;
    }
}

public function compressImage($source, $destination, $quality) {
    $info = getimagesize($source);

    if ($info['mime'] == 'image/jpeg'){
        $image = imagecreatefromjpeg($source);
    } elseif ($info['mime'] == 'image/png'){
        $image = imagecreatefrompng($source);
    }

    imagejpeg($image, $destination, $quality);

}

Updated Code of what you was saying:

public function compressImage($source, $destination, $quality) {
        $info = getimagesize($source);
        $width_new = $info[0];
        $height_new = $info[1];

        $dimg = imagecreatetruecolor($width_new, $height_new);
        $background = imagecolorallocate($dimg , 0, 0, 0);
        imagecolortransparent($dimg, $background);
        imagealphablending($dimg, false);
        imagesavealpha($dimg, true);

        if ($info['mime'] == 'image/jpeg'){
            $image = imagecreatefromjpeg($source);
        } elseif ($info['mime'] == 'image/png'){
            $image = imagecreatefrompng($source);
        }

        imagejpeg($image, $destination, $quality);

    }

Please check my code first and then tell me the solution. Please help me

Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
Zain Shabir
  • 75
  • 1
  • 1
  • 8

1 Answers1

0

This seems to work for me - the compressImage method has simply been wrapped in a dummy class for testing. Calling the method as shown created a nice , transparent PNG image in the output directory.

class fudd{

    public function __construct(){

    }

    public function compressImage( $source, $destination, $quality ) {
        list( $width, $height, $type, $attr ) = getimagesize( $source );
        $target=sprintf('%s/%s',$destination, pathinfo( $source, PATHINFO_BASENAME ) );
        $quality=$quality > 9 ? 5 : $quality;

        switch( image_type_to_mime_type( $type ) ){
            case 'image/jpeg':
                $image = imagecreatefromjpeg( $source );
                imagejpeg( $image, $target, $quality );
            break;
            case 'image/png':
                $image = imagecreatefrompng( $source );
                $bck   = imagecolorallocate( $image , 0, 0, 0 );
                imagecolortransparent( $image, $bck );
                imagealphablending( $image, false );
                imagesavealpha( $image, true );
                imagepng( $image, $target, $quality );
            break;
            default:
                exit( $type );
            break;              
        }
        imagedestroy( $image );
    }
}//end fudd



$img='c:/wwwroot/images/ict_cmyk_jigsaw_1.png';
$destination='c:/temp/fileuploads/stack/';
$quality=50;

$foo=new fudd;
$foo->compressImage( $img, $destination, $quality );

The resultant image

Try like so ( use a pre-defined name for the image ):

public function compressImage( $source, $destination, $quality ) {
    list( $width, $height, $type, $attr ) = getimagesize( $source );
    $quality=$quality > 9 ? 5 : $quality;

    switch( image_type_to_mime_type( $type ) ){
        case 'image/jpeg':
            $image = imagecreatefromjpeg( $source );
            imagejpeg( $image, $destination, $quality );
        break;
        case 'image/png':
            $image = imagecreatefrompng( $source );
            $bck   = imagecolorallocate( $image , 0, 0, 0 );
            imagecolortransparent( $image, $bck );
            imagealphablending( $image, false );
            imagesavealpha( $image, true );
            imagepng( $image, $destination, $quality );
        break;
        default:
            exit( $type );
        break;              
    }
    imagedestroy( $image );
}

I had a quick play writing a webp image, perhaps it'll be of interest. ( The $destination needs to be edited for your use ) ~ basically feed in an image of one of the types shown in the method body (jpg,png,gif,webp ) and set the compression/quality ~ far from fully tested though

public function createwebpimage( $source=false, $destination=null, $quality=50 ){
    if( $source ){

        list( $width, $height, $type, $attr ) = getimagesize( $source );
        $destination=sprintf( '%s/%s.webp', $destination, pathinfo( $source, PATHINFO_FILENAME ) );

        switch( image_type_to_mime_type( $type ) ){
            case 'image/jpeg':
                $image = imagecreatefromjpeg( $source );
            break;
            case 'image/png':
                $image = imagecreatefrompng( $source );
                $bck   = imagecolorallocate( $image , 0, 0, 0 );
                imagecolortransparent( $image, $bck );
                imagealphablending( $image, false );
                imagesavealpha( $image, true );
            break;
            case 'image/gif':
                $image = imagecreatefromgif( $source );
            break;
            case 'image/webp':
                $image=imagecreatefromwebp( $source );
            break;
            default:exit('invalid image type');
        }

        imagewebp( $image, $destination, $quality );
    }
}
Professor Abronsius
  • 33,063
  • 5
  • 32
  • 46
  • Brother It's giving me error after uploading image `Warning: imagepng(user/profilepic/executive-package.png/php1B94.tmp): failed to open stream: No such file or directory in E:\xampp\htdocs\zain\lunch\classes\User.php on line 402` --- `executive_package.png` is my image but I don't know what's that `php1B94.tmp` – Zain Shabir Oct 21 '19 at 06:55
  • You will need to edit `$target=sprintf('%s/%s',$destination, pathinfo( $source, PATHINFO_BASENAME ) );` as that was appropriate for my system. Presumably your `destination` variable is `user/profilepic/executive-package.png` ??? – Professor Abronsius Oct 21 '19 at 07:02
  • what is `$destination`? is it `user/profilepic/executive-package.png` ?? – Professor Abronsius Oct 21 '19 at 07:04
  • yes It's like this: `$location = "user/profilepic/" . $filename;` and the full address is `http://localhost/zain/lunch/user/profilepic/$filename` – Zain Shabir Oct 21 '19 at 07:05
  • PNG is a `Lossless` format and compression ratios for images / photos are not good. Using PNG for large images is not recommended. I tried to replicate what you say and observed similar behaviour. You might wish to investigate using `webp` images - look at https://developers.google.com/speed/webp/gallery2 for size comparisons – Professor Abronsius Oct 21 '19 at 07:21
  • Ammmm. Working fine than before. On `PNG` image It is increasing the image size not decreasing/compressing – Zain Shabir Oct 21 '19 at 07:25
  • yeah It's fine. As long as it's not giving black background. It's good for me – Zain Shabir Oct 21 '19 at 07:25
  • `webp` is the way forward - much smaller file sizes and you can have transparency – Professor Abronsius Oct 21 '19 at 07:37