1<?php 2/* Copyright (C) 2004-2010 Laurent Destailleur <eldy@users.sourceforge.net> 3 * Copyright (C) 2005-2007 Regis Houssin <regis.houssin@inodbox.com> 4 * 5 * This program 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 * This program 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 this program. If not, see <https://www.gnu.org/licenses/>. 17 * or see https://www.gnu.org/ 18 */ 19 20/** 21 * \file htdocs/core/lib/images.lib.php 22 * \brief Set of function for manipulating images 23 */ 24 25// Define size of logo small and mini 26$maxwidthsmall = 480; 27$maxheightsmall = 270; // Near 16/9eme 28$maxwidthmini = 128; 29$maxheightmini = 72; // 16/9eme 30$quality = 80; 31 32 33/** 34 * Return if a filename is file name of a supported image format 35 * 36 * @param int $acceptsvg 0=Default (depends on setup), 1=Always accept SVG as image files 37 * @return string Return list fo image format 38 */ 39function getListOfPossibleImageExt($acceptsvg = 0) 40{ 41 global $conf; 42 43 $regeximgext = '\.gif|\.jpg|\.jpeg|\.png|\.bmp|\.webp|\.xpm|\.xbm'; // See also into product.class.php 44 if ($acceptsvg || !empty($conf->global->MAIN_ALLOW_SVG_FILES_AS_IMAGES)) { 45 $regeximgext .= '|\.svg'; // Not allowed by default. SVG can contains javascript 46 } 47 48 return $regeximgext; 49} 50 51/** 52 * Return if a filename is file name of a supported image format 53 * 54 * @param string $file Filename 55 * @param int $acceptsvg 0=Default (depends on setup), 1=Always accept SVG as image files 56 * @return int -1=Not image filename, 0=Image filename but format not supported for conversion by PHP, 1=Image filename with format supported by this PHP 57 */ 58function image_format_supported($file, $acceptsvg = 0) 59{ 60 $regeximgext = getListOfPossibleImageExt(); 61 62 // Case filename is not a format image 63 $reg = array(); 64 if (!preg_match('/('.$regeximgext.')$/i', $file, $reg)) { 65 return -1; 66 } 67 68 // Case filename is a format image but not supported by this PHP 69 $imgfonction = ''; 70 if (strtolower($reg[1]) == '.gif') { 71 $imgfonction = 'imagecreatefromgif'; 72 } 73 if (strtolower($reg[1]) == '.jpg') { 74 $imgfonction = 'imagecreatefromjpeg'; 75 } 76 if (strtolower($reg[1]) == '.jpeg') { 77 $imgfonction = 'imagecreatefromjpeg'; 78 } 79 if (strtolower($reg[1]) == '.png') { 80 $imgfonction = 'imagecreatefrompng'; 81 } 82 if (strtolower($reg[1]) == '.bmp') { 83 $imgfonction = 'imagecreatefromwbmp'; 84 } 85 if (strtolower($reg[1]) == '.webp') { 86 $imgfonction = 'imagecreatefromwebp'; 87 } 88 if (strtolower($reg[1]) == '.xpm') { 89 $imgfonction = 'imagecreatefromxpm'; 90 } 91 if (strtolower($reg[1]) == '.xbm') { 92 $imgfonction = 'imagecreatefromxbm'; 93 } 94 if (strtolower($reg[1]) == '.svg') { 95 $imgfonction = 'imagecreatefromsvg'; // Never available 96 } 97 if ($imgfonction) { 98 if (!function_exists($imgfonction)) { 99 // Fonctions of conversion not available in this PHP 100 return 0; 101 } 102 103 // Filename is a format image and supported for conversion by this PHP 104 return 1; 105 } 106 107 return 0; 108} 109 110 111/** 112 * Return size of image file on disk (Supported extensions are gif, jpg, png, bmp and webp) 113 * 114 * @param string $file Full path name of file 115 * @param bool $url Image with url (true or false) 116 * @return array array('width'=>width, 'height'=>height) 117 */ 118function dol_getImageSize($file, $url = false) 119{ 120 $ret = array(); 121 122 if (image_format_supported($file) < 0) { 123 return $ret; 124 } 125 126 $filetoread = $file; 127 if (!$url) { 128 $filetoread = realpath(dol_osencode($file)); // Chemin canonique absolu de l'image 129 } 130 131 if ($filetoread) { 132 $infoImg = getimagesize($filetoread); // Recuperation des infos de l'image 133 $ret['width'] = $infoImg[0]; // Largeur de l'image 134 $ret['height'] = $infoImg[1]; // Hauteur de l'image 135 } 136 137 return $ret; 138} 139 140 141/** 142 * Resize or crop an image file (Supported extensions are gif, jpg, png, bmp and webp) 143 * 144 * @param string $file Path of source file to resize/crop 145 * @param int $mode 0=Resize, 1=Crop 146 * @param int $newWidth Largeur maximum que dois faire l'image destination (0=keep ratio) 147 * @param int $newHeight Hauteur maximum que dois faire l'image destination (0=keep ratio) 148 * @param int $src_x Position of croping image in source image (not use if mode=0) 149 * @param int $src_y Position of croping image in source image (not use if mode=0) 150 * @param string $filetowrite Path of file to write (overwrite source file if not provided) 151 * @param int $newquality Value for the new quality of image, for supported format (use 0 for maximum/unchanged). 152 * @return string File name if OK, error message if KO 153 * @see dol_convert_file() 154 */ 155function dol_imageResizeOrCrop($file, $mode, $newWidth, $newHeight, $src_x = 0, $src_y = 0, $filetowrite = '', $newquality = 0) 156{ 157 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; 158 159 global $conf, $langs; 160 161 dol_syslog("dol_imageResizeOrCrop file=".$file." mode=".$mode." newWidth=".$newWidth." newHeight=".$newHeight." src_x=".$src_x." src_y=".$src_y); 162 163 // Clean parameters 164 $file = trim($file); 165 166 // Check parameters 167 if (!$file) { 168 // Si le fichier n'a pas ete indique 169 return 'Bad parameter file'; 170 } elseif (!file_exists($file)) { 171 // Si le fichier passe en parametre n'existe pas 172 return $langs->trans("ErrorFileNotFound", $file); 173 } elseif (image_format_supported($file) < 0) { 174 return 'This filename '.$file.' does not seem to be an image filename.'; 175 } elseif (!is_numeric($newWidth) && !is_numeric($newHeight)) { 176 return 'Wrong value for parameter newWidth or newHeight'; 177 } elseif ($mode == 0 && $newWidth <= 0 && $newHeight <= 0 && (empty($filetowrite) || $filetowrite == $file)) { 178 return 'At least newHeight or newWidth must be defined for resizing, or a target filename must be set to convert'; 179 } elseif ($mode == 1 && ($newWidth <= 0 || $newHeight <= 0)) { 180 return 'Both newHeight or newWidth must be defined for croping'; 181 } 182 183 $filetoread = realpath(dol_osencode($file)); // Chemin canonique absolu de l'image 184 185 $infoImg = getimagesize($filetoread); // Get data about src image 186 $imgWidth = $infoImg[0]; // Largeur de l'image 187 $imgHeight = $infoImg[1]; // Hauteur de l'image 188 189 $imgTargetName = ($filetowrite ? $filetowrite : $file); 190 $newExt = strtolower(pathinfo($imgTargetName, PATHINFO_EXTENSION)); 191 192 if ($mode == 0) { // If resize, we check parameters 193 if (!empty($filetowrite) && $filetowrite != $file && $newWidth <= 0 && $newHeight <= 0) { 194 $newWidth = $imgWidth; 195 $newHeight = $imgHeight; 196 } 197 198 if ($newWidth <= 0) { 199 $newWidth = intval(($newHeight / $imgHeight) * $imgWidth); // Keep ratio 200 } 201 if ($newHeight <= 0) { 202 $newHeight = intval(($newWidth / $imgWidth) * $imgHeight); // Keep ratio 203 } 204 } 205 206 // Test function to read source image exists 207 $imgfonction = ''; 208 switch ($infoImg[2]) { 209 case 1: // IMG_GIF 210 $imgfonction = 'imagecreatefromgif'; 211 break; 212 case 2: // IMG_JPG 213 $imgfonction = 'imagecreatefromjpeg'; 214 break; 215 case 3: // IMG_PNG 216 $imgfonction = 'imagecreatefrompng'; 217 break; 218 case 4: // IMG_WBMP 219 $imgfonction = 'imagecreatefromwbmp'; 220 break; 221 case 18: // IMG_WEBP 222 $imgfonction = 'imagecreatefromwebp'; 223 break; 224 } 225 if ($imgfonction) { 226 if (!function_exists($imgfonction)) { 227 // Fonctions de conversion non presente dans ce PHP 228 return 'Read of image not possible. This PHP does not support GD functions '.$imgfonction; 229 } 230 } 231 232 // Test function to write target image exists 233 if ($filetowrite) { 234 $imgfonction = ''; 235 switch ($newExt) { 236 case 'gif': // IMG_GIF 237 $imgfonction = 'imagecreatefromgif'; 238 break; 239 case 'jpg': // IMG_JPG 240 $imgfonction = 'imagecreatefromjpeg'; 241 break; 242 case 'png': // IMG_PNG 243 $imgfonction = 'imagecreatefrompng'; 244 break; 245 case 'bmp': // IMG_WBMP 246 $imgfonction = 'imagecreatefromwbmp'; 247 break; 248 case 'webp': // IMG_WEBP 249 $imgfonction = 'imagecreatefromwebp'; 250 break; 251 } 252 if ($imgfonction) { 253 if (!function_exists($imgfonction)) { 254 // Fonctions de conversion non presente dans ce PHP 255 return 'Write of image not possible. This PHP does not support GD functions '.$imgfonction; 256 } 257 } 258 } 259 260 // Read source image file 261 switch ($infoImg[2]) { 262 case 1: // Gif 263 $img = imagecreatefromgif($filetoread); 264 $extImg = '.gif'; // File name extension of image 265 break; 266 case 2: // Jpg 267 $img = imagecreatefromjpeg($filetoread); 268 $extImg = '.jpg'; 269 break; 270 case 3: // Png 271 $img = imagecreatefrompng($filetoread); 272 $extImg = '.png'; 273 break; 274 case 4: // Bmp 275 $img = imagecreatefromwbmp($filetoread); 276 $extImg = '.bmp'; 277 break; 278 case 18: // Webp 279 $img = imagecreatefromwebp($filetoread); 280 $extImg = '.webp'; 281 break; 282 } 283 284 // Create empty image for target 285 if ($newExt == 'gif') { 286 // Compatibility image GIF 287 $imgTarget = imagecreate($newWidth, $newHeight); 288 } else { 289 $imgTarget = imagecreatetruecolor($newWidth, $newHeight); 290 } 291 292 // Activate antialiasing for better quality 293 if (function_exists('imageantialias')) { 294 imageantialias($imgTarget, true); 295 } 296 297 // This is to keep transparent alpha channel if exists (PHP >= 4.2) 298 if (function_exists('imagesavealpha')) { 299 imagesavealpha($imgTarget, true); 300 } 301 302 // Set transparent color according to image extension 303 switch ($newExt) { 304 case 'gif': // Gif 305 $trans_colour = imagecolorallocate($imgTarget, 255, 255, 255); // On procede autrement pour le format GIF 306 imagecolortransparent($imgTarget, $trans_colour); 307 break; 308 case 'jpg': // Jpg 309 $trans_colour = imagecolorallocatealpha($imgTarget, 255, 255, 255, 0); 310 break; 311 case 'png': // Png 312 imagealphablending($imgTarget, false); // Pour compatibilite sur certain systeme 313 $trans_colour = imagecolorallocatealpha($imgTarget, 255, 255, 255, 127); // Keep transparent channel 314 break; 315 case 'bmp': // Bmp 316 $trans_colour = imagecolorallocatealpha($imgTarget, 255, 255, 255, 0); 317 break; 318 case 'webp': // Webp 319 $trans_colour = imagecolorallocatealpha($imgTarget, 255, 255, 255, 127); 320 break; 321 } 322 if (function_exists("imagefill")) { 323 imagefill($imgTarget, 0, 0, $trans_colour); 324 } 325 326 dol_syslog("dol_imageResizeOrCrop: convert image from ($imgWidth x $imgHeight) at position ($src_x x $src_y) to ($newWidth x $newHeight) as $extImg"); 327 //imagecopyresized($imgTarget, $img, 0, 0, 0, 0, $thumbWidth, $thumbHeight, $imgWidth, $imgHeight); // Insere l'image de base redimensionnee 328 imagecopyresampled($imgTarget, $img, 0, 0, $src_x, $src_y, $newWidth, $newHeight, ($mode == 0 ? $imgWidth : $newWidth), ($mode == 0 ? $imgHeight : $newHeight)); // Insere l'image de base redimensionnee 329 330 // Check if permission are ok 331 //$fp = fopen($imgTargetName, "w"); 332 //fclose($fp); 333 334 // Create image on disk (overwrite file if exists) 335 switch ($newExt) { 336 case 'gif': // Gif 337 $newquality = 'NU'; // Quality is not used for this format 338 imagegif($imgTarget, $imgTargetName); 339 break; 340 case 'jpg': // Jpg 341 $newquality = ($newquality ? $newquality : '100'); // % quality maximum 342 imagejpeg($imgTarget, $imgTargetName, $newquality); 343 break; 344 case 'png': // Png 345 $newquality = 0; // No compression (0-9) 346 imagepng($imgTarget, $imgTargetName, $newquality); 347 break; 348 case 'bmp': // Bmp 349 $newquality = 'NU'; // Quality is not used for this format 350 imagewbmp($imgTarget, $imgTargetName); 351 break; 352 case 'webp': // Webp 353 $newquality = ($newquality ? $newquality : '100'); // % quality maximum 354 imagewebp($imgTarget, $imgTargetName, $newquality); 355 break; 356 } 357 358 // Set permissions on file 359 if (!empty($conf->global->MAIN_UMASK)) { 360 @chmod($imgTargetName, octdec($conf->global->MAIN_UMASK)); 361 } 362 363 // Free memory. This does not delete image. 364 imagedestroy($img); 365 imagedestroy($imgTarget); 366 367 clearstatcache(); // File was replaced by a modified one, so we clear file caches. 368 369 return $imgTargetName; 370} 371 372 373/** 374 * dolRotateImage if image is a jpg file. 375 * Currently use an autodetection to know if we can rotate. 376 * TODO Introduce a new parameter to force rotate. 377 * 378 * @param string $file_path Full path to image to rotate 379 * @return boolean Success or not 380 */ 381function dolRotateImage($file_path) 382{ 383 return correctExifImageOrientation($file_path, $file_path); 384} 385 386 387/** 388 * Add exif orientation correction for image 389 * 390 * @param string $fileSource Full path to source image to rotate 391 * @param string $fileDest string : Full path to image to rotate | false return gd img | null the raw image stream will be outputted directly 392 * @param int $quality output image quality 393 * @return bool : true on success or false on failure or gd img if $fileDest is false. 394 */ 395function correctExifImageOrientation($fileSource, $fileDest, $quality = 95) 396{ 397 if (function_exists('exif_read_data')) { 398 $exif = @exif_read_data($fileSource); 399 if ($exif && isset($exif['Orientation'])) { 400 $infoImg = getimagesize($fileSource); // Get image infos 401 402 $orientation = $exif['Orientation']; 403 if ($orientation != 1) { 404 $img = imagecreatefromjpeg($fileSource); 405 $deg = 0; 406 switch ($orientation) { 407 case 3: 408 $deg = 180; 409 break; 410 case 6: 411 $deg = 270; 412 break; 413 case 8: 414 $deg = 90; 415 break; 416 } 417 if ($deg) { 418 if ($infoImg[2] === 'IMAGETYPE_PNG') { // In fact there is no exif on PNG but just in case 419 imagealphablending($img, false); 420 imagesavealpha($img, true); 421 $img = imagerotate($img, $deg, imageColorAllocateAlpha($img, 0, 0, 0, 127)); 422 imagealphablending($img, false); 423 imagesavealpha($img, true); 424 } else { 425 $img = imagerotate($img, $deg, 0); 426 } 427 } 428 // then rewrite the rotated image back to the disk as $fileDest 429 if ($fileDest === false) { 430 return $img; 431 } else { 432 // In fact there exif is only for JPG but just in case 433 // Create image on disk 434 $image = false; 435 436 switch ($infoImg[2]) { 437 case IMAGETYPE_GIF: // 1 438 $image = imagegif($img, $fileDest); 439 break; 440 case IMAGETYPE_JPEG: // 2 441 $image = imagejpeg($img, $fileDest, $quality); 442 break; 443 case IMAGETYPE_PNG: // 3 444 $image = imagepng($img, $fileDest, $quality); 445 break; 446 case IMAGETYPE_BMP: // 6 447 // Not supported by PHP GD 448 break; 449 case IMAGETYPE_WBMP: // 15 450 $image = imagewbmp($img, $fileDest); 451 break; 452 } 453 454 // Free up memory (imagedestroy does not delete files): 455 @imagedestroy($img); 456 457 return $image; 458 } 459 } // if there is some rotation necessary 460 } // if have the exif orientation info 461 } // if function exists 462 463 return false; 464} 465 466/** 467 * Create a thumbnail from an image file (Supported extensions are gif, jpg, png and bmp). 468 * If file is myfile.jpg, new file may be myfile_small.jpg 469 * 470 * @param string $file Path of source file to resize 471 * @param int $maxWidth Largeur maximum que dois faire la miniature (-1=unchanged, 160 by default) 472 * @param int $maxHeight Hauteur maximum que dois faire l'image (-1=unchanged, 120 by default) 473 * @param string $extName Extension to differenciate thumb file name ('_small', '_mini') 474 * @param int $quality Quality of compression (0=worst, 100=best) 475 * @param string $outdir Directory where to store thumb 476 * @param int $targetformat New format of target (IMAGETYPE_GIF, IMAGETYPE_JPG, IMAGETYPE_PNG, IMAGETYPE_BMP, IMAGETYPE_WBMP ... or 0 to keep old format) 477 * @return string Full path of thumb or '' if it fails or 'Error...' if it fails 478 */ 479function vignette($file, $maxWidth = 160, $maxHeight = 120, $extName = '_small', $quality = 50, $outdir = 'thumbs', $targetformat = 0) 480{ 481 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; 482 483 global $conf, $langs; 484 485 dol_syslog("vignette file=".$file." extName=".$extName." maxWidth=".$maxWidth." maxHeight=".$maxHeight." quality=".$quality." outdir=".$outdir." targetformat=".$targetformat); 486 487 // Clean parameters 488 $file = trim($file); 489 490 // Check parameters 491 if (!$file) { 492 // Si le fichier n'a pas ete indique 493 return 'ErrorBadParameters'; 494 } elseif (!file_exists($file)) { 495 // Si le fichier passe en parametre n'existe pas 496 dol_syslog($langs->trans("ErrorFileNotFound", $file), LOG_ERR); 497 return $langs->trans("ErrorFileNotFound", $file); 498 } elseif (image_format_supported($file) < 0) { 499 dol_syslog('This file '.$file.' does not seem to be an image format file name.', LOG_WARNING); 500 return 'ErrorBadImageFormat'; 501 } elseif (!is_numeric($maxWidth) || empty($maxWidth) || $maxWidth < -1) { 502 // Si la largeur max est incorrecte (n'est pas numerique, est vide, ou est inferieure a 0) 503 dol_syslog('Wrong value for parameter maxWidth', LOG_ERR); 504 return 'Error: Wrong value for parameter maxWidth'; 505 } elseif (!is_numeric($maxHeight) || empty($maxHeight) || $maxHeight < -1) { 506 // Si la hauteur max est incorrecte (n'est pas numerique, est vide, ou est inferieure a 0) 507 dol_syslog('Wrong value for parameter maxHeight', LOG_ERR); 508 return 'Error: Wrong value for parameter maxHeight'; 509 } 510 511 $filetoread = realpath(dol_osencode($file)); // Chemin canonique absolu de l'image 512 513 $infoImg = getimagesize($filetoread); // Recuperation des infos de l'image 514 $imgWidth = $infoImg[0]; // Largeur de l'image 515 $imgHeight = $infoImg[1]; // Hauteur de l'image 516 517 $ort = false; 518 if (function_exists('exif_read_data')) { 519 $exif = @exif_read_data($filetoread); 520 if ($exif && !empty($exif['Orientation'])) { 521 $ort = $exif['Orientation']; 522 } 523 } 524 525 if ($maxWidth == -1) { 526 $maxWidth = $infoImg[0]; // If size is -1, we keep unchanged 527 } 528 if ($maxHeight == -1) { 529 $maxHeight = $infoImg[1]; // If size is -1, we keep unchanged 530 } 531 532 // Si l'image est plus petite que la largeur et la hauteur max, on ne cree pas de vignette 533 if ($infoImg[0] < $maxWidth && $infoImg[1] < $maxHeight) { 534 // On cree toujours les vignettes 535 dol_syslog("File size is smaller than thumb size", LOG_DEBUG); 536 //return 'Le fichier '.$file.' ne necessite pas de creation de vignette'; 537 } 538 539 $imgfonction = ''; 540 switch ($infoImg[2]) { 541 case IMAGETYPE_GIF: // 1 542 $imgfonction = 'imagecreatefromgif'; 543 break; 544 case IMAGETYPE_JPEG: // 2 545 $imgfonction = 'imagecreatefromjpeg'; 546 break; 547 case IMAGETYPE_PNG: // 3 548 $imgfonction = 'imagecreatefrompng'; 549 break; 550 case IMAGETYPE_BMP: // 6 551 // Not supported by PHP GD 552 break; 553 case IMAGETYPE_WBMP: // 15 554 $imgfonction = 'imagecreatefromwbmp'; 555 break; 556 } 557 if ($imgfonction) { 558 if (!function_exists($imgfonction)) { 559 // Fonctions de conversion non presente dans ce PHP 560 return 'Error: Creation of thumbs not possible. This PHP does not support GD function '.$imgfonction; 561 } 562 } 563 564 // On cree le repertoire contenant les vignettes 565 $dirthumb = dirname($file).($outdir ? '/'.$outdir : ''); // Chemin du dossier contenant les vignettes 566 dol_mkdir($dirthumb); 567 568 // Initialisation des variables selon l'extension de l'image 569 $img = null; 570 switch ($infoImg[2]) { 571 case IMAGETYPE_GIF: // 1 572 $img = imagecreatefromgif($filetoread); 573 $extImg = '.gif'; // Extension de l'image 574 break; 575 case IMAGETYPE_JPEG: // 2 576 $img = imagecreatefromjpeg($filetoread); 577 $extImg = (preg_match('/\.jpeg$/', $file) ? '.jpeg' : '.jpg'); // Extension de l'image 578 break; 579 case IMAGETYPE_PNG: // 3 580 $img = imagecreatefrompng($filetoread); 581 $extImg = '.png'; 582 break; 583 case IMAGETYPE_BMP: // 6 584 // Not supported by PHP GD 585 $extImg = '.bmp'; 586 break; 587 case IMAGETYPE_WBMP: // 15 588 $img = imagecreatefromwbmp($filetoread); 589 $extImg = '.bmp'; 590 break; 591 } 592 593 if (!is_resource($img) && !($img instanceof \GdImage)) { 594 dol_syslog('Failed to detect type of image. We found infoImg[2]='.$infoImg[2], LOG_WARNING); 595 return 0; 596 } 597 598 $exifAngle = false; 599 if ($ort && !empty($conf->global->MAIN_USE_EXIF_ROTATION)) { 600 switch ($ort) { 601 case 3: // 180 rotate left 602 $exifAngle = 180; 603 break; 604 case 6: // 90 rotate right 605 $exifAngle = -90; 606 // changing sizes 607 $trueImgWidth = $infoImg[1]; 608 $trueImgHeight = $infoImg[0]; 609 break; 610 case 8: // 90 rotate left 611 $exifAngle = 90; 612 // changing sizes 613 $trueImgWidth = $infoImg[1]; // Largeur de l'image 614 $trueImgHeight = $infoImg[0]; // Hauteur de l'image 615 break; 616 } 617 } 618 619 if ($exifAngle) { 620 $rotated = false; 621 622 if ($infoImg[2] === 'IMAGETYPE_PNG') { // In fact there is no exif on PNG but just in case 623 imagealphablending($img, false); 624 imagesavealpha($img, true); 625 $rotated = imagerotate($img, $exifAngle, imageColorAllocateAlpha($img, 0, 0, 0, 127)); 626 imagealphablending($rotated, false); 627 imagesavealpha($rotated, true); 628 } else { 629 $rotated = imagerotate($img, $exifAngle, 0); 630 } 631 632 // replace image with good orientation 633 if (!empty($rotated)) { 634 $img = $rotated; 635 $imgWidth = $trueImgWidth; 636 $imgHeight = $trueImgHeight; 637 } 638 } 639 640 // Initialisation des dimensions de la vignette si elles sont superieures a l'original 641 if ($maxWidth > $imgWidth) { 642 $maxWidth = $imgWidth; 643 } 644 if ($maxHeight > $imgHeight) { 645 $maxHeight = $imgHeight; 646 } 647 648 $whFact = $maxWidth / $maxHeight; // Facteur largeur/hauteur des dimensions max de la vignette 649 $imgWhFact = $imgWidth / $imgHeight; // Facteur largeur/hauteur de l'original 650 651 // Fixe les dimensions de la vignette 652 if ($whFact < $imgWhFact) { 653 // Si largeur determinante 654 $thumbWidth = $maxWidth; 655 $thumbHeight = $thumbWidth / $imgWhFact; 656 } else { 657 // Si hauteur determinante 658 $thumbHeight = $maxHeight; 659 $thumbWidth = $thumbHeight * $imgWhFact; 660 } 661 $thumbHeight = round($thumbHeight); 662 $thumbWidth = round($thumbWidth); 663 664 // Define target format 665 if (empty($targetformat)) { 666 $targetformat = $infoImg[2]; 667 } 668 669 // Create empty image 670 if ($targetformat == IMAGETYPE_GIF) { 671 // Compatibilite image GIF 672 $imgThumb = imagecreate($thumbWidth, $thumbHeight); 673 } else { 674 $imgThumb = imagecreatetruecolor($thumbWidth, $thumbHeight); 675 } 676 677 // Activate antialiasing for better quality 678 if (function_exists('imageantialias')) { 679 imageantialias($imgThumb, true); 680 } 681 682 // This is to keep transparent alpha channel if exists (PHP >= 4.2) 683 if (function_exists('imagesavealpha')) { 684 imagesavealpha($imgThumb, true); 685 } 686 687 // Initialisation des variables selon l'extension de l'image 688 // $targetformat is 0 by default, in such case, we keep original extension 689 switch ($targetformat) { 690 case IMAGETYPE_GIF: // 1 691 $trans_colour = imagecolorallocate($imgThumb, 255, 255, 255); // On procede autrement pour le format GIF 692 imagecolortransparent($imgThumb, $trans_colour); 693 $extImgTarget = '.gif'; 694 $newquality = 'NU'; 695 break; 696 case IMAGETYPE_JPEG: // 2 697 $trans_colour = imagecolorallocatealpha($imgThumb, 255, 255, 255, 0); 698 $extImgTarget = (preg_match('/\.jpeg$/i', $file) ? '.jpeg' : '.jpg'); 699 $newquality = $quality; 700 break; 701 case IMAGETYPE_PNG: // 3 702 imagealphablending($imgThumb, false); // Pour compatibilite sur certain systeme 703 $trans_colour = imagecolorallocatealpha($imgThumb, 255, 255, 255, 127); // Keep transparent channel 704 $extImgTarget = '.png'; 705 $newquality = $quality - 100; 706 $newquality = round(abs($quality - 100) * 9 / 100); 707 break; 708 case IMAGETYPE_BMP: // 6 709 // Not supported by PHP GD 710 $extImgTarget = '.bmp'; 711 $newquality = 'NU'; 712 break; 713 case IMAGETYPE_WBMP: // 15 714 $trans_colour = imagecolorallocatealpha($imgThumb, 255, 255, 255, 0); 715 $extImgTarget = '.bmp'; 716 $newquality = 'NU'; 717 break; 718 } 719 if (function_exists("imagefill")) { 720 imagefill($imgThumb, 0, 0, $trans_colour); 721 } 722 723 dol_syslog("vignette: convert image from ($imgWidth x $imgHeight) to ($thumbWidth x $thumbHeight) as $extImg, newquality=$newquality"); 724 //imagecopyresized($imgThumb, $img, 0, 0, 0, 0, $thumbWidth, $thumbHeight, $imgWidth, $imgHeight); // Insere l'image de base redimensionnee 725 imagecopyresampled($imgThumb, $img, 0, 0, 0, 0, $thumbWidth, $thumbHeight, $imgWidth, $imgHeight); // Insere l'image de base redimensionnee 726 727 $fileName = preg_replace('/(\.gif|\.jpeg|\.jpg|\.png|\.bmp)$/i', '', $file); // On enleve extension quelquesoit la casse 728 $fileName = basename($fileName); 729 //$imgThumbName = $dirthumb.'/'.getImageFileNameForSize(basename($file), $extName, $extImgTarget); // Full path of thumb file 730 $imgThumbName = getImageFileNameForSize($file, $extName, $extImgTarget); // Full path of thumb file 731 732 733 // Check if permission are ok 734 //$fp = fopen($imgThumbName, "w"); 735 //fclose($fp); 736 737 // Create image on disk 738 switch ($targetformat) { 739 case IMAGETYPE_GIF: // 1 740 imagegif($imgThumb, $imgThumbName); 741 break; 742 case IMAGETYPE_JPEG: // 2 743 imagejpeg($imgThumb, $imgThumbName, $newquality); 744 break; 745 case IMAGETYPE_PNG: // 3 746 imagepng($imgThumb, $imgThumbName, $newquality); 747 break; 748 case IMAGETYPE_BMP: // 6 749 // Not supported by PHP GD 750 break; 751 case IMAGETYPE_WBMP: // 15 752 imagewbmp($imgThumb, $imgThumbName); 753 break; 754 } 755 756 // Set permissions on file 757 if (!empty($conf->global->MAIN_UMASK)) { 758 @chmod($imgThumbName, octdec($conf->global->MAIN_UMASK)); 759 } 760 761 // Free memory. This does not delete image. 762 imagedestroy($img); 763 imagedestroy($imgThumb); 764 765 return $imgThumbName; 766} 767