Merge branch 'MDL-29542_m21' of git://github.com/rwijaya/moodle into MOODLE_21_STABLE
[moodle.git] / lib / gdlib.php
blob3b026b79d785a62c23da9ac6d9d3c64cb6956689
1 <?php
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.
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/>.
18 /**
19 * gdlib.php - Collection of routines in Moodle related to
20 * processing images using GD
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
27 defined('MOODLE_INTERNAL') || die();
29 /**
31 * long description
32 * @global object
33 * @param object $dst_img
34 * @param object $src_img
35 * @param int $dst_x
36 * @param int $dst_y
37 * @param int $src_x
38 * @param int $src_y
39 * @param int $dst_w
40 * @param int $dst_h
41 * @param int $src_w
42 * @param int $src_h
43 * @return bool
44 * @todo Finish documenting this function
46 function ImageCopyBicubic($dst_img, $src_img, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) {
48 global $CFG;
50 if (function_exists('ImageCopyResampled') and $CFG->gdversion >= 2) {
51 return ImageCopyResampled($dst_img, $src_img, $dst_x, $dst_y, $src_x, $src_y,
52 $dst_w, $dst_h, $src_w, $src_h);
55 $totalcolors = imagecolorstotal($src_img);
56 for ($i=0; $i<$totalcolors; $i++) {
57 if ($colors = ImageColorsForIndex($src_img, $i)) {
58 ImageColorAllocate($dst_img, $colors['red'], $colors['green'], $colors['blue']);
62 $scaleX = ($src_w - 1) / $dst_w;
63 $scaleY = ($src_h - 1) / $dst_h;
65 $scaleX2 = $scaleX / 2.0;
66 $scaleY2 = $scaleY / 2.0;
68 for ($j = 0; $j < $dst_h; $j++) {
69 $sY = $j * $scaleY;
71 for ($i = 0; $i < $dst_w; $i++) {
72 $sX = $i * $scaleX;
74 $c1 = ImageColorsForIndex($src_img,ImageColorAt($src_img,(int)$sX,(int)$sY+$scaleY2));
75 $c2 = ImageColorsForIndex($src_img,ImageColorAt($src_img,(int)$sX,(int)$sY));
76 $c3 = ImageColorsForIndex($src_img,ImageColorAt($src_img,(int)$sX+$scaleX2,(int)$sY+$scaleY2));
77 $c4 = ImageColorsForIndex($src_img,ImageColorAt($src_img,(int)$sX+$scaleX2,(int)$sY));
79 $red = (int) (($c1['red'] + $c2['red'] + $c3['red'] + $c4['red']) / 4);
80 $green = (int) (($c1['green'] + $c2['green'] + $c3['green'] + $c4['green']) / 4);
81 $blue = (int) (($c1['blue'] + $c2['blue'] + $c3['blue'] + $c4['blue']) / 4);
83 $color = ImageColorClosest ($dst_img, $red, $green, $blue);
84 ImageSetPixel ($dst_img, $i + $dst_x, $j + $dst_y, $color);
89 /**
90 * Stores optimised icon images in icon file area
92 * @param $context
93 * @param component
94 * @param $itemid
95 * @param $originalfile
96 * @return success
98 function process_new_icon($context, $component, $filearea, $itemid, $originalfile) {
99 global $CFG;
101 if (empty($CFG->gdversion)) {
102 return false;
105 if (!is_file($originalfile)) {
106 return false;
109 $imageinfo = GetImageSize($originalfile);
111 if (empty($imageinfo)) {
112 return false;
115 $image = new stdClass();
116 $image->width = $imageinfo[0];
117 $image->height = $imageinfo[1];
118 $image->type = $imageinfo[2];
120 switch ($image->type) {
121 case IMAGETYPE_GIF:
122 if (function_exists('ImageCreateFromGIF')) {
123 $im = ImageCreateFromGIF($originalfile);
124 } else {
125 debugging('GIF not supported on this server');
126 return false;
128 break;
129 case IMAGETYPE_JPEG:
130 if (function_exists('ImageCreateFromJPEG')) {
131 $im = ImageCreateFromJPEG($originalfile);
132 } else {
133 debugging('JPEG not supported on this server');
134 return false;
136 break;
137 case IMAGETYPE_PNG:
138 if (function_exists('ImageCreateFromPNG')) {
139 $im = ImageCreateFromPNG($originalfile);
140 } else {
141 debugging('PNG not supported on this server');
142 return false;
144 break;
145 default:
146 return false;
149 if (function_exists('ImagePng')) {
150 $imagefnc = 'ImagePng';
151 $imageext = '.png';
152 $filters = PNG_NO_FILTER;
153 $quality = 1;
154 } else if (function_exists('ImageJpeg')) {
155 $imagefnc = 'ImageJpeg';
156 $imageext = '.jpg';
157 $filters = null; // not used
158 $quality = 90;
159 } else {
160 debugging('Jpeg and png not supported on this server, please fix server configuration');
161 return false;
164 if (function_exists('ImageCreateTrueColor') and $CFG->gdversion >= 2) {
165 $im1 = ImageCreateTrueColor(100,100);
166 $im2 = ImageCreateTrueColor(35,35);
167 if ($image->type == IMAGETYPE_PNG and $imagefnc === 'ImagePng') {
168 imagealphablending($im1, false);
169 $color = imagecolorallocatealpha($im1, 0, 0, 0, 127);
170 imagefill($im1, 0, 0, $color);
171 imagesavealpha($im1, true);
172 imagealphablending($im2, false);
173 $color = imagecolorallocatealpha($im2, 0, 0, 0, 127);
174 imagefill($im2, 0, 0, $color);
175 imagesavealpha($im2, true);
177 } else {
178 $im1 = ImageCreate(100,100);
179 $im2 = ImageCreate(35,35);
182 $cx = $image->width / 2;
183 $cy = $image->height / 2;
185 if ($image->width < $image->height) {
186 $half = floor($image->width / 2.0);
187 } else {
188 $half = floor($image->height / 2.0);
191 ImageCopyBicubic($im1, $im, 0, 0, $cx-$half, $cy-$half, 100, 100, $half*2, $half*2);
192 ImageCopyBicubic($im2, $im, 0, 0, $cx-$half, $cy-$half, 35, 35, $half*2, $half*2);
194 $fs = get_file_storage();
196 $icon = array('contextid'=>$context->id, 'component'=>$component, 'filearea'=>$filearea, 'itemid'=>$itemid, 'filepath'=>'/');
198 ob_start();
199 if (!$imagefnc($im1, NULL, $quality, $filters)) {
200 // keep old icons
201 ob_end_clean();
202 return false;
204 $data = ob_get_clean();
205 ImageDestroy($im1);
206 $icon['filename'] = 'f1'.$imageext;
207 $fs->delete_area_files($context->id, $component, $filearea, $itemid);
208 $fs->create_file_from_string($icon, $data);
210 ob_start();
211 if (!$imagefnc($im2, NULL, $quality, $filters)) {
212 ob_end_clean();
213 $fs->delete_area_files($context->id, $component, $filearea, $itemid);
214 return false;
216 $data = ob_get_clean();
217 ImageDestroy($im2);
218 $icon['filename'] = 'f2'.$imageext;
219 $fs->create_file_from_string($icon, $data);
221 return true;