[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/ -> gdlib.php (source)

   1  <?php
   2  
   3  // This file is part of Moodle - http://moodle.org/
   4  //
   5  // Moodle is free software: you can redistribute it and/or modify
   6  // it under the terms of the GNU General Public License as published by
   7  // the Free Software Foundation, either version 3 of the License, or
   8  // (at your option) any later version.
   9  //
  10  // Moodle is distributed in the hope that it will be useful,
  11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13  // GNU General Public License for more details.
  14  //
  15  // You should have received a copy of the GNU General Public License
  16  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  17  
  18  /**
  19   * gdlib.php - Collection of routines in Moodle related to
  20   * processing images using GD
  21   *
  22   * @package   core
  23   * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  24   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  25   */
  26  
  27  defined('MOODLE_INTERNAL') || die();
  28  
  29  /**
  30   * Copies a rectangular portion of the source image to another rectangle in the destination image
  31   *
  32   * This function calls imagecopyresampled() if it is available and GD version is 2 at least.
  33   * Otherwise it reimplements the same behaviour. See the PHP manual page for more info.
  34   *
  35   * @link http://php.net/manual/en/function.imagecopyresampled.php
  36   * @param resource $dst_img the destination GD image resource
  37   * @param resource $src_img the source GD image resource
  38   * @param int $dst_x vthe X coordinate of the upper left corner in the destination image
  39   * @param int $dst_y the Y coordinate of the upper left corner in the destination image
  40   * @param int $src_x the X coordinate of the upper left corner in the source image
  41   * @param int $src_y the Y coordinate of the upper left corner in the source image
  42   * @param int $dst_w the width of the destination rectangle
  43   * @param int $dst_h the height of the destination rectangle
  44   * @param int $src_w the width of the source rectangle
  45   * @param int $src_h the height of the source rectangle
  46   * @return bool tru on success, false otherwise
  47   */
  48  function imagecopybicubic($dst_img, $src_img, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) {
  49      global $CFG;
  50  
  51      if (function_exists('imagecopyresampled')) {
  52         return imagecopyresampled($dst_img, $src_img, $dst_x, $dst_y, $src_x, $src_y,
  53                                   $dst_w, $dst_h, $src_w, $src_h);
  54      }
  55  
  56      $totalcolors = imagecolorstotal($src_img);
  57      for ($i=0; $i<$totalcolors; $i++) {
  58          if ($colors = imagecolorsforindex($src_img, $i)) {
  59              imagecolorallocate($dst_img, $colors['red'], $colors['green'], $colors['blue']);
  60          }
  61      }
  62  
  63      $scalex = ($src_w - 1) / $dst_w;
  64      $scaley = ($src_h - 1) / $dst_h;
  65  
  66      $scalex2 = $scalex / 2.0;
  67      $scaley2 = $scaley / 2.0;
  68  
  69      for ($j = 0; $j < $dst_h; $j++) {
  70          $sy = $j * $scaley;
  71  
  72          for ($i = 0; $i < $dst_w; $i++) {
  73              $sx = $i * $scalex;
  74  
  75              $c1 = imagecolorsforindex($src_img, imagecolorat($src_img, (int)$sx, (int)$sy + $scaley2));
  76              $c2 = imagecolorsforindex($src_img, imagecolorat($src_img, (int)$sx, (int)$sy));
  77              $c3 = imagecolorsforindex($src_img, imagecolorat($src_img, (int)$sx + $scalex2, (int)$sy + $scaley2));
  78              $c4 = imagecolorsforindex($src_img, imagecolorat($src_img, (int)$sx + $scalex2, (int)$sy));
  79  
  80              $red = (int) (($c1['red'] + $c2['red'] + $c3['red'] + $c4['red']) / 4);
  81              $green = (int) (($c1['green'] + $c2['green'] + $c3['green'] + $c4['green']) / 4);
  82              $blue = (int) (($c1['blue'] + $c2['blue'] + $c3['blue'] + $c4['blue']) / 4);
  83  
  84              $color = imagecolorclosest($dst_img, $red, $green, $blue);
  85              imagesetpixel($dst_img, $i + $dst_x, $j + $dst_y, $color);
  86          }
  87      }
  88  }
  89  
  90  /**
  91   * Stores optimised icon images in icon file area.
  92   *
  93   * Since 2.9 this function will generate an icon in the same format as the original file when possible.
  94   * To counter that behaviour, you can use the argument $preferpng to generate a PNG icon.
  95   *
  96   * @param context $context
  97   * @param string $component
  98   * @param string filearea
  99   * @param int $itemid
 100   * @param string $originalfile
 101   * @param boolean $preferpng When true, it will try to generate a PNG file regardless of the original file.
 102   * @return mixed new unique revision number or false if not saved
 103   */
 104  function process_new_icon($context, $component, $filearea, $itemid, $originalfile, $preferpng = false) {
 105      global $CFG;
 106  
 107      if (!is_file($originalfile)) {
 108          return false;
 109      }
 110  
 111      $imageinfo = getimagesize($originalfile);
 112      $imagefnc = '';
 113  
 114      if (empty($imageinfo)) {
 115          return false;
 116      }
 117  
 118      $image = new stdClass();
 119      $image->width  = $imageinfo[0];
 120      $image->height = $imageinfo[1];
 121      $image->type   = $imageinfo[2];
 122  
 123      $t = null;
 124      switch ($image->type) {
 125          case IMAGETYPE_GIF:
 126              if (function_exists('imagecreatefromgif')) {
 127                  $im = imagecreatefromgif($originalfile);
 128              } else {
 129                  debugging('GIF not supported on this server');
 130                  return false;
 131              }
 132              // Guess transparent colour from GIF.
 133              $transparent = imagecolortransparent($im);
 134              if ($transparent != -1) {
 135                  $t = imagecolorsforindex($im, $transparent);
 136              }
 137              break;
 138          case IMAGETYPE_JPEG:
 139              if (function_exists('imagecreatefromjpeg')) {
 140                  $im = imagecreatefromjpeg($originalfile);
 141              } else {
 142                  debugging('JPEG not supported on this server');
 143                  return false;
 144              }
 145              // If the user uploads a jpeg them we should process as a jpeg if possible.
 146              if (!$preferpng && function_exists('imagejpeg')) {
 147                  $imagefnc = 'imagejpeg';
 148                  $imageext = '.jpg';
 149                  $filters = null; // Not used.
 150                  $quality = 90;
 151              }
 152              break;
 153          case IMAGETYPE_PNG:
 154              if (function_exists('imagecreatefrompng')) {
 155                  $im = imagecreatefrompng($originalfile);
 156              } else {
 157                  debugging('PNG not supported on this server');
 158                  return false;
 159              }
 160              break;
 161          default:
 162              return false;
 163      }
 164  
 165      // The conversion has not been decided yet, let's apply defaults (png with fallback to jpg).
 166      if (empty($imagefnc)) {
 167          if (function_exists('imagepng')) {
 168              $imagefnc = 'imagepng';
 169              $imageext = '.png';
 170              $filters = PNG_NO_FILTER;
 171              $quality = 1;
 172          } else if (function_exists('imagejpeg')) {
 173              $imagefnc = 'imagejpeg';
 174              $imageext = '.jpg';
 175              $filters = null; // Not used.
 176              $quality = 90;
 177          } else {
 178              debugging('Jpeg and png not supported on this server, please fix server configuration');
 179              return false;
 180          }
 181      }
 182  
 183      if (function_exists('imagecreatetruecolor')) {
 184          $im1 = imagecreatetruecolor(100, 100);
 185          $im2 = imagecreatetruecolor(35, 35);
 186          $im3 = imagecreatetruecolor(512, 512);
 187          if ($image->type != IMAGETYPE_JPEG and $imagefnc === 'imagepng') {
 188              if ($t) {
 189                  // Transparent GIF hacking...
 190                  $transparentcolour = imagecolorallocate($im1 , $t['red'] , $t['green'] , $t['blue']);
 191                  imagecolortransparent($im1 , $transparentcolour);
 192                  $transparentcolour = imagecolorallocate($im2 , $t['red'] , $t['green'] , $t['blue']);
 193                  imagecolortransparent($im2 , $transparentcolour);
 194                  $transparentcolour = imagecolorallocate($im3 , $t['red'] , $t['green'] , $t['blue']);
 195                  imagecolortransparent($im3 , $transparentcolour);
 196              }
 197  
 198              imagealphablending($im1, false);
 199              $color = imagecolorallocatealpha($im1, 0, 0,  0, 127);
 200              imagefill($im1, 0, 0,  $color);
 201              imagesavealpha($im1, true);
 202  
 203              imagealphablending($im2, false);
 204              $color = imagecolorallocatealpha($im2, 0, 0,  0, 127);
 205              imagefill($im2, 0, 0,  $color);
 206              imagesavealpha($im2, true);
 207  
 208              imagealphablending($im3, false);
 209              $color = imagecolorallocatealpha($im3, 0, 0,  0, 127);
 210              imagefill($im3, 0, 0,  $color);
 211              imagesavealpha($im3, true);
 212          }
 213      } else {
 214          $im1 = imagecreate(100, 100);
 215          $im2 = imagecreate(35, 35);
 216          $im3 = imagecreate(512, 512);
 217      }
 218  
 219      $cx = $image->width / 2;
 220      $cy = $image->height / 2;
 221  
 222      if ($image->width < $image->height) {
 223          $half = floor($image->width / 2.0);
 224      } else {
 225          $half = floor($image->height / 2.0);
 226      }
 227  
 228      imagecopybicubic($im1, $im, 0, 0, $cx - $half, $cy - $half, 100, 100, $half * 2, $half * 2);
 229      imagecopybicubic($im2, $im, 0, 0, $cx - $half, $cy - $half, 35, 35, $half * 2, $half * 2);
 230      imagecopybicubic($im3, $im, 0, 0, $cx - $half, $cy - $half, 512, 512, $half * 2, $half * 2);
 231  
 232      $fs = get_file_storage();
 233  
 234      $icon = array('contextid'=>$context->id, 'component'=>$component, 'filearea'=>$filearea, 'itemid'=>$itemid, 'filepath'=>'/');
 235  
 236      ob_start();
 237      if (!$imagefnc($im1, NULL, $quality, $filters)) {
 238          // keep old icons
 239          ob_end_clean();
 240          return false;
 241      }
 242      $data = ob_get_clean();
 243      imagedestroy($im1);
 244      $icon['filename'] = 'f1'.$imageext;
 245      $fs->delete_area_files($context->id, $component, $filearea, $itemid);
 246      $file1 = $fs->create_file_from_string($icon, $data);
 247  
 248      ob_start();
 249      if (!$imagefnc($im2, NULL, $quality, $filters)) {
 250          ob_end_clean();
 251          $fs->delete_area_files($context->id, $component, $filearea, $itemid);
 252          return false;
 253      }
 254      $data = ob_get_clean();
 255      imagedestroy($im2);
 256      $icon['filename'] = 'f2'.$imageext;
 257      $fs->create_file_from_string($icon, $data);
 258  
 259      ob_start();
 260      if (!$imagefnc($im3, NULL, $quality, $filters)) {
 261          ob_end_clean();
 262          $fs->delete_area_files($context->id, $component, $filearea, $itemid);
 263          return false;
 264      }
 265      $data = ob_get_clean();
 266      imagedestroy($im3);
 267      $icon['filename'] = 'f3'.$imageext;
 268      $fs->create_file_from_string($icon, $data);
 269  
 270      return $file1->get_id();
 271  }
 272  
 273  /**
 274   * Generates a thumbnail for the given image
 275   *
 276   * If the GD library has at least version 2 and PNG support is available, the returned data
 277   * is the content of a transparent PNG file containing the thumbnail. Otherwise, the function
 278   * returns contents of a JPEG file with black background containing the thumbnail.
 279   *
 280   * @param string $filepath the full path to the original image file
 281   * @param int $width the width of the requested thumbnail
 282   * @param int $height the height of the requested thumbnail
 283   * @return string|bool false if a problem occurs, the thumbnail image data otherwise
 284   */
 285  function generate_image_thumbnail($filepath, $width, $height) {
 286      if (empty($filepath) or empty($width) or empty($height)) {
 287          return false;
 288      }
 289  
 290      // Fetch the image information for this image.
 291      $imageinfo = @getimagesize($filepath);
 292      if (empty($imageinfo)) {
 293          return false;
 294      }
 295  
 296      // Create a new image from the file.
 297      $original = @imagecreatefromstring(file_get_contents($filepath));
 298  
 299      // Generate the thumbnail.
 300      return generate_image_thumbnail_from_image($original, $imageinfo, $width, $height);
 301  }
 302  
 303  /**
 304   * Generates a thumbnail for the given image string.
 305   *
 306   * If the GD library has at least version 2 and PNG support is available, the returned data
 307   * is the content of a transparent PNG file containing the thumbnail. Otherwise, the function
 308   * returns contents of a JPEG file with black background containing the thumbnail.
 309   *
 310   * @param   string $filedata The image content as a string
 311   * @param   int $width the width of the requested thumbnail
 312   * @param   int $height the height of the requested thumbnail
 313   * @return  string|bool false if a problem occurs, the thumbnail image data otherwise
 314   */
 315  function generate_image_thumbnail_from_string($filedata, $width, $height) {
 316      if (empty($filedata) or empty($width) or empty($height)) {
 317          return false;
 318      }
 319  
 320      // Fetch the image information for this image.
 321      $imageinfo = @getimagesizefromstring($filedata);
 322      if (empty($imageinfo)) {
 323          return false;
 324      }
 325  
 326      // Create a new image from the file.
 327      $original = @imagecreatefromstring($filedata);
 328  
 329      // Generate the thumbnail.
 330      return generate_image_thumbnail_from_image($original, $imageinfo, $width, $height);
 331  }
 332  
 333  /**
 334   * Generates a thumbnail for the given image string.
 335   *
 336   * If the GD library has at least version 2 and PNG support is available, the returned data
 337   * is the content of a transparent PNG file containing the thumbnail. Otherwise, the function
 338   * returns contents of a JPEG file with black background containing the thumbnail.
 339   *
 340   * @param   string $original The image content as a string
 341   * @return  string|bool false if a problem occurs, the thumbnail image data otherwise
 342   */
 343  function generate_image_thumbnail_from_image($original, $imageinfo, $width, $height) {
 344      global $CFG;
 345  
 346      if (empty($imageinfo)) {
 347          return false;
 348      }
 349      $originalwidth  = $imageinfo[0];
 350      $originalheight = $imageinfo[1];
 351  
 352      if (empty($originalwidth) or empty($originalheight)) {
 353          return false;
 354      }
 355  
 356      if (function_exists('imagepng')) {
 357          $imagefnc = 'imagepng';
 358          $filters = PNG_NO_FILTER;
 359          $quality = 1;
 360      } else if (function_exists('imagejpeg')) {
 361          $imagefnc = 'imagejpeg';
 362          $filters = null;
 363          $quality = 90;
 364      } else {
 365          debugging('Neither JPEG nor PNG are supported at this server, please fix the system configuration.');
 366          return false;
 367      }
 368  
 369      if (function_exists('imagecreatetruecolor')) {
 370          $thumbnail = imagecreatetruecolor($width, $height);
 371          if ($imagefnc === 'imagepng') {
 372              imagealphablending($thumbnail, false);
 373              imagefill($thumbnail, 0, 0, imagecolorallocatealpha($thumbnail, 0, 0, 0, 127));
 374              imagesavealpha($thumbnail, true);
 375          }
 376      } else {
 377          $thumbnail = imagecreate($width, $height);
 378      }
 379  
 380      $ratio = min($width / $originalwidth, $height / $originalheight);
 381  
 382      if ($ratio < 1) {
 383          $targetwidth    = floor($originalwidth * $ratio);
 384          $targetheight   = floor($originalheight * $ratio);
 385      } else {
 386          // Do not enlarge the original file if it is smaller than the requested thumbnail size.
 387          $targetwidth    = $originalwidth;
 388          $targetheight   = $originalheight;
 389      }
 390  
 391      $dstx = floor(($width - $targetwidth) / 2);
 392      $dsty = floor(($height - $targetheight) / 2);
 393  
 394      imagecopybicubic($thumbnail, $original, $dstx, $dsty, 0, 0, $targetwidth, $targetheight, $originalwidth, $originalheight);
 395  
 396      // Capture the image as a string object, rather than straight to file.
 397      ob_start();
 398      if (!$imagefnc($thumbnail, null, $quality, $filters)) {
 399          ob_end_clean();
 400          return false;
 401      }
 402      $data = ob_get_clean();
 403      imagedestroy($original);
 404      imagedestroy($thumbnail);
 405  
 406      return $data;
 407  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1