dolibarr 23.0.3
images.lib.php
Go to the documentation of this file.
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 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
5 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 * or see https://www.gnu.org/
20 */
21
27// Define size of logo small and mini
28// TODO Remove this and call getDefaultImageSizes() instead
29$maxwidthsmall = 480;
30$maxheightsmall = 270; // Near 16/9eme
31$maxwidthmini = 128;
32$maxheightmini = 72; // 16/9eme
33$quality = 80;
34
35if (!defined('IMAGETYPE_WEBP')) {
36 define('IMAGETYPE_WEBP', 18);
37}
38
39
46{
47 $maxwidthsmall = 480;
48 $maxheightsmall = 270; // Near 16/9eme
49 $maxwidthmini = 128;
50 $maxheightmini = 72; // 16/9eme
51 $quality = 80;
52
53 return array(
54 'maxwidthsmall' => $maxwidthsmall,
55 'maxheightsmall' => $maxheightsmall,
56 'maxwidthmini' => $maxwidthmini,
57 'maxheightmini' => $maxheightmini,
58 'quality' => $quality
59 );
60}
61
68function getListOfPossibleImageExt($acceptsvg = 0)
69{
70 $regeximgext = '\.gif|\.jpg|\.jpeg|\.png|\.bmp|\.webp|\.xpm|\.xbm'; // See also into product.class.php
71 if ($acceptsvg || getDolGlobalString('MAIN_ALLOW_SVG_FILES_AS_IMAGES')) {
72 $regeximgext .= '|\.svg'; // Not allowed by default. SVG can contains javascript
73 }
74
75 return $regeximgext;
76}
77
85function image_format_supported($file, $acceptsvg = 0)
86{
87 $regeximgext = getListOfPossibleImageExt();
88
89 // Case filename is not a format image
90 $reg = array();
91 if (!preg_match('/('.$regeximgext.')$/i', $file, $reg)) {
92 return -1;
93 }
94
95 // Case filename is a format image but not supported by this PHP
96 $imgfonction = '';
97 if (strtolower($reg[1]) == '.gif') {
98 $imgfonction = 'imagecreatefromgif';
99 }
100 if (strtolower($reg[1]) == '.jpg') {
101 $imgfonction = 'imagecreatefromjpeg';
102 }
103 if (strtolower($reg[1]) == '.jpeg') {
104 $imgfonction = 'imagecreatefromjpeg';
105 }
106 if (strtolower($reg[1]) == '.png') {
107 $imgfonction = 'imagecreatefrompng';
108 }
109 if (strtolower($reg[1]) == '.bmp') {
110 $imgfonction = 'imagecreatefromwbmp';
111 }
112 if (strtolower($reg[1]) == '.webp') {
113 $imgfonction = 'imagecreatefromwebp';
114 }
115 if (strtolower($reg[1]) == '.xpm') {
116 $imgfonction = 'imagecreatefromxpm';
117 }
118 if (strtolower($reg[1]) == '.xbm') {
119 $imgfonction = 'imagecreatefromxbm';
120 }
121 if (strtolower($reg[1]) == '.svg') {
122 $imgfonction = 'imagecreatefromsvg'; // Never available
123 }
124 if ($imgfonction) {
125 if (!function_exists($imgfonction)) {
126 // Functions of conversion not available in this PHP
127 return 0;
128 }
129
130 // Filename is a format image and supported for conversion by this PHP
131 return 1;
132 }
133
134 return 0;
135}
136
137
145function dol_getImageSize($file, $url = false)
146{
147 $ret = array();
148
149 if (image_format_supported($file) < 0) {
150 return $ret;
151 }
152
153 $filetoread = $file;
154 if (!$url) {
155 $filetoread = realpath(dol_osencode($file)); // Chemin canonique absolu de l'image
156 }
157
158 if ($filetoread) {
159 $infoImg = getimagesize($filetoread); // Recuperation des infos de l'image
160 if ($infoImg) {
161 $ret['width'] = $infoImg[0]; // Largeur de l'image
162 $ret['height'] = $infoImg[1]; // Hauteur de l'image
163 } else {
164 $ret['width'] = $ret['height'] = '';
165 }
166 }
167
168 return $ret;
169}
170
171
186function dol_imageResizeOrCrop($file, $mode, $newWidth, $newHeight, $src_x = 0, $src_y = 0, $filetowrite = '', $newquality = 0)
187{
188 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
189
190 global $langs;
191
192 dol_syslog("dol_imageResizeOrCrop file=".$file." mode=".$mode." newWidth=".$newWidth." newHeight=".$newHeight." src_x=".$src_x." src_y=".$src_y);
193
194 // Clean parameters
195 $file = trim($file);
196
197 // Check parameters
198 if (!$file) {
199 // Si le fichier n'a pas ete indique
200 return 'Bad parameter file';
201 } elseif (!file_exists($file)) {
202 // Si le fichier passe en parameter n'existe pas
203 return $langs->trans("ErrorFileNotFound", $file);
204 } elseif (image_format_supported($file) < 0) {
205 return 'This filename '.$file.' does not seem to be an image filename.';
206 } elseif (!is_numeric($newWidth) && !is_numeric($newHeight)) {
207 return 'Wrong value for parameter newWidth or newHeight';
208 } elseif ($mode == 0 && $newWidth <= 0 && $newHeight <= 0 && (empty($filetowrite) || $filetowrite == $file)) {
209 return 'At least newHeight or newWidth must be defined for resizing, or a target filename must be set to convert';
210 } elseif ($mode == 1 && ($newWidth <= 0 || $newHeight <= 0)) {
211 return 'Both newHeight or newWidth must be defined for croping';
212 }
213
214 $filetoread = realpath(dol_osencode($file)); // Chemin canonique absolu de l'image
215
216 $infoImg = getimagesize($filetoread); // Get data about src image
217 $imgWidth = $infoImg[0]; // Largeur de l'image
218 $imgHeight = $infoImg[1]; // Hauteur de l'image
219
220 $imgTargetName = ($filetowrite ? $filetowrite : $file);
221 $newExt = strtolower(pathinfo($imgTargetName, PATHINFO_EXTENSION));
222
223 if ($mode == 0) { // If resize, we check parameters
224 if (!empty($filetowrite) && $filetowrite != $file && $newWidth <= 0 && $newHeight <= 0) {
225 $newWidth = $imgWidth;
226 $newHeight = $imgHeight;
227 }
228
229 if ($newWidth <= 0) {
230 $newWidth = intval(($newHeight / $imgHeight) * $imgWidth); // Keep ratio
231 }
232 if ($newHeight <= 0) {
233 $newHeight = intval(($newWidth / $imgWidth) * $imgHeight); // Keep ratio
234 }
235 }
236
237 // Test function to read source image exists
238 $imgfonction = '';
239 switch ($infoImg[2]) {
240 case 1: // IMG_GIF
241 $imgfonction = 'imagecreatefromgif';
242 break;
243 case 2: // IMG_JPG
244 $imgfonction = 'imagecreatefromjpeg';
245 break;
246 case 3: // IMG_PNG
247 $imgfonction = 'imagecreatefrompng';
248 break;
249 case 4: // IMG_WBMP
250 $imgfonction = 'imagecreatefromwbmp';
251 break;
252 case 18: // IMG_WEBP
253 $imgfonction = 'imagecreatefromwebp';
254 break;
255 }
256 if ($imgfonction) {
257 if (!function_exists($imgfonction)) {
258 // Functions de conversion non presente dans ce PHP
259 return 'Read of image not possible. This PHP does not support GD functions '.$imgfonction;
260 }
261 }
262
263 // Test function to write target image exists
264 if ($filetowrite) {
265 $imgfonction = '';
266 switch ($newExt) {
267 case 'gif': // IMG_GIF
268 $imgfonction = 'imagecreatefromgif';
269 break;
270 case 'jpg': // IMG_JPG
271 case 'jpeg': // IMG_JPEG
272 $imgfonction = 'imagecreatefromjpeg';
273 break;
274 case 'png': // IMG_PNG
275 $imgfonction = 'imagecreatefrompng';
276 break;
277 case 'bmp': // IMG_WBMP
278 $imgfonction = 'imagecreatefromwbmp';
279 break;
280 case 'webp': // IMG_WEBP
281 $imgfonction = 'imagecreatefromwebp';
282 break;
283 }
284 if ($imgfonction) {
285 if (!function_exists($imgfonction)) {
286 // Functions de conversion non presente dans ce PHP
287 return 'Write of image not possible. This PHP does not support GD functions '.$imgfonction;
288 }
289 }
290 }
291
292 // Read source image file
293 $img = null;
294 $extImg = null;
295 switch ($infoImg[2]) {
296 case 1: // Gif
297 $img = imagecreatefromgif($filetoread);
298 $extImg = '.gif'; // File name extension of image
299 break;
300 case 2: // Jpg
301 $img = imagecreatefromjpeg($filetoread);
302 $extImg = '.jpg';
303 break;
304 case 3: // Png
305 $img = imagecreatefrompng($filetoread);
306 $extImg = '.png';
307 break;
308 case 4: // Bmp
309 $img = imagecreatefromwbmp($filetoread);
310 $extImg = '.bmp';
311 break;
312 case 18: // Webp
313 $img = imagecreatefromwebp($filetoread);
314 $extImg = '.webp';
315 break;
316 }
317
318 if ($img === null) {
319 return "Error: Could not create Image from '$filetoread'";
320 }
321
322 // Create empty image for target
323 if ($newExt == 'gif') {
324 // Compatibility image GIF
325 $imgTarget = imagecreate($newWidth, $newHeight);
326 } else {
327 $imgTarget = imagecreatetruecolor($newWidth, $newHeight);
328 }
329
330 // Activate antialiasing for better quality
331 if (function_exists('imageantialias')) {
332 imageantialias($imgTarget, true);
333 }
334
335 // This is to keep transparent alpha channel if exists (PHP >= 4.2)
336 if (function_exists('imagesavealpha')) {
337 imagesavealpha($imgTarget, true);
338 }
339
340 // Set transparent color according to image extension
341 $trans_colour = -1; // By default, undefined
342 switch ($newExt) {
343 case 'gif': // Gif
344 $trans_colour = imagecolorallocate($imgTarget, 255, 255, 255); // The method is different for the GIF format
345 imagecolortransparent($imgTarget, $trans_colour);
346 break;
347 case 'jpg': // Jpg
348 case 'jpeg': // Jpeg
349 $trans_colour = imagecolorallocatealpha($imgTarget, 255, 255, 255, 0);
350 break;
351 case 'png': // Png
352 imagealphablending($imgTarget, false); // For compatibility with certain systems
353 $trans_colour = imagecolorallocatealpha($imgTarget, 255, 255, 255, 127); // Keep transparent channel
354 break;
355 case 'bmp': // Bmp
356 $trans_colour = imagecolorallocatealpha($imgTarget, 255, 255, 255, 0);
357 break;
358 case 'webp': // Webp
359 $trans_colour = imagecolorallocatealpha($imgTarget, 255, 255, 255, 127);
360 break;
361 }
362 if (function_exists("imagefill") && $trans_colour > 0) {
363 imagefill($imgTarget, 0, 0, $trans_colour);
364 }
365
366 dol_syslog("dol_imageResizeOrCrop: convert image from ($imgWidth x $imgHeight) at position ($src_x x $src_y) to ($newWidth x $newHeight) as a $extImg");
367 //imagecopyresized($imgTarget, $img, 0, 0, 0, 0, $thumbWidth, $thumbHeight, $imgWidth, $imgHeight); // Insere l'image de base redimensionnee
368 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
369
370 // Check if permission are ok
371 //$fp = fopen($imgTargetName, "w");
372 //fclose($fp);
373
374 // Create image on disk (overwrite file if exists)
375 switch ($newExt) {
376 case 'gif': // Gif
377 $newquality = 'NU'; // Quality is not used for this format
378 imagegif($imgTarget, $imgTargetName);
379 break;
380 case 'jpg': // Jpg
381 case 'jpeg': // Jpeg
382 $newquality = ($newquality ? $newquality : '100'); // % quality maximum
383 imagejpeg($imgTarget, $imgTargetName, $newquality);
384 break;
385 case 'png': // Png
386 $newquality = 0; // No compression (0-9)
387 imagepng($imgTarget, $imgTargetName, $newquality);
388 break;
389 case 'bmp': // Bmp
390 $newquality = 'NU'; // Quality is not used for this format
391 imagewbmp($imgTarget, $imgTargetName);
392 break;
393 case 'webp': // Webp
394 $newquality = ($newquality ? $newquality : '100'); // % quality maximum
395 imagewebp($imgTarget, $imgTargetName, $newquality);
396 break;
397 default:
398 dol_syslog("images.lib.php::imageResizeOrCrop() Format ".$newExt." is not supported", LOG_WARNING);
399 }
400
401 // Set permissions on file
402 dolChmod($imgTargetName);
403
404 // Free memory. This does not delete image.
405 if ($img) {
406 imagedestroy($img);
407 }
408 if ($imgTarget) {
409 imagedestroy($imgTarget);
410 }
411
412 clearstatcache(); // File was replaced by a modified one, so we clear file caches.
413
414 return $imgTargetName;
415}
416
417
426function dolRotateImage($file_path)
427{
428 return correctExifImageOrientation($file_path, $file_path);
429}
430
431
440function correctExifImageOrientation($fileSource, $fileDest, $quality = 95)
441{
442 if (function_exists('exif_read_data')) {
443 $exif = @exif_read_data($fileSource);
444 if ($exif && isset($exif['Orientation'])) {
445 $infoImg = getimagesize($fileSource); // Get image infos
446
447 $orientation = $exif['Orientation'];
448 if ($orientation != 1) {
449 $img = imagecreatefromjpeg($fileSource);
450 $deg = 0;
451 switch ($orientation) {
452 case 3:
453 $deg = 180;
454 break;
455 case 6:
456 $deg = 270;
457 break;
458 case 8:
459 $deg = 90;
460 break;
461 }
462 if ($deg) {
463 if ($infoImg[2] === IMAGETYPE_PNG) { // In fact there is no exif on PNG but just in case
464 imagealphablending($img, false);
465 imagesavealpha($img, true);
466 $img = imagerotate($img, $deg, imagecolorallocatealpha($img, 0, 0, 0, 127));
467 imagealphablending($img, false);
468 imagesavealpha($img, true);
469 } else {
470 $img = imagerotate($img, $deg, 0);
471 }
472 }
473 // then rewrite the rotated image back to the disk as $fileDest
474 if ($fileDest === false) {
475 return $img;
476 } else {
477 // In fact there exif is only for JPG but just in case
478 // Create image on disk
479 $image = false;
480
481 switch ($infoImg[2]) {
482 case IMAGETYPE_GIF: // 1
483 $image = imagegif($img, $fileDest);
484 break;
485 case IMAGETYPE_JPEG: // 2
486 $image = imagejpeg($img, $fileDest, $quality);
487 break;
488 case IMAGETYPE_PNG: // 3
489 $image = imagepng($img, $fileDest, $quality);
490 break;
491 case IMAGETYPE_BMP: // 6
492 // Not supported by PHP GD
493 break;
494 case IMAGETYPE_WBMP: // 15
495 $image = imagewbmp($img, $fileDest);
496 break;
497 }
498
499 // Free up memory (imagedestroy does not delete files):
500 @imagedestroy($img);
501
502 return $image;
503 }
504 } // if there is some rotation necessary
505 } // if have the exif orientation info
506 } // if function exists
507
508 return false;
509}
510
525function vignette($file, $maxWidth = 160, $maxHeight = 120, $extName = '_small', $quality = 50, $outdir = 'thumbs', $targetformat = 0)
526{
527 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
528
529 global $langs;
530
531 dol_syslog("vignette file=".$file." extName=".$extName." maxWidth=".$maxWidth." maxHeight=".$maxHeight." quality=".$quality." outdir=".$outdir." targetformat=".$targetformat);
532
533 // Clean parameters
534 $file = dol_sanitizePathName(trim($file));
535
536 // Check parameters
537 if (!$file) {
538 // If the file has not been indicated
539 return 'ErrorBadParameters';
540 } elseif (image_format_supported($file) < 0) {
541 dol_syslog('This file '.$file.' does not seem to be a supported image file name (bad extension).', LOG_WARNING);
542 return 'ErrorBadImageFormat';
543 } elseif (!is_numeric($maxWidth) || empty($maxWidth) || $maxWidth < -1) {
544 // If max width is incorrect (not numeric, empty, or less than 0)
545 dol_syslog('Wrong value for parameter maxWidth', LOG_ERR);
546 return 'Error: Wrong value for parameter maxWidth';
547 } elseif (!is_numeric($maxHeight) || empty($maxHeight) || $maxHeight < -1) {
548 // If max height is incorrect (not numeric, empty, or less than 0)
549 dol_syslog('Wrong value for parameter maxHeight', LOG_ERR);
550 return 'Error: Wrong value for parameter maxHeight';
551 }
552
553 $filetoread = realpath(dol_osencode($file)); // Absolute canonical path of image
554
555 if (!file_exists($filetoread)) {
556 // If the file passed in parameter does not exist
557 dol_syslog($langs->trans("ErrorFileNotFound", $filetoread), LOG_ERR);
558 return $langs->trans("ErrorFileNotFound", $filetoread);
559 }
560
561 $infoImg = getimagesize($filetoread); // Get information like size and real format of image. Warning real format may be png when extension is .jpg
562 $imgWidth = $infoImg[0]; // Width of image
563 $imgHeight = $infoImg[1]; // Height of image
564
565 // TODO LDR
566 //if $infoImg[2] != extension of file $file, return a string 'Error: content of file has a format that differs of the format of its extension
567
568 $ort = false;
569 if (function_exists('exif_read_data')) {
570 $exif = @exif_read_data($filetoread);
571 if ($exif && !empty($exif['Orientation'])) {
572 $ort = $exif['Orientation'];
573 }
574 }
575
576 if ($maxWidth == -1) {
577 $maxWidth = $infoImg[0]; // If size is -1, we keep unchanged
578 }
579 if ($maxHeight == -1) {
580 $maxHeight = $infoImg[1]; // If size is -1, we keep unchanged
581 }
582
583 // If the image is smaller than the maximum width and height, no thumbnail is created.
584 if ($infoImg[0] < $maxWidth && $infoImg[1] < $maxHeight) {
585 // On cree toujours les vignettes
586 dol_syslog("File size is smaller than thumb size", LOG_DEBUG);
587 //return 'Le fichier '.$file.' ne necessite pas de creation de vignette';
588 }
589
590 $imgfonction = '';
591 switch ($infoImg[2]) {
592 case IMAGETYPE_GIF: // 1
593 $imgfonction = 'imagecreatefromgif';
594 break;
595 case IMAGETYPE_JPEG: // 2
596 $imgfonction = 'imagecreatefromjpeg';
597 break;
598 case IMAGETYPE_PNG: // 3
599 $imgfonction = 'imagecreatefrompng';
600 break;
601 case IMAGETYPE_BMP: // 6
602 // Not supported by PHP GD
603 break;
604 case IMAGETYPE_WBMP: // 15
605 $imgfonction = 'imagecreatefromwbmp';
606 break;
607 case IMAGETYPE_WEBP: // 18
608 $imgfonction = 'imagecreatefromwebp';
609 break;
610 }
611 if ($imgfonction) {
612 if (!function_exists($imgfonction)) {
613 // Conversion functions not present in this PHP
614 return 'Error: Creation of thumbs not possible. This PHP does not support GD function '.$imgfonction;
615 }
616 }
617
618 // We create the directory containing the thumbnails
619 $dirthumb = dirname($file).($outdir ? '/'.$outdir : ''); // Path to thumbnail folder
620 dol_mkdir($dirthumb);
621
622 // Variable initialization according to image extension
623 $img = null;
624 $extImg = null;
625 switch ($infoImg[2]) {
626 case IMAGETYPE_GIF: // 1
627 $img = imagecreatefromgif($filetoread);
628 $extImg = '.gif';
629 break;
630 case IMAGETYPE_JPEG: // 2
631 $img = imagecreatefromjpeg($filetoread);
632 $extImg = (preg_match('/\.jpeg$/', $file) ? '.jpeg' : '.jpg');
633 break;
634 case IMAGETYPE_PNG: // 3
635 $img = imagecreatefrompng($filetoread);
636 $extImg = '.png';
637 break;
638 case IMAGETYPE_BMP: // 6
639 // Not supported by PHP GD
640 $extImg = '.bmp';
641 break;
642 case IMAGETYPE_WBMP: // 15
643 $img = imagecreatefromwbmp($filetoread);
644 $extImg = '.bmp';
645 break;
646 case IMAGETYPE_WEBP: // 18
647 $img = imagecreatefromwebp($filetoread);
648 $extImg = '.webp';
649 break;
650 }
651
652 // Before PHP8, img was a resource, With PHP8, it is a GdImage
653 // if (!is_resource($img) && class_exists('GdImage') && !($img instanceof GdImage)) {
654 if (is_null($img) || $img === false) {
655 dol_syslog('Failed to detect type of image. We found infoImg[2]='.$infoImg[2], LOG_WARNING);
656 return 0;
657 }
658
659 $exifAngle = false;
660 if ($ort && getDolGlobalString('MAIN_USE_EXIF_ROTATION')) {
661 switch ($ort) {
662 case 3: // 180 rotate left
663 $exifAngle = 180;
664 break;
665 case 6: // 90 rotate right
666 $exifAngle = -90;
667 // changing sizes
668 $trueImgWidth = $infoImg[1];
669 $trueImgHeight = $infoImg[0];
670 break;
671 case 8: // 90 rotate left
672 $exifAngle = 90;
673 // changing sizes
674 $trueImgWidth = $infoImg[1]; // Largeur de l'image
675 $trueImgHeight = $infoImg[0]; // Hauteur de l'image
676 break;
677 }
678 }
679
680 if ($exifAngle) {
681 $rotated = false;
682
683 if ($infoImg[2] === IMAGETYPE_PNG) { // In fact there is no exif on PNG but just in case
684 imagealphablending($img, false);
685 imagesavealpha($img, true);
686 $rotated = imagerotate($img, $exifAngle, imagecolorallocatealpha($img, 0, 0, 0, 127));
687 imagealphablending($rotated, false);
688 imagesavealpha($rotated, true);
689 } else {
690 $rotated = imagerotate($img, $exifAngle, 0);
691 }
692
693 // replace image with good orientation
694 if (!empty($rotated) && isset($trueImgWidth) && isset($trueImgHeight)) {
695 $img = $rotated;
696 $imgWidth = $trueImgWidth;
697 $imgHeight = $trueImgHeight;
698 }
699 }
700
701 // Initialize thumbnail dimensions if larger than original
702 if ($maxWidth > $imgWidth) {
703 $maxWidth = $imgWidth;
704 }
705 if ($maxHeight > $imgHeight) {
706 $maxHeight = $imgHeight;
707 }
708
709 $whFact = $maxWidth / $maxHeight; // Width/height factor for maximum label dimensions
710 $imgWhFact = $imgWidth / $imgHeight; // Original width/height factor
711
712 // Set label dimensions
713 if ($whFact < $imgWhFact) {
714 // If determining width
715 $thumbWidth = $maxWidth;
716 $thumbHeight = $thumbWidth / $imgWhFact;
717 } else {
718 // If determining height
719 $thumbHeight = $maxHeight;
720 $thumbWidth = $thumbHeight * $imgWhFact;
721 }
722 $thumbHeight = (int) round($thumbHeight);
723 $thumbWidth = (int) round($thumbWidth);
724
725 // Define target format
726 if (empty($targetformat)) {
727 $targetformat = $infoImg[2];
728 }
729
730 // Create empty image
731 if ($targetformat == IMAGETYPE_GIF) {
732 // Compatibilite image GIF
733 $imgThumb = imagecreate($thumbWidth, $thumbHeight);
734 } else {
735 $imgThumb = imagecreatetruecolor($thumbWidth, $thumbHeight);
736 }
737
738 // Activate antialiasing for better quality
739 if (function_exists('imageantialias')) {
740 imageantialias($imgThumb, true);
741 }
742
743 // This is to keep transparent alpha channel if exists (PHP >= 4.2)
744 if (function_exists('imagesavealpha')) {
745 imagesavealpha($imgThumb, true);
746 }
747
748 // Variable initialization according to image extension
749 // $targetformat is 0 by default, in such case, we keep original extension
750 $extImgTarget = ''; // Default = same extension as original
751 $trans_colour = false;
752 $newquality = null;
753 switch ($targetformat) {
754 case IMAGETYPE_GIF: // 1
755 $trans_colour = imagecolorallocate($imgThumb, 255, 255, 255); // The GIF format works differently
756 imagecolortransparent($imgThumb, $trans_colour);
757 $extImgTarget = '.gif';
758 $newquality = 'NU';
759 break;
760 case IMAGETYPE_JPEG: // 2
761 $trans_colour = imagecolorallocatealpha($imgThumb, 255, 255, 255, 0);
762 $extImgTarget = (preg_match('/\.jpeg$/i', $file) ? '.jpeg' : '.jpg');
763 $newquality = $quality;
764 break;
765 case IMAGETYPE_PNG: // 3
766 imagealphablending($imgThumb, false); // For compatibility on certain systems
767 $trans_colour = imagecolorallocatealpha($imgThumb, 255, 255, 255, 127); // Keep transparent channel
768 $extImgTarget = '.png';
769 $newquality = round(abs($quality - 100) * 9 / 100);
770 break;
771 case IMAGETYPE_BMP: // 6
772 // Not supported by PHP GD
773 $extImgTarget = '.bmp';
774 $newquality = 'NU';
775 break;
776 case IMAGETYPE_WBMP: // 15
777 $trans_colour = imagecolorallocatealpha($imgThumb, 255, 255, 255, 0);
778 $extImgTarget = '.bmp';
779 $newquality = 'NU';
780 break;
781 case IMAGETYPE_WEBP: // 18
782 $trans_colour = imagecolorallocatealpha($imgThumb, 255, 255, 255, 0);
783 $extImgTarget = '.webp';
784 $newquality = $quality;
785 break;
786 }
787 if (function_exists("imagefill") && $trans_colour !== false) {
788 imagefill($imgThumb, 0, 0, $trans_colour);
789 }
790
791 dol_syslog("vignette: convert image from ($imgWidth x $imgHeight) to ($thumbWidth x $thumbHeight) as $extImg, newquality=$newquality");
792 //imagecopyresized($imgThumb, $img, 0, 0, 0, 0, $thumbWidth, $thumbHeight, $imgWidth, $imgHeight); // Insert resized base image
793 imagecopyresampled($imgThumb, $img, 0, 0, 0, 0, $thumbWidth, $thumbHeight, $imgWidth, $imgHeight); // Insert resized base image
794
795 $fileName = preg_replace('/(\.gif|\.jpeg|\.jpg|\.png|\.bmp)$/i', '', $file); // We remove any extension box
796 $fileName = basename($fileName);
797 //$imgThumbName = $dirthumb.'/'.getImageFileNameForSize(basename($file), $extName, $extImgTarget); // Full path of thumb file
798 $imgThumbName = getImageFileNameForSize($file, $extName, $extImgTarget); // Full path of thumb file
799
800
801 // Check if permission are ok
802 //$fp = fopen($imgThumbName, "w");
803 //fclose($fp);
804
805 // Create image on disk
806 switch ($targetformat) {
807 case IMAGETYPE_GIF: // 1
808 imagegif($imgThumb, $imgThumbName);
809 break;
810 case IMAGETYPE_JPEG: // 2
811 imagejpeg($imgThumb, $imgThumbName, $newquality); // @phan-suppress-current-line PhanTypeMismatchArgumentNullableInternal,PhanPossiblyUndeclaredVariable
812 break;
813 case IMAGETYPE_PNG: // 3
814 imagepng($imgThumb, $imgThumbName, !is_numeric($newquality) ? -1 : (int) $newquality); // @phan-suppress-current-line PhanPossiblyUndeclaredVariable
815 break;
816 case IMAGETYPE_BMP: // 6
817 // Not supported by PHP GD
818 break;
819 case IMAGETYPE_WBMP: // 15
820 imagewbmp($imgThumb, $imgThumbName);
821 break;
822 case IMAGETYPE_WEBP: // 18
823 imagewebp($imgThumb, $imgThumbName, $newquality); // @phan-suppress-current-line PhanTypeMismatchArgumentNullableInternal,PhanPossiblyUndeclaredVariable
824 break;
825 }
826
827 // Set permissions on file
828 dolChmod($imgThumbName);
829
830 // Free memory. This does not delete image.
831 imagedestroy($img);
832 imagedestroy($imgThumb);
833
834 return $imgThumbName;
835}
836
837
846function imgAddEditDeleteButton($htmlid, $urledit, $urldelete)
847{
848 // TODO
849 return '';
850}
dol_osencode($str)
Return a string encoded into OS filesystem encoding.
dol_sanitizePathName($str, $newstr='_', $unaccent=0, $allowdash=0)
Clean a string to use it as a path name.
dolChmod($filepath, $newmask='')
Change mod of a file.
getImageFileNameForSize($file, $extName, $extImgTarget='')
Return the filename of file to get the thumbs.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
vignette($file, $maxWidth=160, $maxHeight=120, $extName='_small', $quality=50, $outdir='thumbs', $targetformat=0)
Create a thumbnail from an image file (Supported extensions are gif, jpg, png and bmp).
getListOfPossibleImageExt($acceptsvg=0)
Return if a filename is file name of a supported image format.
if(!defined( 'IMAGETYPE_WEBP')) getDefaultImageSizes()
Return default values for image sizes.
correctExifImageOrientation($fileSource, $fileDest, $quality=95)
Add exif orientation correction for image.
dolRotateImage($file_path)
dolRotateImage if image is a jpg file.
dol_imageResizeOrCrop($file, $mode, $newWidth, $newHeight, $src_x=0, $src_y=0, $filetowrite='', $newquality=0)
Resize or crop an image file (Supported extensions are gif, jpg, png, bmp and webp)
dol_getImageSize($file, $url=false)
Return size of image file on disk (Supported extensions are gif, jpg, png, bmp and webp)
imgAddEditDeleteButton($htmlid, $urledit, $urldelete)
Beautify an image by adding a link edit and delete on image.
image_format_supported($file, $acceptsvg=0)
Return if a filename is file name of a supported image format.