images.lib.php 23 KB

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