osCommerce / oscommerce2

osCommerce Online Merchant v2.x
http://www.oscommerce.com
MIT License
281 stars 222 forks source link

Proposal: Resized images instead of stretched images #607

Open mgutt opened 6 years ago

mgutt commented 6 years ago

I like to see this extension as part of the osC core: https://apps.oscommerce.com/Apps&7CTmT&on-the-fly-thumbnail-creator

No database changes or settings are needed. I used the osC coding style and original osC variables. The code changes as follows:

After this:

  function tep_image($src, $alt = '', $width = '', $height = '', $parameters = '') {
    if ( (empty($src) || ($src == DIR_WS_IMAGES)) && (IMAGE_REQUIRED == 'false') ) {
      return false;
    } 

this is added:

    // thumbnail
    if ($width || $height) {
      $thumb_path = DIR_WS_IMAGES . intval($width) . 'x' . intval($height) . '/';
      $thumb_src = $thumb_path . basename($src);
      // use thumbnail if available
      if (file_exists($thumb_src)) {
        $src = $thumb_src;
      }
      // create thumbnail with GD
      else if (function_exists('imagecreatetruecolor')) {
        $src = img_thumb_create($src, $thumb_src, $width, $height);
      }
      // use css to avoid stretching (this works because width:auto overwrites width="...")
      if (strpos($parameters, 'style=') === false) {
        $parameters .= ' style="';
        if ($width) {
          $parameters .= 'width:auto;max-width:' . intval($width) . 'px;';
        }
        if ($height) {
          $parameters .= 'height:auto;max-height:' . intval($height) . 'px;';
        }
        $parameters .= '"';
      }
      // use original image size to avoid stretching
      else if (CONFIG_CALCULATE_IMAGE_SIZE) {
        $image_size = @getimagesize($src);
        list($width, $height) = img_ratio_size($image_size[0], $image_size[1], $width, $height);
      }
    }

And these functions are added, too:

  function img_resize_gd($src, $mime, $width, $height, $dst, $new_width, $new_height) {
    $imagecreatefunc = 'imagecreatefrom' . $mime;
    $img = $imagecreatefunc($src);
    $new_img = imagecreatetruecolor($new_width, $new_height);
    imagecopyresampled($new_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
    imagedestroy($img);
    switch ($mime) {
      case 'gif':
        imagegif($new_img, $dst);
        break;
      case 'jpeg':
        imagejpeg($new_img, $dst, 90);
        break;
      case 'png':
        imagepng($new_img, $dst, 9);
        break;
    }
    imagedestroy($new_img);
    return file_exists($dst);
  }

  function img_ratio_size($width, $height, $max_width, $max_height) {
    $ratio = min(($max_width ? $max_width / $width : 1) , ($max_height ? $max_height / $height : 1));
    return array(intval($width * $ratio), intval($height * $ratio));
  }

  function img_thumb_create($src, $dst, $thumb_width, $thumb_height) {
    $size = @getimagesize($src);
    // check if all needed image data is available
    if (!$size || !$size[0] || !$size[1] || !$size['mime']) {
      return $src;
    }
    // we resize only specific image types
    if (!preg_match('/^image\/(gif|jpg|jpeg|png)$/i', $size['mime'], $mime)) {
      return $src;
    }
    $width = $size[0];
    $height = $size[1];
    if ($mime[1] == 'jpg') {
      $mime[1] = 'jpeg';
    }
    // get thumbnail size
    list($new_width, $new_height) = img_ratio_size($width, $height, $thumb_width, $thumb_height);
    // no resizing needed
    if ($width <= $new_width && $height <= $new_height) {
      return $src;
    }
    // reset thumbnail cache
    //array_map('unlink', glob(dirname($dst) . "/*.*"));
    // create thumbnail dir if necessary
    if (!file_exists(dirname($dst))) {
      if (!mkdir(dirname($dst), 0755, true)) {
        return $src;
      }
    }
    // set memory limit on the fly
    $bits = isset($size['bits']) ? $size['bits'] : 32;
    $channels = isset($size['channels']) ? $size['channels'] : 8;
    $K64 = pow(2,16); // number of bytes in 64K
    $factor = 1.7;
    $memory_needed = ($width * $height * $bits * $channels / 8 + $K64) * $factor;
    $memory_limit = intval(ini_get('memory_limit')) * pow(1024, 2); // if --disable-memorylimit is set this is 0
    $memory_usage = function_exists('memory_get_usage') ? memory_get_usage() : 0;
    $memory_new_limit = min(134217728, $memory_needed + $memory_usage);// do not set more than 128 MB
    if ($memory_limit && $memory_new_limit > $memory_limit) {
      // try to set the new limit
      if (!ini_set('memory_limit', ceil($memory_new_limit / pow(1024, 2)) . 'M')) {
        return false;
      }
    }
    // create thumbnail
    if (img_resize_gd($src, $mime[1], $width, $height, $dst, $new_width, $new_height)) {
      return $dst;
    }
    return $src;
  }

Features: 1.) Creates thumbnails on-the-fly in DIR_WS_IMAGES subfolders like "130x130/" 2.) No stretching 3.) Faster loading time because of smaller images 4.) Adds the option to resize any image by passing width or height value like tep_image($image_filename, '', 120) or tep_image($image_filename, '', '', 120) 5.) Does not throw any error if GD is not enabled 6.) Sets a higher memory_limit on the fly (if supported) 7.) No settings needed 8.) No database changes

What is missing: