3

I get images as base64 encoded string front end and I have to decode them and save them as images in server. Image can be of any format- png,gif or jpeg. This part works fine. But sometimes the images uploaded by the users can be of very large size, so I'm trying to compress them from backend and this part failed miserably.

I have two functions. One for converting base64 string to image and other one for compressing it.

This is the function that converts the string to an image.

function uploadTimelineImage($base64Img)
{
    $data= array(); 
    $upAt=date('YmdHis');

    if (strpos($base64Img, 'data:image/png;base64') !== false) 
    {
        $img = str_replace('data:image/png;base64,', '', $base64Img);
        $img = str_replace(' ', '+', $img);
        $data = base64_decode($img);    
        $extension= 'png';
    }

    if (strpos($base64Img, 'data:image/gif;base64') !== false) 
    {
        $img = str_replace('data:image/gif;base64,', '', $base64Img);
        $img = str_replace(' ', '+', $img);
        $data = base64_decode($img);    
        $extension= 'gif'; 
    }

    if (strpos($base64Img, 'data:image/jpeg;base64') !== false) 
    {
        $img = str_replace('data:image/jpeg;base64,', '', $base64Img);
        $img = str_replace(' ', '+', $img);
        $data = base64_decode($img);    
        $extension= 'jpeg'; 
    }

    $fileName     = 'img'.$upAt.$extension;
    $filePath     = 'foldername/'.'img'.$upAt.$extension;

    //upload image to folder
    $success = file_put_contents($filePath, $data);
    $result  = $success ? 1 : 0;

    //call to compression function
    $compressThisImg= $filePath;
    $d = compress($compressThisImg, $fileName, 80);

    if($result==1)
    {
        return $fileName;
    }
    else
    {
        return null;
    }

}

And this is the function that does compressing:

//Function to compress an image
function compress($source, $destination, $quality) 
{
    $info = getimagesize($source);

    if ($info['mime'] == 'image/jpeg') 
        $image = imagecreatefromjpeg($source);

    elseif ($info['mime'] == 'image/gif') 
        $image = imagecreatefromgif($source);

    elseif ($info['mime'] == 'image/png') 
        $image = imagecreatefrompng($source);

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

    return $destination;
}

But the above function does not do any compression, it throws error:

 failed to open stream: No such file or directory

and my function uploads the original image.

version 2
  • 1,049
  • 3
  • 15
  • 36
  • A general remark: trying to compress images of an already compressed format (png, gif, jpg) does not make any sense. – arkascha Aug 08 '16 at 12:36
  • If the image is that large, maybe your system's `.ini` files need to be adjusted in order to handle bigger files. If the larger files do get uploaded though, then you can scratch this comment. Something else is causing this and I can't see what it is. However, check the path settings and permissions. – Funk Forty Niner Aug 08 '16 at 12:41
  • It will reduce the size anyway and yeah, I know I will lose clarity as well. Is there anyway to reduce the size of the image from the backend. As far as I know, base64 converts an image to string, it doesnot reduce size. i checked the original file and the uploaded file. @arkascha – version 2 Aug 08 '16 at 12:43
  • It's not about uploading larger images, I'm trying to compress them a little bit so they will get loaded a little bit fast. @Fred -ii- – version 2 Aug 08 '16 at 12:44
  • The *failed to open stream: No such file or directory* error to me, tells me that the compressed image isn't being saved (and/or read) correctly; that's what I get from this. @AmeliaEarheart – Funk Forty Niner Aug 08 '16 at 12:45
  • No! Compressing an already compressed image will _not_ reduce its size! At least not above a trivial level. So it makes no sense. And it would _not_ reduce sharpness, you got that wrong. There are different types of compression. You'd have to decompress it again anyway on the receiving side, otherwise you do not have an image, but a compressed file. – arkascha Aug 08 '16 at 12:46
  • I'd sure like to know where/how `$destination` is assigned to. Again: `failed to open stream: No such file or directory` to me, most likely has something to do with this. I see you're in the answer below. I really hope that will solve the issue here. – Funk Forty Niner Aug 08 '16 at 12:53
  • Actually, what I'm trying to do is, compress the image and upload it but that didn't work well..so I was trying to upload the image first (that part worked well), then compress the image and replace the uploaded image with the compressed image. But compression didn't work. So, destination is same as the image path @Fred -ii- – version 2 Aug 08 '16 at 12:57
  • Ah, I see now; thanks for the clarification. I hope the answer works for you then :-) @AmeliaEarheart *fingers crossed* – Funk Forty Niner Aug 08 '16 at 13:01
  • Haha....Thank you sooo much @Fred -ii- – version 2 Aug 08 '16 at 13:08
  • @AmeliaEarheart You're welcome. However, that answer not working for you? I haven't seen it as being accepted or any other comments in there. – Funk Forty Niner Aug 08 '16 at 13:41
  • Sounds like a path problem to me. Can you post the full text of the error ? You can also troubleshoot the problem using this checklist : http://stackoverflow.com/questions/36577020/failed-to-open-stream-no-such-file-or-directory – Vic Seedoubleyew Aug 20 '16 at 08:57

1 Answers1

0

Why you dont use this function for create any type of image form base64 edncoded image string?

function uploadTimelineImage($base64Img,$h,$w)
{
    $im = imagecreatefromstring($base64Img);
    if ($im !== false) {


        $width = imagesx($im);
        $height = imagesy($im);
        $r = $width / $height; // ratio of image

        // calculating new size for maintain ratio of image
        if ($w/$h > $r) {
            $newwidth = $h*$r; 
            $newheight = $h;
        } else {
            $newheight = $w/$r;
            $newwidth = $w;
        }

        $dst = imagecreatetruecolor($newwidth, $newheight);
        imagecopyresampled($dst, $im, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
        imagedestroy($im);

        $fileName  = 'img'.date('Ymd').'.jpeg';
        $filepath =  'folder/'.$fileName  ;
        imagejpeg($dst,$filepath);

        imagedestroy($dst);
        return $fileName;
    }
    else
    {
        return "";
    }
}
Haresh Vidja
  • 8,340
  • 3
  • 25
  • 42