2 # ========================================================================#
4 # This work is licensed under the Creative Commons Attribution 3.0 Unported
5 # License. To view a copy of this license,
6 # visit http://creativecommons.org/licenses/by/3.0/ or send a letter to
7 # Creative Commons, 444 Castro Street, Suite 900, Mountain View, California,
10 # All rights reserved.
12 # Author: Jarrod Oberto
15 # Purpose: Provide tools for image manipulation using GD
16 # Param In: See functions.
17 # Param Out: Produces a resized image
18 # Requires : Requires PHP GD library.
20 # include("lib/php_image_magician.php");
21 # $magicianObj = new resize('images/car.jpg');
22 # $magicianObj -> resizeImage(150, 100, 0);
23 # $magicianObj -> saveImage('images/car_small.jpg', 100);
25 # - See end of doc for more examples -
27 # Supported file types include: jpg, png, gif, bmp, psd (read)
31 # The following functions are taken from phpThumb() [available from
32 # http://phpthumb.sourceforge.net], and are used with written permission
33 # from James Heinrich.
36 # - LittleEndian2String
38 # The following functions are from Marc Hibbins and are used with written
39 # permission (are also under the Attribution-ShareAlike
40 # [http://creativecommons.org/licenses/by-sa/3.0/] license.
43 # PhpPsdReader is used with written permission from Tim de Koning.
44 # [http://www.kingsquare.nl/phppsdreader]
48 # Modificatoin history
49 # Date Initials Ver Description
50 # 10-05-11 J.C.O 0.0 Initial build
51 # 01-06-11 J.C.O 0.1.1 * Added reflections
52 # * Added Rounded corners
53 # * You can now use PNG interlacing
56 # * Added vintage filter
57 # * Added dynamic image resizing (resize on the fly)
59 # 05-06-11 J.C.O 0.1.1.1 * Fixed undefined variables
60 # 17-06-11 J.C.O 0.1.2 * Added image_batch_class.php class
62 # 26-07-11 J.C.O 0.1.4 * Added support for external images
63 # * Can now set the crop poisition
64 # 03-08-11 J.C.O 0.1.5 * Added reset() method to reset resource to
65 # original input file.
66 # * Added method addTextToCaptionBox() to
67 # simplify adding text to a caption box.
68 # * Added experimental writeIPTC. (not finished)
69 # * Added experimental readIPTC. (not finished)
70 # 11-08-11 J.C.O * Added initial border presets.
71 # 30-08-11 J.C.O * Added 'auto' crop option to crop portrait
72 # images near the top.
73 # 08-09-11 J.C.O * Added cropImage() method to allow standalone
75 # 17-09-11 J.C.O * Added setCropFromTop() set method - set the
76 # percentage to crop from the top when using
78 # * Added setTransparency() set method - allows you
79 # to turn transparency off (like when saving
81 # * Added setFillColor() set method - set the
82 # background color to use instead of transparency.
83 # 05-11-11 J.C.O 0.1.5.1 * Fixed interlacing option
86 # Known issues & Limitations:
87 # -------------------------------
88 # Not so much an issue, the image is destroyed on the deconstruct rather than
89 # when we have finished with it. The reason for this is that we don't know
90 # when we're finished with it as you can both save the image and display
91 # it directly to the screen (imagedestroy($this->imageResized))
93 # Opening BMP files is slow. A test with 884 bmp files processed in a loop
94 # takes forever - over 5 min. This test inlcuded opening the file, then
95 # getting and displaying its width and height.
98 # -------------------------------
100 # $forceStretch can be disabled by calling method setForceStretch with false
101 # parameter. If disabled, if an images original size is smaller than the size
102 # specified by the user, the original size will be used. This is useful when
103 # dealing with small images.
105 # If enabled, images smaller than the size specified will be stretched to
109 # -------------------------------
110 # * If you're resizing a transparent png and saving it as a jpg, set
111 # $keepTransparency to false with: $magicianObj->setTransparency(false);
115 # * BMP SUPPORT (read & write)
116 # * PSD (photoshop) support (read)
118 # - Preserve transparency (png, gif)
119 # - Apply sharpening (jpg) (requires PHP >= 5.1.0)
120 # - Set image quality (jpg, png)
123 # - resize by width (auto height)
124 # - resize by height (auto width)
125 # - auto (automatically determine the best of the above modes to use)
126 # - crop - resize as best as it can then crop the rest
127 # - Force stretching of smaller images (upscale)
129 # - Convert to grey scale
130 # - Convert to black and white
132 # - Convert to negative
134 # - Rotate using predefined "left", "right", or "180"; or any custom degree amount
135 # * EXTRACT EXIF DATA (requires exif module)
150 # - Specify exact x, y placement
151 # - Or, specify using one of the 9 pre-defined placements such as "tl"
152 # (for top left), "m" (for middle), "br" (for bottom right)
153 # - also specify padding from edge amount (optional).
154 # - Set opacity of watermark (png).
156 # * USE HEX WHEN SPECIFYING COLORS (eg: #ffffff)
157 # * SAVE IMAGE OR OUTPUT TO SCREEN
160 # ========================================================================#
171 private $width; # Current width (width after resize)
200 ## --------------------------------------------------------
203 # Author: Jarrod Oberto
205 # Purpose: Constructor
206 # Param in: $fileName: File name and path.
212 if (!$this->testGDInstalled()) {
if ($this->debug) {
throw new Exception(
'The GD Library is not installed.'); }
else{
throw new Exception(); }};
221 $this->image = $this->openImage(
$fileName);
228 if ($this->testIsImage($this->image))
231 $this->width = imagesx($this->image);
232 $this->widthOriginal = imagesx($this->image);
233 $this->height = imagesy($this->image);
234 $this->heightOriginal = imagesy($this->image);
246 $this->imageSize = getimagesize($this->fileName);
249 $this->errorArray[] =
'File is not an image';
253 ## --------------------------------------------------------
257 $this->psdReaderPath = __DIR__ .
'/classPhpPsdReader.php';
258 $this->filterOverlayPath = __DIR__ .
'/filters';
261 $this->isInterlace =
false;
271 public function resizeImage($newWidth, $newHeight, $option = 0, $sharpen =
false, $autoRotate =
false)
272 # Author: Jarrod Oberto
274 # Purpose: Resizes the image
275 # Param in: $newWidth:
277 # $option: 0 / exact = defined size;
278 # 1 / portrait = keep aspect set height;
279 # 2 / landscape = keep aspect set width;
281 # 4 / crop= resize and crop;
283 # $option can also be an array containing options for
284 # cropping. E.G., array('crop', 'r')
286 # This array only applies to 'crop' and the 'r' refers to
287 # "crop right". Other value include; tl, t, tr, l, m (default),
288 # r, bl, b, br, or you can specify your own co-ords (which
291 # $sharpen: true: sharpen (jpg only);
292 # false: don't sharpen
295 # Notes: To clarify the $option input:
296 # 0 = The exact height and width dimensions you set.
297 # 1 = Whatever height is passed in will be the height that
298 # is set. The width will be calculated and set automatically
299 # to a the value that keeps the original aspect ratio.
300 # 2 = The same but based on the width. We try make the image the
301 # biggest size we can while stil fitting inside the box size
302 # 3 = Depending whether the image is landscape or portrait, this
303 # will automatically determine whether to resize via
305 # 4 = Will resize and then crop the image for best fit
307 # forceStretch can be applied to options 1,2,3 and 4
315 }
else if (strpos($option,
'-') !==
false) {
317 $optionPiecesArray = explode(
'-', $option);
318 $cropPos = end($optionPiecesArray);
322 $option = $this->prepOption($option);
325 if (!$this->image) {
if ($this->debug) {
throw new Exception(
'file ' . $this->getFileName() .
' is missing or invalid'); }
else{
throw new Exception(); }};
328 $dimensionsArray = $this->
getDimensions($newWidth, $newHeight, $option);
330 $optimalWidth = $dimensionsArray[
'optimalWidth'];
331 $optimalHeight = $dimensionsArray[
'optimalHeight'];
334 $this->imageResized = imagecreatetruecolor($optimalWidth, $optimalHeight);
335 $this->
keepTransparancy($optimalWidth, $optimalHeight, $this->imageResized);
336 imagecopyresampled($this->imageResized, $this->image, 0, 0, 0, 0, $optimalWidth, $optimalHeight, $this->width, $this->height);
340 if ($option == 4 || $option ==
'crop') {
342 if (($optimalWidth >= $newWidth && $optimalHeight >= $newHeight)) {
343 $this->
crop($optimalWidth, $optimalHeight, $newWidth, $newHeight, $cropPos);
350 $exifData = $this->getExif(
false);
351 if (count($exifData) > 0) {
353 switch($exifData[
'orientation']) {
355 $this->imageResized = imagerotate($this->imageResized,90,0);
358 $this->imageResized = imagerotate($this->imageResized,180,0);
361 $this->imageResized = imagerotate($this->imageResized,-90,0);
368 if ($sharpen && in_array($this->fileExtension, $this->sharpenArray)) {
375 ## --------------------------------------------------------
377 public function cropImage($newWidth, $newHeight, $cropPos =
'm')
378 # Author: Jarrod Oberto
380 # Purpose: Crops the image
381 # Param in: $newWidth: crop with
382 # $newHeight: crop height
383 # $cropPos: Can be any of the following:
384 # tl, t, tr, l, m, r, bl, b, br, auto
386 # a custom position such as '30x50'
394 if (!$this->image) {
if ($this->debug) {
throw new Exception(
'file ' . $this->getFileName() .
' is missing or invalid'); }
else{
throw new Exception(); }};
397 $this->
crop($this->width, $this->height, $newWidth, $newHeight, $cropPos);
401 ## --------------------------------------------------------
404 # Author: Jarrod Oberto
406 # Purpose: Keep transparency for png and gif image
414 if (in_array($this->fileExtension, $this->transparentArray) && $this->keepTransparency) {
415 imagealphablending($im,
false);
416 imagesavealpha($im,
true);
417 $transparent = imagecolorallocatealpha($im, 255, 255, 255, 127);
418 imagefilledrectangle($im, 0, 0,
$width, $height, $transparent);
420 $color = imagecolorallocate($im, $this->fillColorArray[
'r'], $this->fillColorArray[
'g'], $this->fillColorArray[
'b']);
421 imagefilledrectangle($im, 0, 0,
$width, $height, $color);
425 ## --------------------------------------------------------
427 private function crop($optimalWidth, $optimalHeight, $newWidth, $newHeight, $cropPos)
428 # Author: Jarrod Oberto
430 # Purpose: Crops the image
431 # Param in: $newWidth:
440 $cropArray = $this->
getCropPlacing($optimalWidth, $optimalHeight, $newWidth, $newHeight, $cropPos);
441 $cropStartX = $cropArray[
'x'];
442 $cropStartY = $cropArray[
'y'];
445 $crop = imagecreatetruecolor($newWidth , $newHeight);
447 imagecopyresampled($crop, $this->imageResized, 0, 0, $cropStartX, $cropStartY, $newWidth, $newHeight , $newWidth, $newHeight);
449 $this->imageResized = $crop;
452 $this->width = $newWidth;
453 $this->height = $newHeight;
457 ## --------------------------------------------------------
459 private function getCropPlacing($optimalWidth, $optimalHeight, $newWidth, $newHeight, $pos=
'm')
461 # Author: Jarrod Oberto
463 # Purpose: Set the cropping area.
465 # Params out: (array) the crop x and y co-ordinates.
466 # Notes: When specifying the exact pixel crop position (eg 10x15), be
467 # very careful as it's easy to crop out of the image leaving
474 if (strstr($pos,
'x')) {
475 $pos = str_replace(
' ',
'', $pos);
477 $xyArray = explode(
'x', $pos);
478 list($cropStartX, $cropStartY) = $xyArray;
489 $cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 );
494 $cropStartX = $optimalWidth - $newWidth;
500 $cropStartY = ( $optimalHeight/ 2) - ( $newHeight/2 );
504 $cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 );
505 $cropStartY = ( $optimalHeight/ 2) - ( $newHeight/2 );
509 $cropStartX = $optimalWidth - $newWidth;
510 $cropStartY = ( $optimalHeight/ 2) - ( $newHeight/2 );
515 $cropStartY = $optimalHeight - $newHeight;
519 $cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 );
520 $cropStartY = $optimalHeight - $newHeight;
524 $cropStartX = $optimalWidth - $newWidth;
525 $cropStartY = $optimalHeight - $newHeight;
530 if ($optimalHeight > $optimalWidth) {
531 $cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 );
532 $cropStartY = ($this->cropFromTopPercent /100) * $optimalHeight;
536 $cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 );
537 $cropStartY = ( $optimalHeight/ 2) - ( $newHeight/2 );
543 $cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 );
544 $cropStartY = ( $optimalHeight/ 2) - ( $newHeight/2 );
549 return array(
'x' => $cropStartX,
'y' => $cropStartY);
552 ## --------------------------------------------------------
555 # Author: Jarrod Oberto
557 # Purpose: Get new image dimensions based on user specificaions
558 # Param in: $newWidth:
560 # Param out: Array of new width and height values
562 # Notes: If $option = 3 then this function is call recursivly
564 # To clarify the $option input:
565 # 0 = The exact height and width dimensions you set.
566 # 1 = Whatever height is passed in will be the height that
567 # is set. The width will be calculated and set automatically
568 # to a the value that keeps the original aspect ratio.
569 # 2 = The same but based on the width.
570 # 3 = Depending whether the image is landscape or portrait, this
571 # will automatically determine whether to resize via
572 # dimension 1,2 or 0.
573 # 4 = Resize the image as much as possible, then crop the
577 switch (strval($option))
581 $optimalWidth = $newWidth;
582 $optimalHeight= $newHeight;
587 $optimalWidth = $dimensionsArray[
'optimalWidth'];
588 $optimalHeight = $dimensionsArray[
'optimalHeight'];
593 $optimalWidth = $dimensionsArray[
'optimalWidth'];
594 $optimalHeight = $dimensionsArray[
'optimalHeight'];
598 $dimensionsArray = $this->
getSizeByAuto($newWidth, $newHeight);
599 $optimalWidth = $dimensionsArray[
'optimalWidth'];
600 $optimalHeight = $dimensionsArray[
'optimalHeight'];
605 $optimalWidth = $dimensionsArray[
'optimalWidth'];
606 $optimalHeight = $dimensionsArray[
'optimalHeight'];
610 return array(
'optimalWidth' => $optimalWidth,
'optimalHeight' => $optimalHeight);
613 ## --------------------------------------------------------
618 if (!$this->forceStretch) {
621 if ($this->height < $newHeight) {
622 return array(
'optimalWidth' => $this->width,
'optimalHeight' => $this->height);
628 $newWidth = $newHeight * $ratio;
631 return array(
'optimalWidth' => $newWidth,
'optimalHeight' => $newHeight);
634 ## --------------------------------------------------------
639 if (!$this->forceStretch) {
642 if ($this->width < $newWidth) {
643 return array(
'optimalWidth' => $this->width,
'optimalHeight' => $this->height);
649 $newHeight = $newWidth * $ratio;
652 return array(
'optimalWidth' => $newWidth,
'optimalHeight' => $newHeight);
655 ## --------------------------------------------------------
658 # Author: Jarrod Oberto
660 # Purpose: Depending on the height, choose to resize by 0, 1, or 2
661 # Param in: The new height and new width
666 if (!$this->forceStretch) {
669 if ($this->width < $newWidth && $this->height < $newHeight) {
670 return array(
'optimalWidth' => $this->width,
'optimalHeight' => $this->height);
674 if ($this->height < $this->width)
681 $optimalWidth = $dimensionsArray[
'optimalWidth'];
682 $optimalHeight = $dimensionsArray[
'optimalHeight'];
684 elseif ($this->height > $this->width)
691 $optimalWidth = $dimensionsArray[
'optimalWidth'];
692 $optimalHeight = $dimensionsArray[
'optimalHeight'];
698 if ($newHeight < $newWidth) {
702 $optimalWidth = $dimensionsArray[
'optimalWidth'];
703 $optimalHeight = $dimensionsArray[
'optimalHeight'];
704 }
else if ($newHeight > $newWidth) {
708 $optimalWidth = $dimensionsArray[
'optimalWidth'];
709 $optimalHeight = $dimensionsArray[
'optimalHeight'];
712 $optimalWidth = $newWidth;
713 $optimalHeight= $newHeight;
717 return array(
'optimalWidth' => $optimalWidth,
'optimalHeight' => $optimalHeight);
720 ## --------------------------------------------------------
723 # Author: Jarrod Oberto
725 # Purpose: Get optimal crop dimensions
726 # Param in: width and height as requested by user (fig 3)
727 # Param out: Array of optimal width and height (fig 2)
729 # Notes: The optimal width and height return are not the same as the
730 # same as the width and height passed in. For example:
733 # |-----------------| |------------| |-------|
734 # | | => |**| |**| => | |
736 # | | |------------| |-------|
737 # |-----------------|
738 # original optimal crop
742 # 300 x 250 150 x 125 150 x 100
744 # The optimal size is the smallest size (that is closest to the crop size)
745 # while retaining proportion/ratio.
747 # The crop size is the optimal size that has been cropped on one axis to
748 # make the image the exact size specified by the user.
750 # * represent cropped area
755 if (!$this->forceStretch) {
758 if ($this->width < $newWidth && $this->height < $newHeight) {
759 return array(
'optimalWidth' => $this->width,
'optimalHeight' => $this->height);
763 $heightRatio = $this->height / $newHeight;
764 $widthRatio = $this->width / $newWidth;
766 if ($heightRatio < $widthRatio) {
767 $optimalRatio = $heightRatio;
769 $optimalRatio = $widthRatio;
772 $optimalHeight = round( $this->height / $optimalRatio );
773 $optimalWidth = round( $this->width / $optimalRatio );
775 return array(
'optimalWidth' => $optimalWidth,
'optimalHeight' => $optimalHeight);
778 ## --------------------------------------------------------
781 # Author: Jarrod Oberto
783 # Purpose: Sharpen image
788 # Credit: Incorporates Joe Lencioni (August 6, 2008) code
791 if (version_compare(PHP_VERSION,
'5.1.0') >= 0) {
794 if ($this->aggresiveSharpening) { # A more aggressive sharpening solution
796 $sharpenMatrix = array( array( -1, -1, -1 ),
798 array( -1, -1, -1 ) );
802 imageconvolution($this->imageResized, $sharpenMatrix, $divisor, $offset);
804 else # More subtle and personally more desirable
806 $sharpness = $this->findSharp($this->widthOriginal, $this->width);
808 $sharpenMatrix = array(
810 array(-2, $sharpness + 12, -2),
813 $divisor = $sharpness;
815 imageconvolution($this->imageResized, $sharpenMatrix, $divisor, $offset);
820 if ($this->debug) {
throw new Exception(
'Sharpening required PHP 5.1.0 or greater.'); }
824 ## --------------------------------------------------------
828 $sharpenMatrix = array(
829 array($level, $level, $level),
830 array($level, (8*$level)+1, $level),
831 array($level, $level, $level)
836 ## --------------------------------------------------------
838 private function findSharp($orig, $final)
839 # Author: Ryan Rud (http://adryrun.com)
840 # Purpose: Find optimal sharpness
847 $final = $final * (750.0 / $orig);
849 $b = -0.27810650887573124;
850 $c = .00047337278106508946;
852 $result = $a + $b * $final + $c * $final * $final;
857 ## --------------------------------------------------------
859 private function prepOption($option)
860 # Author: Jarrod Oberto
861 # Purpose: Prep option like change the passed in option to lowercase
862 # Param in: (str/int) $option: eg. 'exact', 'crop'. 0, 4
863 # Param out: lowercase string
868 if (is_array($option)) {
869 if (
fix_strtolower($option[0]) ==
'crop' && count($option) == 2) {
872 throw new Exception(
'Crop resize option array is badly formatted.');
874 }
else if (strpos($option,
'crop') !==
false) {
878 if (is_string($option)) {
891 # Preset are pre-defined templates you can apply to your image.
893 # These are inteded to be applied to thumbnail images.
897 public function borderPreset($preset)
903 $this->addBorder(7,
'#fff');
904 $this->addBorder(6,
'#f2f1f0');
905 $this->addBorder(2,
'#fff');
906 $this->addBorder(1,
'#ccc');
919 public function addBorder($thickness = 1, $rgbArray = array(255, 255, 255))
920 # Author: Jarrod Oberto
922 # Purpose: Add a border to the image
926 # Notes: This border is added to the INSIDE of the image
929 if ($this->imageResized) {
931 $rgbArray = $this->formatColor($rgbArray);
939 $x2 = ImageSX($this->imageResized) - 1;
940 $y2 = ImageSY($this->imageResized) - 1;
942 $rgbArray = ImageColorAllocate($this->imageResized, $r, $g, $b);
945 for(
$i = 0;
$i < $thickness;
$i++) {
946 ImageRectangle($this->imageResized, $x1++, $y1++, $x2--, $y2--, $rgbArray);
956 public function greyScale()
957 # Author: Jarrod Oberto
959 # Purpose: Make image greyscale
966 if ($this->imageResized) {
967 imagefilter($this->imageResized, IMG_FILTER_GRAYSCALE);
972 ## --------------------------------------------------------
974 public function greyScaleEnhanced()
975 # Author: Jarrod Oberto
977 # Purpose: Make image greyscale
984 if ($this->imageResized) {
985 imagefilter($this->imageResized, IMG_FILTER_GRAYSCALE);
986 imagefilter($this->imageResized, IMG_FILTER_CONTRAST, -15);
987 imagefilter($this->imageResized, IMG_FILTER_BRIGHTNESS, 2);
992 ## --------------------------------------------------------
994 public function greyScaleDramatic()
995 # Alias of gd_filter_monopin
997 $this->gd_filter_monopin();
1005 public function blackAndWhite()
1006 # Author: Jarrod Oberto
1008 # Purpose: Make image black and white
1015 if ($this->imageResized) {
1017 imagefilter($this->imageResized, IMG_FILTER_GRAYSCALE);
1018 imagefilter($this->imageResized, IMG_FILTER_CONTRAST, -1000);
1028 public function negative()
1029 # Author: Jarrod Oberto
1031 # Purpose: Make image negative
1038 if ($this->imageResized) {
1040 imagefilter($this->imageResized, IMG_FILTER_NEGATE);
1050 public function sepia()
1051 # Author: Jarrod Oberto
1053 # Purpose: Make image sepia
1060 if ($this->imageResized) {
1061 imagefilter($this->imageResized, IMG_FILTER_GRAYSCALE);
1062 imagefilter($this->imageResized, IMG_FILTER_BRIGHTNESS, -10);
1063 imagefilter($this->imageResized, IMG_FILTER_CONTRAST, -20);
1064 imagefilter($this->imageResized, IMG_FILTER_COLORIZE, 60, 30, -15);
1068 ## --------------------------------------------------------
1070 public function sepia2()
1073 if ($this->imageResized) {
1075 $total = imagecolorstotal( $this->imageResized );
1076 for (
$i = 0;
$i < $total;
$i++ ) {
1077 $index = imagecolorsforindex( $this->imageResized,
$i );
1078 $red = (
$index[
"red"] * 0.393 +
$index[
"green"] * 0.769 +
$index[
"blue"] * 0.189 ) / 1.351;
1079 $green = (
$index[
"red"] * 0.349 +
$index[
"green"] * 0.686 +
$index[
"blue"] * 0.168 ) / 1.203;
1080 $blue = (
$index[
"red"] * 0.272 +
$index[
"green"] * 0.534 +
$index[
"blue"] * 0.131 ) / 2.140;
1081 imagecolorset( $this->imageResized,
$i, $red, $green, $blue );
1093 public function vintage()
1094 # Alias of gd_filter_monopin
1096 $this->gd_filter_vintage();
1105 public function gd_filter_monopin()
1108 if ($this->imageResized) {
1109 imagefilter($this->imageResized, IMG_FILTER_GRAYSCALE);
1110 imagefilter($this->imageResized, IMG_FILTER_BRIGHTNESS, -15);
1111 imagefilter($this->imageResized, IMG_FILTER_CONTRAST, -15);
1112 $this->imageResized = $this->gd_apply_overlay($this->imageResized,
'vignette', 100);
1116 ## --------------------------------------------------------
1118 public function gd_filter_vintage()
1120 if ($this->imageResized) {
1121 $this->imageResized = $this->gd_apply_overlay($this->imageResized,
'vignette', 45);
1122 imagefilter($this->imageResized, IMG_FILTER_BRIGHTNESS, 20);
1123 imagefilter($this->imageResized, IMG_FILTER_CONTRAST, -35);
1124 imagefilter($this->imageResized, IMG_FILTER_COLORIZE, 60, -10, 35);
1125 imagefilter($this->imageResized, IMG_FILTER_SMOOTH, 7);
1126 $this->imageResized = $this->gd_apply_overlay($this->imageResized,
'scratch', 10);
1130 ## --------------------------------------------------------
1133 private function gd_apply_overlay($im,
$type, $amount)
1135 # Original Author: Marc Hibbins
1136 # License: Attribution-ShareAlike 3.0
1144 $height = imagesy($im);
1147 imagealphablending(
$filter,
false);
1148 imagesavealpha(
$filter,
true);
1150 $transparent = imagecolorallocatealpha(
$filter, 255, 255, 255, 127);
1151 imagefilledrectangle(
$filter, 0, 0,
$width, $height, $transparent);
1154 $overlay = $this->filterOverlayPath .
'/' .
$type .
'.png';
1155 $png = imagecreatefrompng($overlay);
1156 imagecopyresampled(
$filter, $png, 0, 0, 0, 0,
$width, $height, imagesx($png), imagesy($png));
1158 $comp = imagecreatetruecolor(
$width, $height);
1159 imagecopy($comp, $im, 0, 0, 0, 0,
$width, $height);
1161 imagecopymerge($im, $comp, 0, 0, 0, 0,
$width, $height, $amount);
1163 imagedestroy($comp);
1172 public function image_colorize($rgb) {
1173 imageTrueColorToPalette($this->imageResized,
true,256);
1174 $numColors = imageColorsTotal($this->imageResized);
1176 for ($x = 0; $x < $numColors; $x++) {
1177 list($r,$g,$b) = array_values(imageColorsForIndex($this->imageResized,$x));
1180 $grayscale = ($r + $g + $b) / 3 / 0xff;
1182 imageColorSet($this->imageResized,$x,
1183 $grayscale * $rgb[0],
1184 $grayscale * $rgb[1],
1185 $grayscale * $rgb[2]
1198 public function addReflection($reflectionHeight = 50, $startingTransparency = 30, $inside =
false, $bgColor =
'#fff', $stretch=
false, $divider = 0)
1202 $rgbArray = $this->formatColor($bgColor);
1203 $r = $rgbArray[
'r'];
1204 $g = $rgbArray[
'g'];
1205 $b = $rgbArray[
'b'];
1208 $li = imagecreatetruecolor($this->width, 1);
1210 $bgc = imagecolorallocate($li, $r, $g, $b);
1211 imagefilledrectangle($li, 0, 0, $this->width, 1, $bgc);
1213 $bg = imagecreatetruecolor($this->width, $reflectionHeight);
1214 $wh = imagecolorallocate($im, 255, 255, 255);
1216 $im = imagerotate($im, -180, $wh);
1217 imagecopyresampled(
$bg, $im, 0, 0, 0, 0, $this->width, $this->height, $this->width, $this->height);
1221 $bg = imagecreatetruecolor($this->width, $reflectionHeight);
1224 imagecopy(
$bg, $im, $x, 0, $this->width-$x -1, 0, 1, $reflectionHeight);
1228 $transaprencyAmount = $this->invertTransparency($startingTransparency, 100);
1233 $step = 100/($reflectionHeight + $startingTransparency);
1235 $step = 100/$reflectionHeight;
1237 for(
$i=0;
$i<=$reflectionHeight;
$i++){
1239 if($startingTransparency>100) $startingTransparency = 100;
1240 if($startingTransparency< 1) $startingTransparency = 1;
1241 imagecopymerge(
$bg, $li, 0,
$i, 0, 0, $this->width, 1, $startingTransparency);
1242 $startingTransparency+=$step;
1246 imagecopymerge($im, $li, 0, 0, 0, 0, $this->width, $divider, 100);
1258 $final = imagecreatetruecolor($this->width, $this->height);
1260 imagecopymerge ($final, $this->imageResized, 0, 0, 0, $reflectionHeight, $this->width, $this->height - $reflectionHeight, 100);
1261 imagecopymerge ($final, $im, 0, $this->height - $reflectionHeight, 0, 0, $x, $y, 100);
1266 $final = imagecreatetruecolor($this->width, $this->height + $y);
1268 imagecopymerge ($final, $this->imageResized, 0, 0, 0, 0, $this->width, $this->height, 100);
1269 imagecopymerge ($final, $im, 0, $this->height, 0, 0, $x, $y, 100);
1272 $this->imageResized = $final;
1283 public function rotate($value = 90, $bgColor =
'transparent')
1284 # Author: Jarrod Oberto
1286 # Purpose: Rotate image
1287 # Param in: (mixed) $degrees: (int) number of degress to rotate image
1288 # (str) param "left": rotate left
1289 # (str) param "right": rotate right
1290 # (str) param "upside": upside-down image
1293 # Notes: The default direction of imageRotate() is counter clockwise.
1296 if ($this->imageResized) {
1298 if (is_integer($value)) {
1303 $rgbArray = $this->formatColor($bgColor);
1304 $r = $rgbArray[
'r'];
1305 $g = $rgbArray[
'g'];
1306 $b = $rgbArray[
'b'];
1307 if (isset($rgbArray[
'a'])) {$a = $rgbArray[
'a']; }
1309 if (is_string($value)) {
1331 $degrees = 360 - $degrees;
1334 $bg = ImageColorAllocateAlpha($this->imageResized, $r, $g, $b, $a);
1337 ImageFill($this->imageResized, 0, 0 ,
$bg);
1340 $this->imageResized = imagerotate($this->imageResized, $degrees,
$bg);
1343 ImageSaveAlpha($this->imageResized,
true);
1353 public function roundCorners($radius = 5, $bgColor =
'transparent')
1354 # Author: Jarrod Oberto
1356 # Purpose: Create rounded corners on your image
1357 # Param in: (int) radius = the amount of curvature
1358 # (mixed) $bgColor = the corner background color
1366 $isTransparent =
false;
1367 if (!is_array($bgColor)) {
1369 $isTransparent =
true;
1375 if ($isTransparent) {
1376 $bgColor = $this->findUnusedGreen();
1380 $rgbArray = $this->formatColor($bgColor);
1381 $r = $rgbArray[
'r'];
1382 $g = $rgbArray[
'g'];
1383 $b = $rgbArray[
'b'];
1384 if (isset($rgbArray[
'a'])) {$a = $rgbArray[
'a']; }
1389 $cornerImg = imagecreatetruecolor($radius, $radius);
1399 $maskColor = imagecolorallocate($cornerImg, 0, 0, 0);
1404 imagecolortransparent($cornerImg, $maskColor);
1409 $imagebgColor = imagecolorallocate($cornerImg, $r, $g, $b);
1414 imagefill($cornerImg, 0, 0, $imagebgColor);
1417 imagefilledellipse($cornerImg, $radius, $radius, $radius * 2, $radius * 2, $maskColor );
1421 imagecopymerge($this->imageResized, $cornerImg, 0, 0, 0, 0, $radius, $radius, 100); #tl
1424 $cornerImg = imagerotate($cornerImg, 90, 0);
1425 imagecopymerge($this->imageResized, $cornerImg, 0, $this->height - $radius, 0, 0, $radius, $radius, 100); #bl
1427 $cornerImg = imagerotate($cornerImg, 90, 0);
1428 imagecopymerge($this->imageResized, $cornerImg, $this->width - $radius, $this->height - $radius, 0, 0, $radius, $radius, 100); #br
1430 $cornerImg = imagerotate($cornerImg, 90, 0);
1431 imagecopymerge($this->imageResized, $cornerImg, $this->width - $radius, 0, 0, 0, $radius, $radius, 100); #tr
1435 if ($isTransparent) {
1437 $this->imageResized = $this->transparentImage($this->imageResized);
1438 imagesavealpha($this->imageResized,
true);
1448 public function addShadow($shadowAngle=45, $blur=15, $bgColor=
'transparent')
1450 # Author: Jarrod Oberto (Adapted from Pascal Naidon)
1451 # Ref: http://www.les-stooges.org/pascal/webdesign/vignettes/index.php?la=en
1452 # Purpose: Add a drop shadow to your image
1453 # Params in: (int) $angle: the angle of the shadow
1454 # (int) $blur: the blur distance
1455 # (mixed) $bgColor: the color of the background
1461 define(
'STEPS', $blur*2);
1464 $shadowDistance = $blur*0.25;
1467 $blurWidth = $blurHeight = $blur;
1470 if ($shadowAngle == 0) {
1474 $distWidth = $shadowDistance * cos(deg2rad($shadowAngle));
1475 $distHeight = $shadowDistance * sin(deg2rad($shadowAngle));
1481 $rgbArray = $this->formatColor($bgColor);
1482 $r0 = $rgbArray[
'r'];
1483 $g0 = $rgbArray[
'g'];
1484 $b0 = $rgbArray[
'b'];
1493 $newImage = imagecreatetruecolor(
$width, $height);
1498 $rgb = imagecreatetruecolor(
$width+$blurWidth,$height+$blurHeight);
1499 $colour = imagecolorallocate($rgb, 0, 0, 0);
1500 imagefilledrectangle($rgb, 0, 0,
$width+$blurWidth, $height+$blurHeight, $colour);
1501 $colour = imagecolorallocate($rgb, 255, 255, 255);
1503 imagefilledrectangle($rgb, $blurWidth*0.5-$distWidth, $blurHeight*0.5-$distHeight,
$width+$blurWidth*0.5-$distWidth, $height+$blurWidth*0.5-$distHeight, $colour);
1505 imagecopymerge($rgb, $newImage, $blurWidth*0.5-$distWidth, $blurHeight*0.5-$distHeight, 0,0,
$width+$blurWidth, $height+$blurHeight, 100);
1509 $shadow = imagecreatetruecolor(
$width+$blurWidth,$height+$blurHeight);
1510 imagealphablending($shadow,
false);
1511 $colour = imagecolorallocate($shadow, 0, 0, 0);
1512 imagefilledrectangle($shadow, 0, 0,
$width+$blurWidth, $height+$blurHeight, $colour);
1515 for(
$i=0;
$i<=STEPS;
$i++) {
1517 $t = ((1.0*
$i)/STEPS);
1518 $intensity = 255*$t*$t;
1520 $colour = imagecolorallocate($shadow, $intensity, $intensity, $intensity);
1522 $blurWidth*$t, $blurHeight,
1523 $blurWidth, $blurHeight*$t,
1525 $width+$blurWidth*(1-$t), $blurHeight,
1526 $width+$blurWidth*(1-$t), $height,
1527 $width, $height+$blurHeight*(1-$t),
1528 $blurWidth, $height+$blurHeight*(1-$t),
1529 $blurWidth*$t, $height
1531 imagepolygon($shadow, $points, 8, $colour);
1534 for(
$i=0;
$i<=STEPS;
$i++) {
1536 $t = ((1.0*
$i)/STEPS);
1537 $intensity = 255*$t*$t;
1539 $colour = imagecolorallocate($shadow, $intensity, $intensity, $intensity);
1540 imagefilledarc($shadow, $blurWidth-1, $blurHeight-1, 2*(1-$t)*$blurWidth, 2*(1-$t)*$blurHeight, 180, 268, $colour, IMG_ARC_PIE);
1541 imagefilledarc($shadow,
$width, $blurHeight-1, 2*(1-$t)*$blurWidth, 2*(1-$t)*$blurHeight, 270, 358, $colour, IMG_ARC_PIE);
1542 imagefilledarc($shadow,
$width, $height, 2*(1-$t)*$blurWidth, 2*(1-$t)*$blurHeight, 0, 90, $colour, IMG_ARC_PIE);
1543 imagefilledarc($shadow, $blurWidth-1, $height, 2*(1-$t)*$blurWidth, 2*(1-$t)*$blurHeight, 90, 180, $colour, IMG_ARC_PIE);
1547 $colour = imagecolorallocate($shadow, 255, 255, 255);
1548 imagefilledrectangle($shadow, $blurWidth, $blurHeight,
$width, $height, $colour);
1549 imagefilledrectangle($shadow, $blurWidth*0.5-$distWidth, $blurHeight*0.5-$distHeight,
$width+$blurWidth*0.5-1-$distWidth, $height+$blurHeight*0.5-1-$distHeight, $colour);
1553 imagealphablending($rgb,
false);
1555 for ($theX=0;$theX<imagesx($rgb);$theX++){
1556 for ($theY=0;$theY<imagesy($rgb);$theY++){
1559 $colArray = imagecolorat($rgb,$theX,$theY);
1560 $r = ($colArray >> 16) & 0xFF;
1561 $g = ($colArray >> 8) & 0xFF;
1562 $b = $colArray & 0xFF;
1565 $colArray = imagecolorat($shadow,$theX,$theY);
1566 $a = $colArray & 0xFF;
1567 $a = 127-floor($a/2);
1572 $myColour = imagecolorallocatealpha($rgb,$r,$g,$b,$a);
1574 $myColour = imagecolorallocate($rgb,$r*(1.0-$t)+$r0*$t,$g*(1.0-$t)+$g0*$t,$b*(1.0-$t)+$b0*$t);
1578 imagesetpixel($rgb, $theX, $theY, $myColour);
1582 imagealphablending($rgb,
true);
1583 imagesavealpha($rgb,
true);
1585 $this->imageResized = $rgb;
1588 imagedestroy($newImage);
1589 imagedestroy($shadow);
1597 public function addCaptionBox($side=
'b', $thickness=50, $padding=0, $bgColor=
'#000', $transaprencyAmount=30)
1599 # Author: Jarrod Oberto
1601 # Purpose: Add a caption box
1602 # Params in: (str) $side: the side to add the caption box (t, r, b, or l).
1603 # (int) $thickness: how thick you want the caption box to be.
1604 # (mixed) $bgColor: The color of the caption box.
1605 # (int) $transaprencyAmount: The amount of transparency to be
1614 $rgbArray = $this->formatColor($bgColor);
1615 $r = $rgbArray[
'r'];
1616 $g = $rgbArray[
'g'];
1617 $b = $rgbArray[
'b'];
1619 $positionArray = $this->calculateCaptionBoxPosition($side, $thickness, $padding);
1622 $this->captionBoxPositionArray = $positionArray;
1625 $transaprencyAmount = $this->invertTransparency($transaprencyAmount, 127,
false);
1626 $transparent = imagecolorallocatealpha($this->imageResized, $r, $g, $b, $transaprencyAmount);
1627 imagefilledrectangle($this->imageResized, $positionArray[
'x1'], $positionArray[
'y1'], $positionArray[
'x2'], $positionArray[
'y2'], $transparent);
1630 ## --------------------------------------------------------
1632 public function addTextToCaptionBox(
$text, $fontColor=
'#fff', $fontSize = 12, $angle = 0, $font = null)
1634 # Author: Jarrod Oberto
1636 # Purpose: Simplify adding text to a caption box by automatically
1637 # locating the center of the caption box
1638 # Params in: The usually text paams (less a couple)
1645 if (count($this->captionBoxPositionArray) == 4) {
1646 $x1 = $this->captionBoxPositionArray[
'x1'];
1647 $x2 = $this->captionBoxPositionArray[
'x2'];
1648 $y1 = $this->captionBoxPositionArray[
'y1'];
1649 $y2 = $this->captionBoxPositionArray[
'y2'];
1651 if ($this->debug) {
throw new Exception(
'No caption box found.'); }
else{
return false; }
1656 $font = $this->getTextFont($font);
1659 $textSizeArray = $this->getTextSize($fontSize, $angle, $font,
$text);
1660 $textWidth = $textSizeArray[
'width'];
1661 $textHeight = $textSizeArray[
'height'];
1664 $boxXMiddle = (($x2 - $x1) / 2);
1665 $boxYMiddle = (($y2 - $y1) / 2);
1668 $xPos = ($x1 + $boxXMiddle) - ($textWidth/2);
1669 $yPos = ($y1 + $boxYMiddle) - ($textHeight/2);
1671 $pos = $xPos .
'x' . $yPos;
1673 $this->addText(
$text, $pos, $padding = 0, $fontColor, $fontSize, $angle, $font);
1677 ## --------------------------------------------------------
1679 private function calculateCaptionBoxPosition($side, $thickness, $padding)
1681 $positionArray = array();
1685 $positionArray[
'x1'] = 0;
1686 $positionArray[
'y1'] = $padding;
1688 $positionArray[
'y2'] = $thickness + $padding;
1691 $positionArray[
'x1'] = $this->width - $thickness - $padding;
1692 $positionArray[
'y1'] = 0;
1693 $positionArray[
'x2'] = $this->width - $padding;
1697 $positionArray[
'x1'] = 0;
1698 $positionArray[
'y1'] = $this->height - $thickness - $padding;
1700 $positionArray[
'y2'] = $this->height - $padding;
1703 $positionArray[
'x1'] = $padding;
1704 $positionArray[
'y1'] = 0;
1705 $positionArray[
'x2'] = $thickness + $padding;
1713 return $positionArray;
1721 public function getExif(
$debug=
false)
1722 # Author: Jarrod Oberto
1724 # Purpose: Get image EXIF data
1726 # Param out: An associate array of EXIF data
1729 # 23 May 13 : added orientation flag -jco
1736 if (!$this->testEXIFInstalled()) {
if (
$debug) {
throw new Exception(
'The EXIF Library is not installed.'); }
else{
return array(); }};
1737 if (!file_exists($this->fileName)) {
if (
$debug) {
throw new Exception(
'Image not found.'); }
else{
return array(); }};
1738 if ($this->fileExtension !=
'.jpg') {
if (
$debug) {
throw new Exception(
'Metadata not supported for this image type.'); }
else{
return array(); }};
1739 $exifData = exif_read_data($this->fileName,
'IFD0');
1742 $ev = $exifData[
'ApertureValue'];
1743 $apPeicesArray = explode(
'/', $ev);
1744 if (count($apPeicesArray) == 2) {
1745 $apertureValue = round($apPeicesArray[0] / $apPeicesArray[1], 2, PHP_ROUND_HALF_DOWN) .
' EV';
1746 }
else { $apertureValue =
'';}
1749 $focalLength = $exifData[
'FocalLength'];
1750 $flPeicesArray = explode(
'/', $focalLength);
1751 if (count($flPeicesArray) == 2) {
1752 $focalLength = $flPeicesArray[0] / $flPeicesArray[1] .
'.0 mm';
1753 }
else { $focalLength =
'';}
1756 $fNumber = $exifData[
'FNumber'];
1757 $fnPeicesArray = explode(
'/', $fNumber);
1758 if (count($fnPeicesArray) == 2) {
1759 $fNumber = $fnPeicesArray[0] / $fnPeicesArray[1];
1760 }
else { $fNumber =
'';}
1763 if (isset($exifData[
'ExposureProgram'])) { $ep = $exifData[
'ExposureProgram']; }
1764 if (isset($ep)) { $ep = $this->resolveExposureProgram($ep); }
1768 $mm = $exifData[
'MeteringMode'];
1769 $mm = $this->resolveMeteringMode($mm);
1772 $flash = $exifData[
'Flash'];
1773 $flash = $this->resolveFlash($flash);
1776 if (isset($exifData[
'Make'])) {
1777 $exifDataArray[
'make'] = $exifData[
'Make'];
1778 }
else { $exifDataArray[
'make'] =
''; }
1780 if (isset($exifData[
'Model'])) {
1781 $exifDataArray[
'model'] = $exifData[
'Model'];
1782 }
else { $exifDataArray[
'model'] =
''; }
1784 if (isset($exifData[
'DateTime'])) {
1785 $exifDataArray[
'date'] = $exifData[
'DateTime'];
1786 }
else { $exifDataArray[
'date'] =
''; }
1788 if (isset($exifData[
'ExposureTime'])) {
1789 $exifDataArray[
'exposure time'] = $exifData[
'ExposureTime'] .
' sec.';
1790 }
else { $exifDataArray[
'exposure time'] =
''; }
1792 if ($apertureValue !=
'') {
1793 $exifDataArray[
'aperture value'] = $apertureValue;
1794 }
else { $exifDataArray[
'aperture value'] =
''; }
1796 if (isset($exifData[
'COMPUTED'][
'ApertureFNumber'])) {
1797 $exifDataArray[
'f-stop'] = $exifData[
'COMPUTED'][
'ApertureFNumber'];
1798 }
else { $exifDataArray[
'f-stop'] =
''; }
1800 if (isset($exifData[
'FNumber'])) {
1801 $exifDataArray[
'fnumber'] = $exifData[
'FNumber'];
1802 }
else { $exifDataArray[
'fnumber'] =
''; }
1804 if ($fNumber !=
'') {
1805 $exifDataArray[
'fnumber value'] = $fNumber;
1806 }
else { $exifDataArray[
'fnumber value'] =
''; }
1808 if (isset($exifData[
'ISOSpeedRatings'])) {
1809 $exifDataArray[
'iso'] = $exifData[
'ISOSpeedRatings'];
1810 }
else { $exifDataArray[
'iso'] =
''; }
1812 if ($focalLength !=
'') {
1813 $exifDataArray[
'focal length'] = $focalLength;
1814 }
else { $exifDataArray[
'focal length'] =
''; }
1817 $exifDataArray[
'exposure program'] = $ep;
1818 }
else { $exifDataArray[
'exposure program'] =
''; }
1821 $exifDataArray[
'metering mode'] = $mm;
1822 }
else { $exifDataArray[
'metering mode'] =
''; }
1825 $exifDataArray[
'flash status'] = $flash;
1826 }
else { $exifDataArray[
'flash status'] =
''; }
1828 if (isset($exifData[
'Artist'])) {
1829 $exifDataArray[
'creator'] = $exifData[
'Artist'] ;
1830 }
else { $exifDataArray[
'creator'] =
''; }
1832 if (isset($exifData[
'Copyright'])) {
1833 $exifDataArray[
'copyright'] = $exifData[
'Copyright'];
1834 }
else { $exifDataArray[
'copyright'] =
''; }
1837 if (isset($exifData[
'Orientation'])) {
1838 $exifDataArray[
'orientation'] = $exifData[
'Orientation'];
1839 }
else { $exifDataArray[
'orientation'] =
''; }
1841 return $exifDataArray;
1844 ## --------------------------------------------------------
1846 private function resolveExposureProgram($ep)
1856 $ep =
'normal program';
1859 $ep =
'aperture priority';
1862 $ep =
'shutter priority';
1865 $ep =
'creative program';
1868 $ep =
'action program';
1871 $ep =
'portrait mode';
1874 $ep =
'landscape mode';
1884 ## --------------------------------------------------------
1886 private function resolveMeteringMode($mm)
1896 $mm =
'center weighted average';
1921 ## --------------------------------------------------------
1923 private function resolveFlash($flash)
1927 $flash =
'flash did not fire';
1930 $flash =
'flash fired';
1933 $flash =
'strobe return light not detected';
1936 $flash =
'strobe return light detected';
1939 $flash =
'flash fired, compulsory flash mode';
1942 $flash =
'flash fired, compulsory flash mode, return light not detected';
1945 $flash =
'flash fired, compulsory flash mode, return light detected';
1948 $flash =
'flash did not fire, compulsory flash mode';
1951 $flash =
'flash did not fire, auto mode';
1954 $flash =
'flash fired, auto mode';
1957 $flash =
'flash fired, auto mode, return light not detected';
1960 $flash =
'flash fired, auto mode, return light detected';
1963 $flash =
'no flash function';
1966 $flash =
'flash fired, red-eye reduction mode';
1969 $flash =
'flash fired, red-eye reduction mode, return light not detected';
1972 $flash =
'flash fired, red-eye reduction mode, return light detected';
1975 $flash =
'flash fired, compulsory flash mode, red-eye reduction mode';
1978 $flash =
'flash fired, compulsory flash mode, red-eye reduction mode, return light not detected';
1981 $flash =
'flash fired, compulsory flash mode, red-eye reduction mode, return light detected';
1984 $flash =
'flash fired, auto mode, red-eye reduction mode';
1987 $flash =
'flash fired, auto mode, return light not detected, red-eye reduction mode';
1990 $flash =
'flash fired, auto mode, return light detected, red-eye reduction mode';
2011 public function writeIPTCcaption($value)
2014 $this->writeIPTC(120, $value);
2017 ## --------------------------------------------------------
2019 public function writeIPTCwriter($value)
2024 ## --------------------------------------------------------
2026 private function writeIPTC($dat, $value)
2031 $caption_block = $this->iptc_maketag(2, $dat, $value);
2032 $image_string = iptcembed($caption_block, $this->fileName);
2033 file_put_contents(
'iptc.jpg', $image_string);
2036 ## --------------------------------------------------------
2038 private function iptc_maketag($rec,$dat,$val)
2039 # Author: Thies C. Arntzen
2040 # Purpose: Function to format the new IPTC text
2041 # Param in: $rec: Application record. (We’re working with #2)
2042 # $dat: Index. (120 for caption, 118 for contact. See the IPTC IIM
2044 # http://www.iptc.org/std/IIM/4.1/specification/IIMV4.1.pdf
2045 # $val: Value/data/text. Make sure this is within the length
2046 # constraints of the IPTC IIM specification
2047 # Ref: http://blog.peterhaza.no/working-with-image-meta-data-in-exif-and-iptc-headers-from-php/
2048 # http://php.net/manual/en/function.iptcembed.php
2051 $len = strlen($val);
2053 return chr(0x1c).chr($rec).chr($dat).
2058 return chr(0x1c).chr($rec).chr($dat).
2059 chr(0x80).chr(0x04).
2060 chr(($len >> 24) & 0xff).
2061 chr(($len >> 16) & 0xff).
2062 chr(($len >> 8 ) & 0xff).
2063 chr(($len ) & 0xff).
2080 public function addText(
$text, $pos =
'20x20', $padding = 0, $fontColor=
'#fff', $fontSize = 12, $angle = 0, $font = null)
2081 # Author: Jarrod Oberto
2083 # Purpose: Add text to an image
2086 # Reference: http://php.net/manual/en/function.imagettftext.php
2087 # Notes: Make sure you supply the font.
2092 $rgbArray = $this->formatColor($fontColor);
2093 $r = $rgbArray[
'r'];
2094 $g = $rgbArray[
'g'];
2095 $b = $rgbArray[
'b'];
2098 $font = $this->getTextFont($font);
2101 $textSizeArray = $this->getTextSize($fontSize, $angle, $font,
$text);
2102 $textWidth = $textSizeArray[
'width'];
2103 $textHeight = $textSizeArray[
'height'];
2106 $posArray = $this->calculatePosition($pos, $padding, $textWidth, $textHeight,
false);
2107 $x = $posArray[
'width'];
2108 $y = $posArray[
'height'];
2110 $fontColor = imagecolorallocate($this->imageResized, $r, $g, $b);
2113 imagettftext($this->imageResized, $fontSize, $angle, $x, $y, $fontColor, $font,
$text);
2116 ## --------------------------------------------------------
2118 private function getTextFont($font)
2125 putenv(
'GDFONTPATH=' . realpath(
'.'));
2128 if ($font == null || !file_exists($font)) {
2131 $font = $fontPath .
'/arimo.ttf';
2134 if (!file_exists($font)) {
2137 if ($this->debug) {
throw new Exception(
'Font not found'); }
else{
return false; }
2145 ## --------------------------------------------------------
2147 private function getTextSize($fontSize, $angle, $font,
$text)
2151 $box = @imageTTFBbox($fontSize, $angle, $font,
$text);
2154 $textWidth = abs($box[4] - $box[0]);
2157 $textHeight = abs($box[5] - $box[1]);
2159 return array(
'height' => $textHeight,
'width' => $textWidth);
2167 public function addWatermark($watermarkImage, $pos, $padding = 0, $opacity = 0)
2168 # Author: Jarrod Oberto
2170 # Purpose: Add watermark image
2171 # Param in: (str) $watermark: The watermark image
2172 # (str) $pos: Could be a pre-determined position such as:
2180 # b = bottom (middle),
2182 # Or, it could be a co-ordinate position such as: 50x100
2184 # (int) $padding: If using a pre-determined position you can
2185 # adjust the padding from the edges by passing an amount
2186 # in pixels. If using co-ordinates, this value is ignored.
2188 # Reference: http://www.php.net/manual/en/image.examples-watermark.php
2189 # Notes: Based on example in reference.
2195 $stamp = $this->openImage ($watermarkImage); # stamp
2199 $sx = imagesx($stamp);
2200 $sy = imagesy($stamp);
2203 $posArray = $this->calculatePosition($pos, $padding, $sx, $sy);
2204 $x = $posArray[
'width'];
2205 $y = $posArray[
'height'];
2210 $opacity = $this->invertTransparency($opacity, 100);
2211 $this->filterOpacity($stamp, $opacity);
2215 imagecopy($im, $stamp, $x, $y, 0, 0, imagesx($stamp), imagesy($stamp));
2219 ## --------------------------------------------------------
2221 private function calculatePosition($pos, $padding, $assetWidth, $assetHeight, $upperLeft =
true)
2223 # Author: Jarrod Oberto
2225 # Purpose: Calculate the x, y pixel cordinates of the asset to place
2226 # Params in: (str) $pos: Either something like: "tl", "l", "br" or an
2227 # exact position like: "100x50"
2228 # (int) $padding: The amount of padding from the edge. Only
2229 # used for the predefined $pos.
2230 # (int) $assetWidth: The width of the asset to add to the image
2231 # (int) $assetHeight: The height of the asset to add to the image
2232 # (bol) $upperLeft: if true, the asset will be positioned based
2233 # on the upper left x, y coords. If false, it means you're
2234 # using the lower left as the basepoint and this will
2235 # convert it to the upper left position
2237 # NOTE: this is done from the UPPER left corner!! But will convert lower
2238 # left basepoints to upper left if $upperleft is set to false
2245 if (strstr($pos,
'x')) {
2246 $pos = str_replace(
' ',
'', $pos);
2248 $xyArray = explode(
'x', $pos);
2249 list(
$width, $height) = $xyArray;
2256 $height = 0 + $padding;
2260 $width = ($this->width / 2) - ($assetWidth / 2);
2261 $height = 0 + $padding;
2265 $width = $this->width - $assetWidth - $padding;
2266 $height = 0 + $padding;;
2271 $height = ($this->height / 2) - ($assetHeight / 2);
2275 $width = ($this->width / 2) - ($assetWidth / 2);
2276 $height = ($this->height / 2) - ($assetHeight / 2);
2280 $width = $this->width - $assetWidth - $padding;
2281 $height = ($this->height / 2) - ($assetHeight / 2);
2286 $height = $this->height - $assetHeight - $padding;
2290 $width = ($this->width / 2) - ($assetWidth / 2);
2291 $height = $this->height - $assetHeight - $padding;
2295 $width = $this->width - $assetWidth - $padding;
2296 $height = $this->height - $assetHeight - $padding;
2307 $height = $height + $assetHeight;
2310 return array(
'width' =>
$width,
'height' => $height);
2314 ## --------------------------------------------------------
2316 private function filterOpacity(&$img, $opacity = 75)
2318 # Author: aiden dot mail at freemail dot hu
2319 # Author date: 29-03-08 08:16
2320 # Date added: 08-05-11
2321 # Purpose: Change opacity of image
2322 # Params in: $img: Image resource id
2323 # (int) $opacity: the opacity amount: 0-100, 100 being not opaque.
2324 # Params out: (bool) true on success, else false
2325 # Ref: http://www.php.net/manual/en/function.imagefilter.php#82162
2330 if (!isset($opacity)) {
2334 if ($opacity == 100) {
2345 imagealphablending($img,
false);
2349 for ($x = 0; $x < $w; $x++)
2350 for ($y = 0; $y < $h; $y++) {
2351 $alpha = ( imagecolorat($img, $x, $y) >> 24 ) & 0xFF;
2352 if ($alpha < $minalpha) {
2358 for ($x = 0; $x < $w; $x++) {
2359 for ($y = 0; $y < $h; $y++) {
2361 $colorxy = imagecolorat($img, $x, $y);
2362 $alpha = ( $colorxy >> 24 ) & 0xFF;
2364 if ($minalpha !== 127) {
2365 $alpha = 127 + 127 * $opacity * ( $alpha - 127 ) / ( 127 - $minalpha );
2367 $alpha += 127 * $opacity;
2370 $alphacolorxy = imagecolorallocatealpha($img, ( $colorxy >> 16 ) & 0xFF, ( $colorxy >> 8 ) & 0xFF, $colorxy & 0xFF, $alpha);
2372 if (!imagesetpixel($img, $x, $y, $alphacolorxy)) {
2382 ## --------------------------------------------------------
2384 private function openImage(
$file)
2385 # Author: Jarrod Oberto
2395 if (!file_exists(
$file) && !$this->checkStringStartsWith(
'http://',
$file)) {
if ($this->debug) {
throw new Exception(
'Image not found.'); }
else{
throw new Exception(); }};
2398 $extension = strrchr(
$file,
'.');
2404 $img = @imagecreatefromjpeg(
$file);
2407 $img = @imagecreatefromgif(
$file);
2410 $img = @imagecreatefrompng(
$file);
2413 $img = @$this->imagecreatefrombmp(
$file);
2416 $img = @$this->imagecreatefrompsd(
$file);
2430 ## --------------------------------------------------------
2432 public function reset()
2434 # Author: Jarrod Oberto
2436 # Purpose: Reset the resource (allow further editing)
2445 ## --------------------------------------------------------
2447 public function saveImage($savePath, $imageQuality=
"100")
2448 # Author: Jarrod Oberto
2450 # Purpose: Saves the image
2451 # Param in: $savePath: Where to save the image including filename:
2452 # $imageQuality: image quality you want the image saved at 0-100
2455 # Notes: * gif doesn't have a quality parameter
2456 # * jpg has a quality setting 0-100 (100 being the best)
2457 # * png has a quality setting 0-9 (0 being the best)
2459 # * bmp files have no native support for bmp files. We use a
2460 # third party class to save as bmp.
2464 if (!is_resource($this->imageResized)) {
if ($this->debug) {
throw new Exception(
'saveImage: This is not a resource.'); }
else{
throw new Exception(); }}
2465 $fileInfoArray = pathInfo($savePath);
2467 if (!is_writable($fileInfoArray[
'dirname'])) {
if ($this->debug) {
throw new Exception(
'The path is not writable. Please check your permissions.'); }
else{
throw new Exception(); }}
2470 $extension = strrchr($savePath,
'.');
2479 $this->checkInterlaceImage($this->isInterlace);
2480 if (imagetypes() & IMG_JPG) {
2481 imagejpeg($this->imageResized, $savePath, $imageQuality);
2482 }
else {
$error =
'jpg'; }
2486 $this->checkInterlaceImage($this->isInterlace);
2487 if (imagetypes() & IMG_GIF) {
2488 imagegif($this->imageResized, $savePath);
2489 }
else {
$error =
'gif'; }
2494 $scaleQuality = round(($imageQuality/100) * 9);
2497 $invertScaleQuality = 9 - $scaleQuality;
2499 $this->checkInterlaceImage($this->isInterlace);
2500 if (imagetypes() & IMG_PNG) {
2501 imagepng($this->imageResized, $savePath, $invertScaleQuality);
2502 }
else {
$error =
'png'; }
2506 file_put_contents($savePath, $this->GD2BMPstring($this->imageResized));
2514 $this->errorArray[] =
'This file type (' . $extension .
') is not supported. File not saved.';
2522 $this->errorArray[] =
$error .
' support is NOT enabled. File not saved.';
2526 ## --------------------------------------------------------
2528 public function displayImage($fileType =
'jpg', $imageQuality=
"100")
2529 # Author: Jarrod Oberto
2531 # Purpose: Display images directly to the browser
2532 # Param in: The image type you want to display
2539 if (!is_resource($this->imageResized)) {
if ($this->debug) {
throw new Exception(
'saveImage: This is not a resource.'); }
else{
throw new Exception(); }}
2545 header(
'Content-type: image/jpeg');
2546 imagejpeg($this->imageResized,
'', $imageQuality);
2549 header(
'Content-type: image/gif');
2550 imagegif($this->imageResized);
2553 header(
'Content-type: image/png');
2556 $scaleQuality = round(($imageQuality/100) * 9);
2559 $invertScaleQuality = 9 - $scaleQuality;
2561 imagepng($this->imageResized,
'', $invertScaleQuality);
2564 echo
'bmp file format is not supported.';
2578 ## --------------------------------------------------------
2580 public function setTransparency($bool)
2583 $this->keepTransparency = $bool;
2586 ## --------------------------------------------------------
2588 public function setFillColor($value)
2590 # Param in: (mixed) $value: (array) Could be an array of RGB
2591 # (str) Could be hex #ffffff or #fff, fff, ffffff
2593 # If the keepTransparency is set to false, then no transparency is to be used.
2594 # This is ideal when you want to save as jpg.
2596 # this method allows you to set the background color to use instead of
2600 $colorArray = $this->formatColor($value);
2601 $this->fillColorArray = $colorArray;
2604 ## --------------------------------------------------------
2606 public function setCropFromTop($value)
2609 $this->cropFromTopPercent = $value;
2612 ## --------------------------------------------------------
2614 public function testGDInstalled()
2615 # Author: Jarrod Oberto
2617 # Purpose: Test to see if GD is installed
2619 # Param out: (bool) True is gd extension loaded otherwise false
2624 if(extension_loaded(
'gd') && function_exists(
'gd_info'))
2626 $gdInstalled =
true;
2630 $gdInstalled =
false;
2633 return $gdInstalled;
2636 ## --------------------------------------------------------
2638 public function testEXIFInstalled()
2639 # Author: Jarrod Oberto
2641 # Purpose: Test to see if EXIF is installed
2643 # Param out: (bool) True is exif extension loaded otherwise false
2648 if(extension_loaded(
'exif'))
2650 $exifInstalled =
true;
2654 $exifInstalled =
false;
2657 return $exifInstalled;
2660 ## --------------------------------------------------------
2662 public function testIsImage(
$image)
2663 # Author: Jarrod Oberto
2665 # Purpose: Test if file is an image
2674 $fileIsImage =
true;
2678 $fileIsImage =
false;
2681 return $fileIsImage;
2684 ## --------------------------------------------------------
2686 public function testFunct()
2687 # Author: Jarrod Oberto
2689 # Purpose: Test Function
2699 ## --------------------------------------------------------
2701 public function setForceStretch($value)
2702 # Author: Jarrod Oberto
2705 # Param in: (bool) $value
2711 $this->forceStretch = $value;
2714 ## --------------------------------------------------------
2717 # Author: Jarrod Oberto
2729 ## --------------------------------------------------------
2731 public function getFileName()
2732 # Author: Jarrod Oberto
2744 ## --------------------------------------------------------
2746 public function getHeight()
2751 ## --------------------------------------------------------
2753 public function getWidth()
2758 ## --------------------------------------------------------
2760 public function getOriginalHeight()
2765 ## --------------------------------------------------------
2767 public function getOriginalWidth()
2772 ## --------------------------------------------------------
2774 public function getErrors()
2775 # Author: Jarrod Oberto
2777 # Purpose: Returns the error array
2779 # Param out: Array of errors
2787 ## --------------------------------------------------------
2789 private function checkInterlaceImage($isEnabled)
2790 # jpg will use progressive (they don't use interace)
2793 imageinterlace($this->imageResized, $isEnabled);
2797 ## --------------------------------------------------------
2799 protected function formatColor($value)
2800 # Author: Jarrod Oberto
2802 # Purpose: Determine color method passed in and return color as RGB
2803 # Param in: (mixed) $value: (array) Could be an array of RGB
2804 # (str) Could be hex #ffffff or #fff, fff, ffffff
2810 $rgbArray = array();
2813 if (is_array($value)) {
2815 if (key($value) == 0 && count($value) == 3) {
2817 $rgbArray[
'r'] = $value[0];
2818 $rgbArray[
'g'] = $value[1];
2819 $rgbArray[
'b'] = $value[2];
2836 $rgbArray = $this -> hex2dec($value);
2842 ## --------------------------------------------------------
2844 function hex2dec($hex)
2845 # Purpose: Convert #hex color to RGB
2847 $color = str_replace(
'#',
'', $hex);
2849 if (strlen($color) == 3) {
2850 $color = $color . $color;
2854 'r' => hexdec(substr($color, 0, 2)),
2855 'g' => hexdec(substr($color, 2, 2)),
2856 'b' => hexdec(substr($color, 4, 2)),
2862 ## --------------------------------------------------------
2864 private function createImageColor ($colorArray)
2866 $r = $colorArray[
'r'];
2867 $g = $colorArray[
'g'];
2868 $b = $colorArray[
'b'];
2870 return imagecolorallocate($this->imageResized, $r, $g, $b);
2873 ## --------------------------------------------------------
2875 private function testColorExists($colorArray)
2877 $r = $colorArray[
'r'];
2878 $g = $colorArray[
'g'];
2879 $b = $colorArray[
'b'];
2881 if (imagecolorexact($this->imageResized, $r, $g, $b) == -1) {
2888 ## --------------------------------------------------------
2890 private function findUnusedGreen()
2891 # Purpose: We find a green color suitable to use like green-screen effect.
2892 # Therefore, the color must not exist in the image.
2898 $greenChroma = array(0, $green, 0);
2899 $colorArray = $this->formatColor($greenChroma);
2900 $match = $this->testColorExists($colorArray);
2903 }
while ($match ==
false && $green > 0);
2907 $greenChroma = array(0, $green, 0);
2910 return $greenChroma;
2913 ## --------------------------------------------------------
2915 private function findUnusedBlue()
2916 # Purpose: We find a green color suitable to use like green-screen effect.
2917 # Therefore, the color must not exist in the image.
2923 $blueChroma = array(0, 0, $blue);
2924 $colorArray = $this->formatColor($blueChroma);
2925 $match = $this->testColorExists($colorArray);
2928 }
while ($match ==
false && $blue > 0);
2932 $blueChroma = array(0, 0, $blue);
2938 ## --------------------------------------------------------
2940 private function invertTransparency($value, $originalMax, $invert=
true)
2941 # Purpose: This does two things:
2942 # 1) Convert the range from 0-127 to 0-100
2943 # 2) Inverts value to 100 is not transparent while 0 is fully
2944 # transparent (like Photoshop)
2947 if ($value > $originalMax) {
2948 $value = $originalMax;
2957 return $originalMax - (($value/100) * $originalMax);
2959 return ($value/100) * $originalMax;
2963 ## --------------------------------------------------------
2965 private function transparentImage($src)
2971 for ($x = 0; $x < imagesx($src); ++$x) {
2972 for ($y = 0; $y < imagesy($src); ++$y) {
2973 $color = imagecolorat($src, $x, $y);
2974 $r = ($color >> 16) & 0xFF;
2975 $g = ($color >> 8) & 0xFF;
2977 for (
$i = 0;
$i < 270;
$i++) {
2979 if ($r == 0 && $g == 255 && $b == 0) {
2981 $trans_colour = imagecolorallocatealpha($src, 0, 0, 0, 127);
2982 imagefill($src, $x, $y, $trans_colour);
2991 ## --------------------------------------------------------
2993 function checkStringStartsWith($needle, $haystack)
2994 # Check if a string starts with a specific pattern
2996 return (substr($haystack, 0, strlen($needle))==$needle);
3004 private function GD2BMPstring(&$gd_image)
3005 # Author: James Heinrich
3006 # Purpose: Save file as type bmp
3007 # Param in: The image canvas (passed as ref)
3010 # Notes: This code was stripped out of two external files
3011 # (phpthumb.bmp.php,phpthumb.functions.php) and added below to
3012 # avoid dependancies.
3015 $imageX = ImageSX($gd_image);
3016 $imageY = ImageSY($gd_image);
3019 for ($y = ($imageY - 1); $y >= 0; $y--) {
3021 for ($x = 0; $x < $imageX; $x++) {
3022 $argb = $this->GetPixelColor($gd_image, $x, $y);
3023 $thisline .= chr($argb[
'blue']).chr($argb[
'green']).chr($argb[
'red']);
3025 while (strlen($thisline) % 4) {
3026 $thisline .=
"\x00";
3031 $bmpSize = strlen($BMP) + 14 + 40;
3033 $BITMAPFILEHEADER =
'BM';
3034 $BITMAPFILEHEADER .= $this->LittleEndian2String($bmpSize, 4);
3035 $BITMAPFILEHEADER .= $this->LittleEndian2String( 0, 2);
3036 $BITMAPFILEHEADER .= $this->LittleEndian2String( 0, 2);
3037 $BITMAPFILEHEADER .= $this->LittleEndian2String( 54, 4);
3040 $BITMAPINFOHEADER = $this->LittleEndian2String( 40, 4);
3041 $BITMAPINFOHEADER .= $this->LittleEndian2String( $imageX, 4);
3042 $BITMAPINFOHEADER .= $this->LittleEndian2String( $imageY, 4);
3043 $BITMAPINFOHEADER .= $this->LittleEndian2String( 1, 2);
3044 $BITMAPINFOHEADER .= $this->LittleEndian2String( 24, 2);
3045 $BITMAPINFOHEADER .= $this->LittleEndian2String( 0, 4);
3046 $BITMAPINFOHEADER .= $this->LittleEndian2String( 0, 4);
3047 $BITMAPINFOHEADER .= $this->LittleEndian2String( 2835, 4);
3048 $BITMAPINFOHEADER .= $this->LittleEndian2String( 2835, 4);
3049 $BITMAPINFOHEADER .= $this->LittleEndian2String( 0, 4);
3050 $BITMAPINFOHEADER .= $this->LittleEndian2String( 0, 4);
3052 return $BITMAPFILEHEADER.$BITMAPINFOHEADER.$BMP;
3055 ## --------------------------------------------------------
3057 private function GetPixelColor(&$img, $x, $y)
3058 # Author: James Heinrich
3066 if (!is_resource($img)) {
3069 return @ImageColorsForIndex($img, @ImageColorAt($img, $x, $y));
3072 ## --------------------------------------------------------
3074 private function LittleEndian2String($number, $minbytes=1)
3075 # Author: James Heinrich
3076 # Purpose: BMP SUPPORT (SAVING)
3084 while ($number > 0) {
3085 $intstring = $intstring.chr($number & 255);
3088 return str_pad($intstring, $minbytes,
"\x00", STR_PAD_RIGHT);
3096 private function ImageCreateFromBMP($filename)
3098 # Date: The 15th of June 2005
3100 # Purpose: To create an image from a BMP file.
3101 # Param in: BMP file to open.
3102 # Param out: Return a resource like the other ImageCreateFrom functions
3103 # Reference: http://us3.php.net/manual/en/function.imagecreate.php#53879
3104 # Bug fix: Author: domelca at terra dot es
3105 # Date: 06 March 2008
3106 # Fix: Correct 16bit BMP support
3112 if (! $f1 = fopen($filename,
"rb"))
return FALSE;
3115 $FILE = unpack(
"vfile_type/Vfile_size/Vreserved/Vbitmap_offset", fread($f1,14));
3116 if ($FILE[
'file_type'] != 19778)
return FALSE;
3119 $BMP = unpack(
'Vheader_size/Vwidth/Vheight/vplanes/vbits_per_pixel'.
3120 '/Vcompression/Vsize_bitmap/Vhoriz_resolution'.
3121 '/Vvert_resolution/Vcolors_used/Vcolors_important', fread($f1,40));
3122 $BMP[
'colors'] = pow(2,$BMP[
'bits_per_pixel']);
3124 if ($BMP[
'size_bitmap'] == 0) $BMP[
'size_bitmap'] = $FILE[
'file_size'] - $FILE[
'bitmap_offset'];
3126 $BMP[
'bytes_per_pixel'] = $BMP[
'bits_per_pixel']/8;
3127 $BMP[
'bytes_per_pixel2'] = ceil($BMP[
'bytes_per_pixel']);
3128 $BMP[
'decal'] = ($BMP[
'width']*$BMP[
'bytes_per_pixel']/4);
3129 $BMP[
'decal'] -= floor($BMP[
'width']*$BMP[
'bytes_per_pixel']/4);
3130 $BMP[
'decal'] = 4-(4*$BMP[
'decal']);
3132 if ($BMP[
'decal'] == 4) $BMP[
'decal'] = 0;
3136 if ($BMP[
'colors'] < 16777216)
3138 $PALETTE = unpack(
'V'.$BMP[
'colors'], fread($f1,$BMP[
'colors']*4));
3142 $IMG = fread($f1,$BMP[
'size_bitmap']);
3145 $res = imagecreatetruecolor($BMP[
'width'],$BMP[
'height']);
3147 $Y = $BMP[
'height']-1;
3151 while ($X < $BMP[
'width'])
3153 if ($BMP[
'bits_per_pixel'] == 24)
3154 $COLOR = unpack(
"V",substr($IMG,$P,3).$VIDE);
3155 elseif ($BMP[
'bits_per_pixel'] == 16)
3174 $COLOR = unpack(
"v",substr($IMG,$P,2));
3175 $blue = ($COLOR[1] & 0x001f) << 3;
3176 $green = ($COLOR[1] & 0x07e0) >> 3;
3177 $red = ($COLOR[1] & 0xf800) >> 8;
3178 $COLOR[1] = $red * 65536 + $green * 256 + $blue;
3181 elseif ($BMP[
'bits_per_pixel'] == 8)
3183 $COLOR = unpack(
"n",$VIDE.substr($IMG,$P,1));
3184 $COLOR[1] = $PALETTE[$COLOR[1]+1];
3186 elseif ($BMP[
'bits_per_pixel'] == 4)
3188 $COLOR = unpack(
"n",$VIDE.substr($IMG,floor($P),1));
3189 if (($P*2)%2 == 0) $COLOR[1] = ($COLOR[1] >> 4) ;
else $COLOR[1] = ($COLOR[1] & 0x0F);
3190 $COLOR[1] = $PALETTE[$COLOR[1]+1];
3192 elseif ($BMP[
'bits_per_pixel'] == 1)
3194 $COLOR = unpack(
"n",$VIDE.substr($IMG,floor($P),1));
3195 if (($P*8)%8 == 0) $COLOR[1] = $COLOR[1] >>7;
3196 elseif (($P*8)%8 == 1) $COLOR[1] = ($COLOR[1] & 0x40)>>6;
3197 elseif (($P*8)%8 == 2) $COLOR[1] = ($COLOR[1] & 0x20)>>5;
3198 elseif (($P*8)%8 == 3) $COLOR[1] = ($COLOR[1] & 0x10)>>4;
3199 elseif (($P*8)%8 == 4) $COLOR[1] = ($COLOR[1] & 0x8)>>3;
3200 elseif (($P*8)%8 == 5) $COLOR[1] = ($COLOR[1] & 0x4)>>2;
3201 elseif (($P*8)%8 == 6) $COLOR[1] = ($COLOR[1] & 0x2)>>1;
3202 elseif (($P*8)%8 == 7) $COLOR[1] = ($COLOR[1] & 0x1);
3203 $COLOR[1] = $PALETTE[$COLOR[1]+1];
3208 imagesetpixel(
$res,$X,$Y,$COLOR[1]);
3210 $P += $BMP['bytes_per_pixel'];
3227 private function imagecreatefrompsd(
$fileName)
3228 # Author: Tim de Koning
3230 # Purpose: To create an image from a PSD file.
3231 # Param in: PSD file to open.
3232 # Param out: Return a resource like the other ImageCreateFrom functions
3233 # Reference: http://www.kingsquare.nl/phppsdreader
3237 if (file_exists($this->psdReaderPath)) {
3240 include_once($this->psdReaderPath);
3242 $psdReader =
new PhpPsdReader(
$fileName);
3244 if (isset($psdReader->infoArray[
'error']))
return '';
3245 else return $psdReader->getImage();
3251 ## --------------------------------------------------------
3253 public function __destruct() {
3254 if (is_resource($this->imageResized)) {
3255 imagedestroy($this->imageResized);
3259 ## --------------------------------------------------------
if(empty($settings['ROOT_PATH'])) elseif(empty($settings['DB_PARAMETERS'])) $error
getOptimalCrop($newWidth, $newHeight)#Author
if(!$dbm->isConnectable()) $res
if(!isset($xoops->paths[$path_type])) if($path_type== 'var') $file
getSizeByAuto($newWidth, $newHeight)#Author
keepTransparancy($width, $height, $im)#Author
getSizeByFixedWidth($newWidth, $newHeight)
__construct($fileName)#Author
getSizeByFixedHeight($newWidth, $newHeight)
if($xoops->isActiveModule('images')) return false
if($xoops->isUser()) else
getCropPlacing($optimalWidth, $optimalHeight, $newWidth, $newHeight, $pos='m')##Author
resizeImage($newWidth, $newHeight, $option=0, $sharpen=false, $autoRotate=false)#Author
cropImage($newWidth, $newHeight, $cropPos= 'm')#Author
getDimensions($newWidth, $newHeight, $option)#Author
crop($optimalWidth, $optimalHeight, $newWidth, $newHeight, $cropPos)#Author