[ Index ]

PHP Cross Reference of moodle-2.8

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   * @param context $context
  94   * @param string $component
  95   * @param string filearea
  96   * @param int $itemid
  97   * @param string $originalfile
  98   * @return mixed new unique revision number or false if not saved
  99   */
 100  function process_new_icon($context, $component, $filearea, $itemid, $originalfile) {
 101      global $CFG;
 102  
 103      if (!is_file($originalfile)) {
 104          return false;
 105      }
 106  
 107      $imageinfo = getimagesize($originalfile);
 108  
 109      if (empty($imageinfo)) {
 110          return false;
 111      }
 112  
 113      $image = new stdClass();
 114      $image->width  = $imageinfo[0];
 115      $image->height = $imageinfo[1];
 116      $image->type   = $imageinfo[2];
 117  
 118      $t = null;
 119      switch ($image->type) {
 120          case IMAGETYPE_GIF:
 121              if (function_exists('imagecreatefromgif')) {
 122                  $im = imagecreatefromgif($originalfile);
 123              } else {
 124                  debugging('GIF not supported on this server');
 125                  return false;
 126              }
 127              // Guess transparent colour from GIF.
 128              $transparent = imagecolortransparent($im);
 129              if ($transparent != -1) {
 130                  $t = imagecolorsforindex($im, $transparent);
 131              }
 132              break;
 133          case IMAGETYPE_JPEG:
 134              if (function_exists('imagecreatefromjpeg')) {
 135                  $im = imagecreatefromjpeg($originalfile);
 136              } else {
 137                  debugging('JPEG not supported on this server');
 138                  return false;
 139              }
 140              break;
 141          case IMAGETYPE_PNG:
 142              if (function_exists('imagecreatefrompng')) {
 143                  $im = imagecreatefrompng($originalfile);
 144              } else {
 145                  debugging('PNG not supported on this server');
 146                  return false;
 147              }
 148              break;
 149          default:
 150              return false;
 151      }
 152  
 153      if (function_exists('imagepng')) {
 154          $imagefnc = 'imagepng';
 155          $imageext = '.png';
 156          $filters = PNG_NO_FILTER;
 157          $quality = 1;
 158      } else if (function_exists('imagejpeg')) {
 159          $imagefnc = 'imagejpeg';
 160          $imageext = '.jpg';
 161          $filters = null; // not used
 162          $quality = 90;
 163      } else {
 164          debugging('Jpeg and png not supported on this server, please fix server configuration');
 165          return false;
 166      }
 167  
 168      if (function_exists('imagecreatetruecolor')) {
 169          $im1 = imagecreatetruecolor(100, 100);
 170          $im2 = imagecreatetruecolor(35, 35);
 171          $im3 = imagecreatetruecolor(512, 512);
 172          if ($image->type != IMAGETYPE_JPEG and $imagefnc === 'imagepng') {
 173              if ($t) {
 174                  // Transparent GIF hacking...
 175                  $transparentcolour = imagecolorallocate($im1 , $t['red'] , $t['green'] , $t['blue']);
 176                  imagecolortransparent($im1 , $transparentcolour);
 177                  $transparentcolour = imagecolorallocate($im2 , $t['red'] , $t['green'] , $t['blue']);
 178                  imagecolortransparent($im2 , $transparentcolour);
 179                  $transparentcolour = imagecolorallocate($im3 , $t['red'] , $t['green'] , $t['blue']);
 180                  imagecolortransparent($im3 , $transparentcolour);
 181              }
 182  
 183              imagealphablending($im1, false);
 184              $color = imagecolorallocatealpha($im1, 0, 0,  0, 127);
 185              imagefill($im1, 0, 0,  $color);
 186              imagesavealpha($im1, true);
 187  
 188              imagealphablending($im2, false);
 189              $color = imagecolorallocatealpha($im2, 0, 0,  0, 127);
 190              imagefill($im2, 0, 0,  $color);
 191              imagesavealpha($im2, true);
 192  
 193              imagealphablending($im3, false);
 194              $color = imagecolorallocatealpha($im3, 0, 0,  0, 127);
 195              imagefill($im3, 0, 0,  $color);
 196              imagesavealpha($im3, true);
 197          }
 198      } else {
 199          $im1 = imagecreate(100, 100);
 200          $im2 = imagecreate(35, 35);
 201          $im3 = imagecreate(512, 512);
 202      }
 203  
 204      $cx = $image->width / 2;
 205      $cy = $image->height / 2;
 206  
 207      if ($image->width < $image->height) {
 208          $half = floor($image->width / 2.0);
 209      } else {
 210          $half = floor($image->height / 2.0);
 211      }
 212  
 213      imagecopybicubic($im1, $im, 0, 0, $cx - $half, $cy - $half, 100, 100, $half * 2, $half * 2);
 214      imagecopybicubic($im2, $im, 0, 0, $cx - $half, $cy - $half, 35, 35, $half * 2, $half * 2);
 215      imagecopybicubic($im3, $im, 0, 0, $cx - $half, $cy - $half, 512, 512, $half * 2, $half * 2);
 216  
 217      $fs = get_file_storage();
 218  
 219      $icon = array('contextid'=>$context->id, 'component'=>$component, 'filearea'=>$filearea, 'itemid'=>$itemid, 'filepath'=>'/');
 220  
 221      ob_start();
 222      if (!$imagefnc($im1, NULL, $quality, $filters)) {
 223          // keep old icons
 224          ob_end_clean();
 225          return false;
 226      }
 227      $data = ob_get_clean();
 228      imagedestroy($im1);
 229      $icon['filename'] = 'f1'.$imageext;
 230      $fs->delete_area_files($context->id, $component, $filearea, $itemid);
 231      $file1 = $fs->create_file_from_string($icon, $data);
 232  
 233      ob_start();
 234      if (!$imagefnc($im2, NULL, $quality, $filters)) {
 235          ob_end_clean();
 236          $fs->delete_area_files($context->id, $component, $filearea, $itemid);
 237          return false;
 238      }
 239      $data = ob_get_clean();
 240      imagedestroy($im2);
 241      $icon['filename'] = 'f2'.$imageext;
 242      $fs->create_file_from_string($icon, $data);
 243  
 244      ob_start();
 245      if (!$imagefnc($im3, NULL, $quality, $filters)) {
 246          ob_end_clean();
 247          $fs->delete_area_files($context->id, $component, $filearea, $itemid);
 248          return false;
 249      }
 250      $data = ob_get_clean();
 251      imagedestroy($im3);
 252      $icon['filename'] = 'f3'.$imageext;
 253      $fs->create_file_from_string($icon, $data);
 254  
 255      return $file1->get_id();
 256  }
 257  
 258  /**
 259   * Generates a thumbnail for the given image
 260   *
 261   * If the GD library has at least version 2 and PNG support is available, the returned data
 262   * is the content of a transparent PNG file containing the thumbnail. Otherwise, the function
 263   * returns contents of a JPEG file with black background containing the thumbnail.
 264   *
 265   * @param string $filepath the full path to the original image file
 266   * @param int $width the width of the requested thumbnail
 267   * @param int $height the height of the requested thumbnail
 268   * @return string|bool false if a problem occurs, the thumbnail image data otherwise
 269   */
 270  function generate_image_thumbnail($filepath, $width, $height) {
 271      global $CFG;
 272  
 273      if (empty($filepath) or empty($width) or empty($height)) {
 274          return false;
 275      }
 276  
 277      $imageinfo = getimagesize($filepath);
 278  
 279      if (empty($imageinfo)) {
 280          return false;
 281      }
 282  
 283      $originalwidth = $imageinfo[0];
 284      $originalheight = $imageinfo[1];
 285  
 286      if (empty($originalwidth) or empty($originalheight)) {
 287          return false;
 288      }
 289  
 290      $original = imagecreatefromstring(file_get_contents($filepath));
 291  
 292      if (function_exists('imagepng')) {
 293          $imagefnc = 'imagepng';
 294          $filters = PNG_NO_FILTER;
 295          $quality = 1;
 296      } else if (function_exists('imagejpeg')) {
 297          $imagefnc = 'imagejpeg';
 298          $filters = null;
 299          $quality = 90;
 300      } else {
 301          debugging('Neither JPEG nor PNG are supported at this server, please fix the system configuration.');
 302          return false;
 303      }
 304  
 305      if (function_exists('imagecreatetruecolor')) {
 306          $thumbnail = imagecreatetruecolor($width, $height);
 307          if ($imagefnc === 'imagepng') {
 308              imagealphablending($thumbnail, false);
 309              imagefill($thumbnail, 0, 0, imagecolorallocatealpha($thumbnail, 0, 0, 0, 127));
 310              imagesavealpha($thumbnail, true);
 311          }
 312      } else {
 313          $thumbnail = imagecreate($width, $height);
 314      }
 315  
 316      $ratio = min($width / $originalwidth, $height / $originalheight);
 317  
 318      if ($ratio < 1) {
 319          $targetwidth = floor($originalwidth * $ratio);
 320          $targetheight = floor($originalheight * $ratio);
 321      } else {
 322          // do not enlarge the original file if it is smaller than the requested thumbnail size
 323          $targetwidth = $originalwidth;
 324          $targetheight = $originalheight;
 325      }
 326  
 327      $dstx = floor(($width - $targetwidth) / 2);
 328      $dsty = floor(($height - $targetheight) / 2);
 329  
 330      imagecopybicubic($thumbnail, $original, $dstx, $dsty, 0, 0, $targetwidth, $targetheight, $originalwidth, $originalheight);
 331  
 332      ob_start();
 333      if (!$imagefnc($thumbnail, null, $quality, $filters)) {
 334          ob_end_clean();
 335          return false;
 336      }
 337      $data = ob_get_clean();
 338      imagedestroy($original);
 339      imagedestroy($thumbnail);
 340  
 341      return $data;
 342  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1