WI accepting JPEGs 150Kb or less

2012-05-09
2013-05-28
  • Joel Martin
    Joel Martin
    2012-05-09

    Something odd is occuring with my installation of WI on my server. I am uploading product photos in jpeg format, nothing over 1MB and for some reason, photos that are roughly 150Kb or less are uploading, resizing and cropping and being inserted into the database just fine. But when I try a jpeg that is roughly 150Kb or more, it does not resize, crop and insert the photo.

    I've blended down the code to as basic as I could get it, here it is:

    if(WideImage::load($photo[$each]['tmp_name'])->getWidth() > 1000) {
                $image_full = WideImage::load($photo[$each]['tmp_name'])->resizeDown('1000', NULL, 'inside');
            } else {
                $image_full = WideImage::load($photo[$each]['tmp_name']);
            }
            $image_thumb1 = WideImage::load($photo[$each]['tmp_name'])->resizeDown(NULL, '300')->crop('center', 'middle', 300, 300);
            $image_thumb2 = WideImage::load($photo[$each]['tmp_name'])->resizeDown(NULL, '50')->crop('center', 'middle', 50, 50);
            
            if ($num == '1') {
                $image_thumb3 = WideImage::load($photo[$each]['tmp_name'])->resizeDown(NULL, '195')->crop('center', 'middle', 195, 195);
                $image_thumb4 = WideImage::load($photo[$each]['tmp_name'])->resizeDown(NULL, '95')->crop('center', 'middle', 95, 95);
            }
    

    As I said, small jpegs work just fine and are damn sexier than what I was achieving with Imagick. Any ideas?

     
  • Gasper Kozak
    Gasper Kozak
    2012-05-10

    Do you get any errors? This looks like a memory issue to me. The size of the file doesn't matter, the dimensions do. Image takes more than up width*height*4 bytes of memory once loaded, so a 2500x2000 image uses more than 20MB of memory. Are you hitting your memory_limit by any chance?

     
  • Joel Martin
    Joel Martin
    2012-05-10

    I suppose it could be. But the images I am working with at most would maybe be 3MBs on your calculation. The server this site is on was a custom Linux Gentoo install by the development company who hasn't been around in over 2 years, the typically work a rounds the php memory limit I have tried do not work, but I don't necessarily want to go to a new server, or spend time manually re-sizing all the images first.

    Have any tricks or ideas I could try?

     
  • Joel Martin
    Joel Martin
    2012-05-10

    Just cracked open the phpinfo and check the current memory_limit is 64M at the local value and was 128M at the master value.

     
  • Klemen Slavič
    Klemen Slavič
    2012-05-10

    The code you've posted looks like it's running in a loop. Remember that all operations in WideImage create a copy of the image, it doesn't modify the original image. It could be that you're hitting the memory limit because you're storing references to previous intermediate images somewhere and the GC hasn't had time to clean up any images left over. Have a look at the destroy methods in the API to manually deallocate the memory after you're done with the image inside the loop. ( http://wideimage.sourceforge.net/wp-content/current/doc/WideImage/WideImage_Image.html#methoddestroy )

    As for the memory limit, the 64MB includes all the heap and stack for the application; you may only have a fraction of that available for WideImage, depending on your web app and framework (if using any). That may explain why you're hitting the limit so fast.

     
  • Joel Martin
    Joel Martin
    2012-05-10

    Secondly, max file upload is set at 2MB, which is probably my culprit. Problem is I have no access to the php.ini file and do not have the 'root' account info to even change it, might have to just dump this server and start on a new one.

     
  • Joel Martin
    Joel Martin
    2012-05-10

    Here is the full code set:

    include('wideImage/WideImage.php');
    $num=1;
    foreach($photo as $each => $values) {
        if ($photo[$each]['tmp_name']) {
            
            if(WideImage::load($photo[$each]['tmp_name'])->getWidth() > 1000) {
                $image_full = WideImage::load($photo[$each]['tmp_name'])->resizeDown('1000', NULL, 'inside');
            } else {
                $image_full = WideImage::load($photo[$each]['tmp_name']);
            }
            $image_thumb1 = WideImage::load($photo[$each]['tmp_name'])->resizeDown(NULL, '300')->crop('center', 'middle', 300, 300);
            $image_thumb2 = WideImage::load($photo[$each]['tmp_name'])->resizeDown(NULL, '50')->crop('center', 'middle', 50, 50);
            
            if ($num == '1') {
                $image_thumb3 = WideImage::load($photo[$each]['tmp_name'])->resizeDown(NULL, '195')->crop('center', 'middle', 195, 195);
                $image_thumb4 = WideImage::load($photo[$each]['tmp_name'])->resizeDown(NULL, '95')->crop('center', 'middle', 95, 95);
            }
    
            $connect = new mysqli($db_server, $db_username, $db_password, $db_name);
            if($num == '1') {
                $queryline = "UPDATE products SET image".$num."_full = ?, image".$num."_thumb1 = ?, image".$num."_thumb2 = ?, image".$num."_thumb3 = ?, image".$num."_thumb4 = ? 
            WHERE id = ?";
            } else {
                $queryline = "UPDATE products SET image".$num."_full = ?, image".$num."_thumb1 = ?, image".$num."_thumb2 = ? WHERE id = ?";
            }
    
            if ($query = $connect->prepare($queryline)) {
                $null = NULL;
                if($num == '1') {
                    $query->bind_param('bbbbbi',$null,$null,$null,$null,$null,$id);
                } else {
                    $query->bind_param('bbbi',$null,$null,$null,$id);
                }
    
                //Send Full Image
                $query->send_long_data(0, $image_full);
                unset($image_full);
    
                //Send Product Display Image
                $query->send_long_data(1, $image_thumb1);
                unset($image_thumb1);
    
                //Send Mini-thumb
                $query->send_long_data(2, $image_thumb2);
                unset($image_thumb2);
    
                //Cart and Category page images only if default image
                if ($num == '1') {
                    $query->send_long_data(3, $image_thumb3);
                    unset($image_thumb3);
                    $query->send_long_data(4, $image_thumb4);
                    unset($image_thumb4);
                }
                $query->execute();
            } else {
                printf("Errormessage: %s\n", $connect->error);
                printf("Errormessage: %s\n", $connect->sqlstate);
                printf("Errormessage: %s\n", $connect->dump_debug_info);
            }
        }
        $num++;
    }
    
     
  • Klemen Slavič
    Klemen Slavič
    2012-05-10

    Try destroying all `$image_*` images at the end of the loop. Also, you might want to check your PHP error log to see what exactly the error is; this way, we can only guess at what's really happening under the hood.

     
  • Joel Martin
    Joel Martin
    2012-05-10

    Well I managed to get SSH access to the server and got in and pumped the memory limit of the POST upload and file upload to 50M each. Tried to upload it again, same result. PHP Error logs are disabled, I have not been able to reactivate them in ssh.

     
  • Gasper Kozak
    Gasper Kozak
    2013-02-20

    Well, I see you're constantly loading the same image, which is at least very bad for performance and maybe using a lot more memory than necessary.

    You should load the image only once and work from that:
    $image = WideImage::load($photo);

    and then:
    if (…)
      $image_full = $image->resizeDown(…);
    else
      $Image_full = $image;