Completed
Push — master ( 02f2d8...e7d60a )
by Michael
02:40
created

imageLib::getOriginalHeight()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
   # ========================================================================#
3
   #
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,
8
   #  94041, USA.
9
   #
10
   #  All rights reserved.
11
   #
12
   #  Author:    Jarrod Oberto
13
   #  Version:   1.5.1
14
   #  Date:      10-05-11
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.
19
   #  Usage Example:
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);
24
   #
25
   #        - See end of doc for more examples -
26
   #
27
   #  Supported file types include: jpg, png, gif, bmp, psd (read)
28
   #
29
   #
30
   #
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.
34
   #    - GD2BMPstring
35
   #      - GetPixelColor
36
   #      - LittleEndian2String
37
   #
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.
41
   #    -
42
   #
43
   #  PhpPsdReader is used with written permission from Tim de Koning.
44
   #  [http://www.kingsquare.nl/phppsdreader]
45
   #
46
   #
47
   #
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
54
   #              * Added shadow
55
   #              * Added caption box
56
   #              * Added vintage filter
57
   #              * Added dynamic image resizing (resize on the fly)
58
   #              * minor bug fixes
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
61
   #              * Minor bug fixes
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
74
   #                cropping.
75
   #  17-09-11  J.C.O     * Added setCropFromTop() set method - set the
76
   #                percentage to crop from the top when using
77
   #                crop 'auto' option.
78
   #              * Added setTransparency() set method - allows you
79
   #                to turn transparency off (like when saving
80
   #                as a jpg).
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
84
   #  0-07-12  J.C.O   1.0
85
   #
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))
92
   #
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.
96
   #
97
   #  $forceStretch:
98
   # -------------------------------
99
   #  On by default.
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.
104
   #
105
   #  If enabled, images smaller than the size specified will be stretched to
106
   #  that size.
107
   #
108
   #  Tips:
109
   # -------------------------------
110
   #  * If you're resizing a transparent png and saving it as a jpg, set
111
   #  $keepTransparency to false with: $magicianObj->setTransparency(false);
112
   #
113
   #  FEATURES:
114
   #    * EASY TO USE
115
   #    * BMP SUPPORT (read & write)
116
   #    * PSD (photoshop) support (read)
117
   #    * RESIZE IMAGES
118
   #      - Preserve transparency (png, gif)
119
   #      - Apply sharpening (jpg) (requires PHP >= 5.1.0)
120
   #      - Set image quality (jpg, png)
121
   #      - Resize modes:
122
   #        - exact size
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)
128
   #    * APPLY FILTERS
129
   #      - Convert to grey scale
130
   #      - Convert to black and white
131
   #      - Convert to sepia
132
   #      - Convert to negative
133
   #    * ROTATE IMAGES
134
   #      - Rotate using predefined "left", "right", or "180"; or any custom degree amount
135
   #    * EXTRACT EXIF DATA (requires exif module)
136
   #      - make
137
   #      - model
138
   #      - date
139
   #      - exposure
140
   #      - aperture
141
   #      - f-stop
142
   #      - iso
143
   #      - focal length
144
   #      - exposure program
145
   #      - metering mode
146
   #      - flash status
147
   #      - creator
148
   #      - copyright
149
   #    * ADD WATERMARK
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).
155
   #    * ADD BORDER
156
   #    * USE HEX WHEN SPECIFYING COLORS (eg: #ffffff)
157
   #    * SAVE IMAGE OR OUTPUT TO SCREEN
158
   #
159
   #
160
   # ========================================================================#
161
162
163
class imageLib
164
{
165
166
    private $fileName;
167
    private $image;
168
    protected $imageResized;
169
    private $widthOriginal;     # Always be the original width
170
    private $heightOriginal;
171
    private $width;         # Current width (width after resize)
172
    private $height;
173
    private $imageSize;
174
  private $fileExtension;
175
176
  private $debug = true;
177
  private $errorArray = array();
178
179
  private $forceStretch = true;
180
  private $aggresiveSharpening = false;
181
182
  private $transparentArray = array('.png', '.gif');
183
  private $keepTransparency = true;
184
  private $fillColorArray = array('r'=>255, 'g'=>255, 'b'=>255);
185
186
  private $sharpenArray = array('jpg');
187
188
  private $psdReaderPath;
189
  private $filterOverlayPath;
190
191
  private $isInterlace;
192
193
  private $captionBoxPositionArray = array();
194
195
  private $fontDir = 'fonts';
196
197
  private $cropFromTopPercent = 10;
198
199
## --------------------------------------------------------
200
201
    function __construct($fileName)
202
    # Author:     Jarrod Oberto
203
  # Date:     27-02-08
204
    # Purpose:    Constructor
205
    # Param in:   $fileName: File name and path.
206
    # Param out:  n/a
207
    # Reference:
208
    # Notes:
209
    #
210
    {
211
    if (!$this->testGDInstalled()) { if ($this->debug) { throw new Exception('The GD Library is not installed.'); }else{ throw new Exception(); }};
212
213
    $this->initialise();
214
215
        // *** Save the image file name. Only store this incase you want to display it
216
        $this->fileName = $fileName;
217
    $this->fileExtension = fix_strtolower(strrchr($fileName, '.'));
218
219
        // *** Open up the file
220
        $this->image = $this->openImage($fileName);
221
222
    // *** Assign here so we don't modify the original
223
    $this->imageResized = $this->image;
224
225
        // *** If file is an image
226
        if ($this->testIsImage($this->image))
227
        {
228
            // *** Get width and height
229
            $this->width  = imagesx($this->image);
230
            $this->widthOriginal = imagesx($this->image);
231
            $this->height = imagesy($this->image);
232
            $this->heightOriginal = imagesy($this->image);
233
234
        /*  Added 15-09-08
235
         *  Get the filesize using this build in method.
236
         *  Stores an array of size
237
         *
238
         *  $this->imageSize[1] = width
239
         *  $this->imageSize[2] = height
240
         *  $this->imageSize[3] = width x height
241
         *
242
         */
243
            $this->imageSize = getimagesize($this->fileName);
244
245
        } else {
246
      $this->errorArray[] = 'File is not an image';
247
    }
248
    }
249
250
## --------------------------------------------------------
251
252
  private function initialise () {
253
254
    $this->psdReaderPath = __DIR__ . '/classPhpPsdReader.php';
255
    $this->filterOverlayPath = __DIR__ . '/filters';
256
257
    // *** Set if image should be interlaced or not.
258
    $this->isInterlace = false;
259
  }
260
261
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*-
262
  Resize
263
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*/
264
265
    public function resizeImage($newWidth, $newHeight, $option = 0, $sharpen = false, $autoRotate = false)
266
    # Author:     Jarrod Oberto
267
    # Date:       27-02-08
268
    # Purpose:    Resizes the image
269
    # Param in:   $newWidth:
270
    #             $newHeight:
271
    #             $option:     0 / exact = defined size;
272
    #                          1 / portrait = keep aspect set height;
273
    #                          2 / landscape = keep aspect set width;
274
    #                          3 / auto = auto;
275
  #                          4 / crop= resize and crop;
276
  #
277
  #         $option can also be an array containing options for
278
  #         cropping. E.G., array('crop', 'r')
279
  #
280
  #         This array only applies to 'crop' and the 'r' refers to
281
  #         "crop right". Other value include; tl, t, tr, l, m (default),
282
  #         r, bl, b, br, or you can specify your own co-ords (which
283
  #         isn't recommended.
284
  #
285
  #       $sharpen:    true: sharpen (jpg only);
286
  #                false: don't sharpen
287
    # Param out:  n/a
288
    # Reference:
289
    # Notes:      To clarify the $option input:
290
    #               0 = The exact height and width dimensions you set.
291
    #               1 = Whatever height is passed in will be the height that
292
    #                   is set. The width will be calculated and set automatically
293
    #                   to a the value that keeps the original aspect ratio.
294
    #               2 = The same but based on the width. We try make the image the
295
  #                  biggest size we can while stil fitting inside the box size
296
    #               3 = Depending whether the image is landscape or portrait, this
297
    #                   will automatically determine whether to resize via
298
    #                   dimension 1,2 or 0
299
  #               4 = Will resize and then crop the image for best fit
300
  #
301
  #       forceStretch can be applied to options 1,2,3 and 4
302
    #
303
    {
304
305
    // *** We can pass in an array of options to change the crop position
306
    $cropPos = 'm';
307
    if (is_array($option) && fix_strtolower($option[0]) == 'crop') {
308
      $cropPos = $option[1];         # get the crop option
309
    } else if (strpos($option, '-') !== false) {
310
      // *** Or pass in a hyphen seperated option
311
      $optionPiecesArray = explode('-', $option);
312
      $cropPos = end($optionPiecesArray);
313
    }
314
315
    // *** Check the option is valid
316
    $option = $this->prepOption($option);
317
318
    // *** Make sure the file passed in is valid
319
    if (!$this->image) { if ($this->debug) { throw new Exception('file ' . $this->getFileName() .' is missing or invalid'); }else{ throw new Exception(); }};
320
321
    // *** Get optimal width and height - based on $option
322
    $dimensionsArray = $this->getDimensions($newWidth, $newHeight, $option);
323
324
    $optimalWidth  = $dimensionsArray['optimalWidth'];
325
    $optimalHeight = $dimensionsArray['optimalHeight'];
326
327
    // *** Resample - create image canvas of x, y size
328
    $this->imageResized = imagecreatetruecolor($optimalWidth, $optimalHeight);
329
    $this->keepTransparancy($optimalWidth, $optimalHeight, $this->imageResized);
330
    imagecopyresampled($this->imageResized, $this->image, 0, 0, 0, 0, $optimalWidth, $optimalHeight, $this->width, $this->height);
331
332
    // *** If '4', then crop too
333
    if ($option == 4 || $option == 'crop') {
334
335
      if (($optimalWidth >= $newWidth && $optimalHeight >= $newHeight)) {
336
        $this->crop($optimalWidth, $optimalHeight, $newWidth, $newHeight, $cropPos);
337
      }
338
    }
339
340
    // *** If Rotate.
341
    if ($autoRotate) {
342
343
      $exifData = $this->getExif(false);
344
      if (count($exifData) > 0) {
345
346
        switch($exifData['orientation']) {
347
            case 8:
348
                $this->imageResized = imagerotate($this->imageResized,90,0);
349
                break;
350
            case 3:
351
                $this->imageResized = imagerotate($this->imageResized,180,0);
352
                break;
353
            case 6:
354
                $this->imageResized = imagerotate($this->imageResized,-90,0);
355
                break;
356
        }
357
      }
358
    }
359
360
    // *** Sharpen image (if jpg and the user wishes to do so)
361
    if ($sharpen && in_array($this->fileExtension, $this->sharpenArray)) {
362
363
      // *** Sharpen
364
      $this->sharpen();
365
    }
366
    }
367
368
## --------------------------------------------------------
369
370
  public function cropImage($newWidth, $newHeight, $cropPos = 'm')
371
    # Author:     Jarrod Oberto
372
    # Date:       08-09-11
373
    # Purpose:    Crops the image
374
    # Param in:   $newWidth: crop with
375
    #             $newHeight: crop height
376
  #       $cropPos: Can be any of the following:
377
  #             tl, t, tr, l, m, r, bl, b, br, auto
378
  #           Or:
379
  #             a custom position such as '30x50'
380
    # Param out:  n/a
381
    # Reference:
382
    # Notes:
383
    #
384
  {
385
386
    // *** Make sure the file passed in is valid
387
    if (!$this->image) { if ($this->debug) { throw new Exception('file ' . $this->getFileName() .' is missing or invalid'); }else{ throw new Exception(); }};
388
389
    $this->imageResized = $this->image;
390
    $this->crop($this->width, $this->height, $newWidth, $newHeight, $cropPos);
391
392
  }
393
394
## --------------------------------------------------------
395
396
  private function keepTransparancy($width, $height, $im)
397
    # Author:     Jarrod Oberto
398
    # Date:       08-04-11
399
    # Purpose:    Keep transparency for png and gif image
400
    # Param in:
401
    # Param out:  n/a
402
    # Reference:
403
    # Notes:
404
    #
405
  {
406
    // *** If PNG, perform some transparency retention actions (gif untested)
407
    if (in_array($this->fileExtension, $this->transparentArray) && $this->keepTransparency) {
408
      imagealphablending($im, false);
409
      imagesavealpha($im, true);
410
      $transparent = imagecolorallocatealpha($im, 255, 255, 255, 127);
411
      imagefilledrectangle($im, 0, 0, $width, $height, $transparent);
412
    } else {
413
      $color = imagecolorallocate($im, $this->fillColorArray['r'], $this->fillColorArray['g'], $this->fillColorArray['b']);
414
      imagefilledrectangle($im, 0, 0, $width, $height, $color);
415
    }
416
  }
417
418
## --------------------------------------------------------
419
420
    private function crop($optimalWidth, $optimalHeight, $newWidth, $newHeight, $cropPos)
421
    # Author:     Jarrod Oberto
422
    # Date:       15-09-08
423
    # Purpose:    Crops the image
424
    # Param in:   $newWidth:
425
    #             $newHeight:
426
    # Param out:  n/a
427
    # Reference:
428
    # Notes:
429
    #
430
    {
431
432
    // *** Get cropping co-ordinates
433
    $cropArray = $this->getCropPlacing($optimalWidth, $optimalHeight, $newWidth, $newHeight, $cropPos);
434
    $cropStartX = $cropArray['x'];
435
    $cropStartY = $cropArray['y'];
436
437
    // *** Crop this bad boy
438
    $crop = imagecreatetruecolor($newWidth , $newHeight);
439
    $this->keepTransparancy($optimalWidth, $optimalHeight, $crop);
440
    imagecopyresampled($crop, $this->imageResized, 0, 0, $cropStartX, $cropStartY, $newWidth, $newHeight , $newWidth, $newHeight);
441
442
    $this->imageResized = $crop;
443
444
    // *** Set new width and height to our variables
445
    $this->width = $newWidth;
446
    $this->height = $newHeight;
447
448
    }
449
450
## --------------------------------------------------------
451
452
  private function getCropPlacing($optimalWidth, $optimalHeight, $newWidth, $newHeight, $pos='m')
453
  #
454
  # Author:   Jarrod Oberto
455
  # Date:   July 11
456
  # Purpose:  Set the cropping area.
457
  # Params in:
458
  # Params out: (array) the crop x and y co-ordinates.
459
  # Notes:    When specifying the exact pixel crop position (eg 10x15), be
460
  #       very careful as it's easy to crop out of the image leaving
461
  #       black borders.
462
  #
463
  {
464
    $pos = fix_strtolower($pos);
465
466
    // *** If co-ords have been entered
467
    if (strstr($pos, 'x')) {
468
      $pos = str_replace(' ', '', $pos);
469
470
      $xyArray = explode('x', $pos);
471
      list($cropStartX, $cropStartY) = $xyArray;
472
473
    } else {
474
475
      switch ($pos) {
476
        case 'tl':
477
          $cropStartX = 0;
478
          $cropStartY = 0;
479
          break;
480
481
        case 't':
482
          $cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 );
483
          $cropStartY = 0;
484
          break;
485
486
        case 'tr':
487
          $cropStartX = $optimalWidth - $newWidth;
488
          $cropStartY = 0;
489
          break;
490
491
        case 'l':
492
          $cropStartX = 0;
493
          $cropStartY = ( $optimalHeight/ 2) - ( $newHeight/2 );
494
          break;
495
496
        case 'm':
497
          $cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 );
498
          $cropStartY = ( $optimalHeight/ 2) - ( $newHeight/2 );
499
          break;
500
501
        case 'r':
502
          $cropStartX = $optimalWidth - $newWidth;
503
          $cropStartY = ( $optimalHeight/ 2) - ( $newHeight/2 );
504
          break;
505
506
        case 'bl':
507
          $cropStartX = 0;
508
          $cropStartY = $optimalHeight - $newHeight;
509
          break;
510
511
        case 'b':
512
          $cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 );
513
          $cropStartY = $optimalHeight - $newHeight;
514
          break;
515
516
        case 'br':
517
          $cropStartX = $optimalWidth - $newWidth;
518
          $cropStartY = $optimalHeight - $newHeight;
519
          break;
520
521
        case 'auto':
522
          // *** If image is a portrait crop from top, not center. v1.5
523
          if ($optimalHeight > $optimalWidth) {
524
            $cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 );
525
            $cropStartY = ($this->cropFromTopPercent /100) * $optimalHeight;
526
          } else {
527
528
            // *** Else crop from the center
529
            $cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 );
530
            $cropStartY = ( $optimalHeight/ 2) - ( $newHeight/2 );
531
          }
532
          break;
533
534
        default:
535
          // *** Default to center
536
          $cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 );
537
          $cropStartY = ( $optimalHeight/ 2) - ( $newHeight/2 );
538
          break;
539
      }
540
    }
541
542
    return array('x' => $cropStartX, 'y' => $cropStartY);
543
  }
544
545
## --------------------------------------------------------
546
547
  private function getDimensions($newWidth, $newHeight, $option)
548
    # Author:     Jarrod Oberto
549
    # Date:       17-11-09
550
    # Purpose:    Get new image dimensions based on user specificaions
551
    # Param in:   $newWidth:
552
    #             $newHeight:
553
    # Param out:  Array of new width and height values
554
    # Reference:
555
    # Notes:    If $option = 3 then this function is call recursivly
556
  #
557
  #       To clarify the $option input:
558
    #               0 = The exact height and width dimensions you set.
559
    #               1 = Whatever height is passed in will be the height that
560
    #                   is set. The width will be calculated and set automatically
561
    #                   to a the value that keeps the original aspect ratio.
562
    #               2 = The same but based on the width.
563
    #               3 = Depending whether the image is landscape or portrait, this
564
    #                   will automatically determine whether to resize via
565
    #                   dimension 1,2 or 0.
566
  #               4 = Resize the image as much as possible, then crop the
567
  #         remainder.
568
  {
569
570
        switch (strval($option))
571
        {
572
            case '0':
573
      case 'exact':
574
                $optimalWidth = $newWidth;
575
                $optimalHeight= $newHeight;
576
                break;
577
            case '1':
578
      case 'portrait':
579
                $dimensionsArray = $this->getSizeByFixedHeight($newWidth, $newHeight);
580
        $optimalWidth = $dimensionsArray['optimalWidth'];
581
        $optimalHeight = $dimensionsArray['optimalHeight'];
582
                break;
583
            case '2':
584
      case 'landscape':
585
                $dimensionsArray = $this->getSizeByFixedWidth($newWidth, $newHeight);
586
        $optimalWidth = $dimensionsArray['optimalWidth'];
587
        $optimalHeight = $dimensionsArray['optimalHeight'];
588
                break;
589
            case '3':
590
      case 'auto':
591
                $dimensionsArray = $this->getSizeByAuto($newWidth, $newHeight);
592
        $optimalWidth = $dimensionsArray['optimalWidth'];
593
        $optimalHeight = $dimensionsArray['optimalHeight'];
594
                break;
595
      case '4':
596
      case 'crop':
597
                $dimensionsArray = $this->getOptimalCrop($newWidth, $newHeight);
598
        $optimalWidth = $dimensionsArray['optimalWidth'];
599
        $optimalHeight = $dimensionsArray['optimalHeight'];
600
                break;
601
        }
602
603
    return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
0 ignored issues
show
Bug introduced by
The variable $optimalWidth does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Bug introduced by
The variable $optimalHeight does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
604
  }
605
606
## --------------------------------------------------------
607
608
    private function getSizeByFixedHeight($newWidth, $newHeight)
0 ignored issues
show
Unused Code introduced by
The parameter $newWidth is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
609
    {
610
    // *** If forcing is off...
611
    if (!$this->forceStretch) {
612
613
      // *** ...check if actual height is less than target height
614
      if ($this->height < $newHeight) {
615
        return array('optimalWidth' => $this->width, 'optimalHeight' => $this->height);
616
      }
617
    }
618
619
        $ratio = $this->width / $this->height;
620
621
        $newWidth = $newHeight * $ratio;
622
623
        //return $newWidth;
624
    return array('optimalWidth' => $newWidth, 'optimalHeight' => $newHeight);
625
    }
626
627
## --------------------------------------------------------
628
629
    private function getSizeByFixedWidth($newWidth, $newHeight)
0 ignored issues
show
Unused Code introduced by
The parameter $newHeight is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
630
    {
631
    // *** If forcing is off...
632
    if (!$this->forceStretch) {
633
634
      // *** ...check if actual width is less than target width
635
      if ($this->width < $newWidth) {
636
        return array('optimalWidth' => $this->width, 'optimalHeight' => $this->height);
637
      }
638
    }
639
640
    $ratio = $this->height / $this->width;
641
642
        $newHeight = $newWidth * $ratio;
643
644
        //return $newHeight;
645
    return array('optimalWidth' => $newWidth, 'optimalHeight' => $newHeight);
646
    }
647
648
## --------------------------------------------------------
649
650
    private function getSizeByAuto($newWidth, $newHeight)
651
    # Author:     Jarrod Oberto
652
    # Date:       19-08-08
653
    # Purpose:    Depending on the height, choose to resize by 0, 1, or 2
654
    # Param in:   The new height and new width
655
    # Notes:
656
    #
657
    {
658
    // *** If forcing is off...
659
    if (!$this->forceStretch) {
660
661
      // *** ...check if actual size is less than target size
662
      if ($this->width < $newWidth && $this->height < $newHeight) {
663
        return array('optimalWidth' => $this->width, 'optimalHeight' => $this->height);
664
      }
665
    }
666
667
        if ($this->height < $this->width)
668
        // *** Image to be resized is wider (landscape)
669
        {
670
            //$optimalWidth = $newWidth;
671
            //$optimalHeight= $this->getSizeByFixedWidth($newWidth);
672
673
            $dimensionsArray = $this->getSizeByFixedWidth($newWidth, $newHeight);
674
      $optimalWidth = $dimensionsArray['optimalWidth'];
675
      $optimalHeight = $dimensionsArray['optimalHeight'];
676
        }
677
        elseif ($this->height > $this->width)
678
        // *** Image to be resized is taller (portrait)
679
        {
680
            //$optimalWidth = $this->getSizeByFixedHeight($newHeight);
681
            //$optimalHeight= $newHeight;
682
683
            $dimensionsArray = $this->getSizeByFixedHeight($newWidth, $newHeight);
684
      $optimalWidth = $dimensionsArray['optimalWidth'];
685
      $optimalHeight = $dimensionsArray['optimalHeight'];
686
        }
687
    else
688
        // *** Image to be resizerd is a square
689
        {
690
691
      if ($newHeight < $newWidth) {
692
          //$optimalWidth = $newWidth;
693
        //$optimalHeight= $this->getSizeByFixedWidth($newWidth);
694
                $dimensionsArray = $this->getSizeByFixedWidth($newWidth, $newHeight);
695
        $optimalWidth = $dimensionsArray['optimalWidth'];
696
        $optimalHeight = $dimensionsArray['optimalHeight'];
697
      } else if ($newHeight > $newWidth) {
698
          //$optimalWidth = $this->getSizeByFixedHeight($newHeight);
699
            //$optimalHeight= $newHeight;
700
                $dimensionsArray = $this->getSizeByFixedHeight($newWidth, $newHeight);
701
        $optimalWidth = $dimensionsArray['optimalWidth'];
702
        $optimalHeight = $dimensionsArray['optimalHeight'];
703
      } else {
704
        // *** Sqaure being resized to a square
705
        $optimalWidth = $newWidth;
706
        $optimalHeight= $newHeight;
707
      }
708
        }
709
710
    return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
711
    }
712
713
## --------------------------------------------------------
714
715
    private function getOptimalCrop($newWidth, $newHeight)
716
  # Author:     Jarrod Oberto
717
    # Date:       17-11-09
718
    # Purpose:    Get optimal crop dimensions
719
    # Param in:   width and height as requested by user (fig 3)
720
    # Param out:  Array of optimal width and height (fig 2)
721
    # Reference:
722
    # Notes:      The optimal width and height return are not the same as the
723
  #       same as the width and height passed in. For example:
724
  #
725
  #
726
  #   |-----------------|     |------------|       |-------|
727
  #   |             |   =>  |**|      |**|   =>  |       |
728
  #   |             |     |**|      |**|       |       |
729
    #   |           |       |------------|       |-------|
730
  #   |-----------------|
731
  #        original                optimal             crop
732
  #              size                   size               size
733
  #  Fig          1                      2                  3
734
  #
735
  #       300 x 250           150 x 125          150 x 100
736
  #
737
  #    The optimal size is the smallest size (that is closest to the crop size)
738
  #    while retaining proportion/ratio.
739
  #
740
  #  The crop size is the optimal size that has been cropped on one axis to
741
  #  make the image the exact size specified by the user.
742
  #
743
  #               * represent cropped area
744
  #
745
  {
746
747
    // *** If forcing is off...
748
    if (!$this->forceStretch) {
749
750
      // *** ...check if actual size is less than target size
751
      if ($this->width < $newWidth && $this->height < $newHeight) {
752
        return array('optimalWidth' => $this->width, 'optimalHeight' => $this->height);
753
      }
754
    }
755
756
    $heightRatio = $this->height / $newHeight;
757
    $widthRatio  = $this->width /  $newWidth;
758
759
    if ($heightRatio < $widthRatio) {
760
      $optimalRatio = $heightRatio;
761
    } else {
762
      $optimalRatio = $widthRatio;
763
    }
764
765
    $optimalHeight = round( $this->height / $optimalRatio );
766
    $optimalWidth  = round( $this->width  / $optimalRatio );
767
768
    return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
769
  }
770
771
## --------------------------------------------------------
772
773
  private function sharpen()
774
    # Author:     Jarrod Oberto
775
    # Date:       08 04 2011
776
    # Purpose:    Sharpen image
777
    # Param in:   n/a
778
    # Param out:  n/a
779
    # Reference:
780
    # Notes:
781
    # Credit:   Incorporates Joe Lencioni (August 6, 2008) code
782
  {
783
784
    if (version_compare(PHP_VERSION, '5.1.0') >= 0) {
785
786
      // ***
787
      if ($this->aggresiveSharpening) { # A more aggressive sharpening solution
788
789
        $sharpenMatrix = array( array( -1, -1, -1 ),
790
                         array( -1, 16, -1 ),
791
                         array( -1, -1, -1 ) );
792
        $divisor = 8;
793
        $offset = 0;
794
795
        imageconvolution($this->imageResized, $sharpenMatrix, $divisor, $offset);
796
      }
797
      else # More subtle and personally more desirable
798
      {
799
        $sharpness  = $this->findSharp($this->widthOriginal, $this->width);
800
801
        $sharpenMatrix  = array(
802
          array(-1, -2, -1),
803
          array(-2, $sharpness + 12, -2), //Lessen the effect of a filter by increasing the value in the center cell
804
          array(-1, -2, -1)
805
        );
806
        $divisor    = $sharpness; // adjusts brightness
807
        $offset     = 0;
808
        imageconvolution($this->imageResized, $sharpenMatrix, $divisor, $offset);
809
      }
810
    }
811
    else
812
    {
813
      if ($this->debug) { throw new Exception('Sharpening required PHP 5.1.0 or greater.'); }
814
    }
815
  }
816
817
  ## --------------------------------------------------------
818
819
  private function sharpen2($level)
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
820
  {
821
      $sharpenMatrix  = array(
0 ignored issues
show
Unused Code introduced by
$sharpenMatrix is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
822
        array($level, $level, $level),
823
        array($level, (8*$level)+1, $level), //Lessen the effect of a filter by increasing the value in the center cell
824
        array($level, $level, $level)
825
      );
826
827
  }
828
829
## --------------------------------------------------------
830
831
  private function findSharp($orig, $final)
832
    # Author:     Ryan Rud (http://adryrun.com)
833
    # Purpose:    Find optimal sharpness
834
    # Param in:   n/a
835
    # Param out:  n/a
836
    # Reference:
837
    # Notes:
838
    #
839
  {
840
    $final  = $final * (750.0 / $orig);
841
    $a    = 52;
842
    $b    = -0.27810650887573124;
843
    $c    = .00047337278106508946;
844
845
    $result = $a + $b * $final + $c * $final * $final;
846
847
    return max(round($result), 0);
848
  }
849
850
## --------------------------------------------------------
851
852
  private function prepOption($option)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
853
    # Author:     Jarrod Oberto
854
    # Purpose:    Prep option like change the passed in option to lowercase
855
    # Param in:   (str/int) $option: eg. 'exact', 'crop'. 0, 4
856
    # Param out:  lowercase string
857
    # Reference:
858
    # Notes:
859
    #
860
  {
861
    if (is_array($option)) {
862
      if (fix_strtolower($option[0]) == 'crop' && count($option) == 2) {
863
        return 'crop';
864
      } else {
865
        throw new Exception('Crop resize option array is badly formatted.');
866
      }
867
    } else if (strpos($option, 'crop') !== false) {
868
      return 'crop';
869
    }
870
871
    if (is_string($option)) {
872
      return fix_strtolower($option);
873
    }
874
875
    return $option;
876
  }
877
878
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*-
879
  Presets
880
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*/
881
882
#
883
# Preset are pre-defined templates you can apply to your image.
884
#
885
# These are inteded to be applied to thumbnail images.
886
#
887
888
889
  public function borderPreset($preset)
890
  {
891
    switch ($preset)
892
    {
893
894
      case 'simple':
895
        $this->addBorder(7, '#fff');
0 ignored issues
show
Documentation introduced by
'#fff' is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
896
        $this->addBorder(6, '#f2f1f0');
0 ignored issues
show
Documentation introduced by
'#f2f1f0' is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
897
        $this->addBorder(2, '#fff');
0 ignored issues
show
Documentation introduced by
'#fff' is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
898
        $this->addBorder(1, '#ccc');
0 ignored issues
show
Documentation introduced by
'#ccc' is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
899
        break;
900
      default:
901
        break;
902
    }
903
904
  }
905
906
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*-
907
  Draw border
908
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*/
909
910
  public function addBorder($thickness = 1, $rgbArray = array(255, 255, 255))
911
    # Author:     Jarrod Oberto
912
    # Date:       05-05-11
913
    # Purpose:    Add a border to the image
914
    # Param in:
915
    # Param out:
916
    # Reference:
917
    # Notes:    This border is added to the INSIDE of the image
918
    #
919
  {
920
    if ($this->imageResized) {
921
922
      $rgbArray = $this->formatColor($rgbArray);
923
      $r = $rgbArray['r'];
924
      $g = $rgbArray['g'];
925
      $b = $rgbArray['b'];
926
927
      $x1 = 0;
928
      $y1 = 0;
929
      $x2 = ImageSX($this->imageResized) - 1;
930
      $y2 = ImageSY($this->imageResized) - 1;
931
932
      $rgbArray = imagecolorallocate($this->imageResized, $r, $g, $b);
933
934
      for($i = 0; $i < $thickness; ++$i) {
935
        ImageRectangle($this->imageResized, ++$x1, ++$y1, $x2--, $y2--, $rgbArray);
936
      }
937
    }
938
  }
939
940
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*-
941
  Gray Scale
942
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*/
943
944
  public function greyScale()
945
    # Author:     Jarrod Oberto
946
    # Date:       07-05-2011
947
    # Purpose:    Make image greyscale
948
    # Param in:   n/a
949
    # Param out:
950
    # Reference:
951
    # Notes:
952
    #
953
  {
954
    if ($this->imageResized) {
955
      imagefilter($this->imageResized, IMG_FILTER_GRAYSCALE);
956
    }
957
958
  }
959
960
  ## --------------------------------------------------------
961
962
  public function greyScaleEnhanced()
963
    # Author:     Jarrod Oberto
964
    # Date:       07-05-2011
965
    # Purpose:    Make image greyscale
966
    # Param in:   n/a
967
    # Param out:
968
    # Reference:
969
    # Notes:
970
    #
971
  {
972
    if ($this->imageResized) {
973
      imagefilter($this->imageResized, IMG_FILTER_GRAYSCALE);
974
      imagefilter($this->imageResized, IMG_FILTER_CONTRAST, -15);
975
      imagefilter($this->imageResized, IMG_FILTER_BRIGHTNESS, 2);
976
      $this->sharpen($this->width);
0 ignored issues
show
Unused Code introduced by
The call to imageLib::sharpen() has too many arguments starting with $this->width.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
977
    }
978
  }
979
980
  ## --------------------------------------------------------
981
982
  public function greyScaleDramatic()
983
  # Alias of gd_filter_monopin
984
  {
985
    $this->gd_filter_monopin();
986
  }
987
988
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*-
989
  Black 'n White
990
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*/
991
992
  public function blackAndWhite()
993
    # Author:     Jarrod Oberto
994
    # Date:       07-05-2011
995
    # Purpose:    Make image black and white
996
    # Param in:   n/a
997
    # Param out:
998
    # Reference:
999
    # Notes:
1000
    #
1001
  {
1002
    if ($this->imageResized) {
1003
1004
      imagefilter($this->imageResized, IMG_FILTER_GRAYSCALE);
1005
      imagefilter($this->imageResized, IMG_FILTER_CONTRAST, -1000);
1006
    }
1007
1008
  }
1009
1010
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*-
1011
  Negative
1012
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*/
1013
1014
  public function negative()
1015
    # Author:     Jarrod Oberto
1016
    # Date:       07-05-2011
1017
    # Purpose:    Make image negative
1018
    # Param in:   n/a
1019
    # Param out:
1020
    # Reference:
1021
    # Notes:
1022
    #
1023
  {
1024
    if ($this->imageResized) {
1025
1026
      imagefilter($this->imageResized, IMG_FILTER_NEGATE);
1027
    }
1028
1029
  }
1030
1031
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*-
1032
  Sepia
1033
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*/
1034
1035
  public function sepia()
1036
    # Author:     Jarrod Oberto
1037
    # Date:       07-05-2011
1038
    # Purpose:    Make image sepia
1039
    # Param in:   n/a
1040
    # Param out:
1041
    # Reference:
1042
    # Notes:
1043
    #
1044
  {
1045
    if ($this->imageResized) {
1046
      imagefilter($this->imageResized, IMG_FILTER_GRAYSCALE);
1047
      imagefilter($this->imageResized, IMG_FILTER_BRIGHTNESS, -10);
1048
      imagefilter($this->imageResized, IMG_FILTER_CONTRAST, -20);
1049
      imagefilter($this->imageResized, IMG_FILTER_COLORIZE, 60, 30, -15);
1050
    }
1051
  }
1052
1053
  ## --------------------------------------------------------
1054
1055
  public function sepia2()
1056
1057
  {
1058
    if ($this->imageResized) {
1059
1060
      $total = imagecolorstotal( $this->imageResized );
1061
      for ( $i = 0; $i < $total; ++$i ) {
1062
        $index = imagecolorsforindex( $this->imageResized, $i );
1063
        $red = ( $index["red"] * 0.393 + $index["green"] * 0.769 + $index["blue"] * 0.189 ) / 1.351;
1064
        $green = ( $index["red"] * 0.349 + $index["green"] * 0.686 + $index["blue"] * 0.168 ) / 1.203;
1065
        $blue = ( $index["red"] * 0.272 + $index["green"] * 0.534 + $index["blue"] * 0.131 ) / 2.140;
1066
        imagecolorset( $this->imageResized, $i, $red, $green, $blue );
1067
      }
1068
1069
    }
1070
  }
1071
1072
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*-
1073
  Vintage
1074
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*/
1075
1076
  public function vintage()
1077
  # Alias of gd_filter_monopin
1078
  {
1079
    $this->gd_filter_vintage();
1080
  }
1081
1082
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*-
1083
  Presets By Marc Hibbins
1084
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*/
1085
1086
  /** Apply 'Monopin' preset */
1087
  public function gd_filter_monopin()
1088
  {
1089
1090
    if ($this->imageResized) {
1091
      imagefilter($this->imageResized, IMG_FILTER_GRAYSCALE);
1092
      imagefilter($this->imageResized, IMG_FILTER_BRIGHTNESS, -15);
1093
      imagefilter($this->imageResized, IMG_FILTER_CONTRAST, -15);
1094
      $this->imageResized = $this->gd_apply_overlay($this->imageResized, 'vignette', 100);
1095
    }
1096
  }
1097
1098
  ## --------------------------------------------------------
1099
1100
  public function gd_filter_vintage()
1101
  {
1102
    if ($this->imageResized) {
1103
      $this->imageResized = $this->gd_apply_overlay($this->imageResized, 'vignette', 45);
1104
      imagefilter($this->imageResized, IMG_FILTER_BRIGHTNESS, 20);
1105
      imagefilter($this->imageResized, IMG_FILTER_CONTRAST, -35);
1106
      imagefilter($this->imageResized, IMG_FILTER_COLORIZE, 60, -10, 35);
1107
      imagefilter($this->imageResized, IMG_FILTER_SMOOTH, 7);
1108
      $this->imageResized = $this->gd_apply_overlay($this->imageResized, 'scratch', 10);
1109
    }
1110
  }
1111
1112
  ## --------------------------------------------------------
1113
1114
  /** Apply a PNG overlay */
1115
  private function gd_apply_overlay($im, $type, $amount)
1116
  #
1117
  # Original Author:    Marc Hibbins
1118
  # License:  Attribution-ShareAlike 3.0
1119
  # Purpose:
1120
  # Params in:
1121
  # Params out:
1122
  # Notes:
1123
  #
1124
  {
1125
    $width = imagesx($im);
1126
    $height = imagesy($im);
1127
    $filter = imagecreatetruecolor($width, $height);
1128
1129
    imagealphablending($filter, false);
1130
    imagesavealpha($filter, true);
1131
1132
    $transparent = imagecolorallocatealpha($filter, 255, 255, 255, 127);
1133
    imagefilledrectangle($filter, 0, 0, $width, $height, $transparent);
1134
1135
    // *** Resize overlay
1136
    $overlay = $this->filterOverlayPath . '/' . $type . '.png';
1137
    $png = imagecreatefrompng($overlay);
1138
    imagecopyresampled($filter, $png, 0, 0, 0, 0, $width, $height, imagesx($png), imagesy($png));
1139
1140
    $comp = imagecreatetruecolor($width, $height);
1141
    imagecopy($comp, $im, 0, 0, 0, 0, $width, $height);
1142
    imagecopy($comp, $filter, 0, 0, 0, 0, $width, $height);
1143
    imagecopymerge($im, $comp, 0, 0, 0, 0, $width, $height, $amount);
1144
1145
    imagedestroy($comp);
1146
1147
    return $im;
1148
  }
1149
1150
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*-
1151
  Colorise
1152
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*/
1153
1154
  public function image_colorize($rgb) {
1155
    imageTrueColorToPalette($this->imageResized,true,256);
1156
    $numColors = imageColorsTotal($this->imageResized);
1157
1158
    for ($x = 0; $x < $numColors; ++$x) {
1159
    list($r,$g,$b) = array_values(imageColorsForIndex($this->imageResized,$x));
1160
1161
    // calculate grayscale in percent
1162
    $grayscale = ($r + $g + $b) / 3 / 0xff;
1163
1164
    imageColorSet($this->imageResized,$x,
1165
      $grayscale * $rgb[0],
1166
      $grayscale * $rgb[1],
1167
      $grayscale * $rgb[2]
1168
    );
1169
1170
    }
1171
1172
    return true;
1173
  }
1174
1175
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*-
1176
  Reflection
1177
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*/
1178
1179
  public function addReflection($reflectionHeight = 50, $startingTransparency = 30, $inside = false, $bgColor = '#fff', $stretch=false, $divider = 0)
1180
  {
1181
1182
    // *** Convert color
1183
    $rgbArray = $this->formatColor($bgColor);
1184
    $r = $rgbArray['r'];
1185
    $g = $rgbArray['g'];
1186
    $b = $rgbArray['b'];
1187
1188
    $im = $this->imageResized;
1189
    $li = imagecreatetruecolor($this->width, 1);
1190
1191
    $bgc = imagecolorallocate($li, $r, $g, $b);
1192
    imagefilledrectangle($li, 0, 0, $this->width, 1, $bgc);
1193
1194
    $bg = imagecreatetruecolor($this->width, $reflectionHeight);
1195
    $wh = imagecolorallocate($im, 255, 255, 255);
1196
1197
    $im = imagerotate($im, -180, $wh);
1198
    imagecopyresampled($bg, $im, 0, 0, 0, 0, $this->width, $this->height, $this->width, $this->height);
1199
1200
    $im = $bg;
1201
1202
    $bg = imagecreatetruecolor($this->width, $reflectionHeight);
1203
1204
    for ($x = 0; $x < $this->width; ++$x) {
1205
      imagecopy($bg, $im, $x, 0, $this->width-$x -1, 0, 1, $reflectionHeight);
1206
    }
1207
    $im = $bg;
1208
1209
    $transaprencyAmount = $this->invertTransparency($startingTransparency, 100);
0 ignored issues
show
Unused Code introduced by
$transaprencyAmount is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1210
1211
    // *** Fade
1212
    if ($stretch) {
1213
      $step = 100/($reflectionHeight + $startingTransparency);
1214
    } else{
1215
      $step = 100/$reflectionHeight;
1216
    }
1217
    for($i=0; $i<=$reflectionHeight; ++$i){
1218
1219
      if($startingTransparency>100) $startingTransparency = 100;
1220
      if($startingTransparency< 1) $startingTransparency = 1;
1221
      imagecopymerge($bg, $li, 0, $i, 0, 0, $this->width, 1, $startingTransparency);
1222
      $startingTransparency+=$step;
1223
    }
1224
1225
    // *** Apply fade
1226
    imagecopymerge($im, $li, 0, 0, 0, 0, $this->width, $divider, 100); // Divider
1227
1228
1229
    // *** width, height of reflection.
1230
    $x = imagesx($im);
1231
    $y = imagesy($im);
1232
1233
    // *** Determines if the reflection should be displayed inside or outside the image
1234
    if ($inside) {
1235
1236
      // Create new blank image with sizes.
1237
      $final = imagecreatetruecolor($this->width, $this->height);
1238
1239
      imagecopymerge ($final, $this->imageResized, 0, 0, 0, $reflectionHeight, $this->width, $this->height - $reflectionHeight, 100);
1240
      imagecopymerge ($final, $im, 0, $this->height - $reflectionHeight, 0, 0, $x, $y, 100);
1241
1242
    } else {
1243
1244
      // Create new blank image with sizes.
1245
      $final = imagecreatetruecolor($this->width, $this->height + $y);
1246
1247
      imagecopymerge ($final, $this->imageResized, 0, 0, 0, 0, $this->width, $this->height, 100);
1248
      imagecopymerge ($final, $im, 0, $this->height, 0, 0, $x, $y, 100);
1249
    }
1250
1251
    $this->imageResized = $final;
1252
1253
    imagedestroy($li);
1254
    imagedestroy($im);
1255
  }
1256
1257
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*-
1258
  Rotate
1259
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*/
1260
1261
  public function rotate($value = 90, $bgColor = 'transparent')
1262
    # Author:     Jarrod Oberto
1263
    # Date:       07-05-2011
1264
    # Purpose:    Rotate image
1265
    # Param in:   (mixed) $degrees: (int) number of degress to rotate image
1266
  #               (str) param "left": rotate left
1267
  #               (str) param "right": rotate right
1268
  #               (str) param "upside": upside-down image
1269
    # Param out:
1270
    # Reference:
1271
    # Notes:    The default direction of imageRotate() is counter clockwise.
1272
    #
1273
  {
1274
    if ($this->imageResized) {
1275
1276
      if (is_integer($value)) {
1277
        $degrees = $value;
1278
      }
1279
1280
      // *** Convert color
1281
      $rgbArray = $this->formatColor($bgColor);
1282
      $r = $rgbArray['r'];
1283
      $g = $rgbArray['g'];
1284
      $b = $rgbArray['b'];
1285
      if (isset($rgbArray['a'])) {$a = $rgbArray['a']; }
1286
1287
      if (is_string($value)) {
1288
1289
        $value = fix_strtolower($value);
1290
1291
        switch ($value) {
1292
          case 'left':
1293
            $degrees = 90;
1294
            break;
1295
          case 'right':
1296
            $degrees = 270;
1297
            break;
1298
          case 'upside':
1299
            $degrees = 180;
1300
            break;
1301
          default:
1302
            break;
1303
        }
1304
1305
      }
1306
1307
      // *** The default direction of imageRotate() is counter clockwise
1308
      //   * This makes it clockwise
1309
      $degrees = 360 - $degrees;
0 ignored issues
show
Bug introduced by
The variable $degrees does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1310
1311
      // *** Create background color
1312
      $bg = ImageColorAllocateAlpha($this->imageResized, $r, $g, $b, $a);
0 ignored issues
show
Bug introduced by
The variable $a does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1313
1314
      // *** Fill with background
1315
      ImageFill($this->imageResized, 0, 0 , $bg);
1316
1317
      // *** Rotate
1318
      $this->imageResized = imagerotate($this->imageResized, $degrees, $bg); // Rotate 45 degrees and allocated the transparent colour as the one to make transparent (obviously)
1319
1320
      // Ensure alpha transparency
1321
      ImageSaveAlpha($this->imageResized,true);
1322
1323
    }
1324
  }
1325
1326
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*-
1327
  Round corners
1328
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*/
1329
1330
  public function roundCorners($radius = 5,  $bgColor = 'transparent')
1331
    # Author:     Jarrod Oberto
1332
    # Date:       19-05-2011
1333
    # Purpose:    Create rounded corners on your image
1334
    # Param in:   (int) radius = the amount of curvature
1335
  #       (mixed) $bgColor = the corner background color
1336
    # Param out:  n/a
1337
    # Reference:
1338
    # Notes:
1339
    #
1340
  {
1341
1342
    // *** Check if the user wants transparency
1343
    $isTransparent = false;
1344
    if (!is_array($bgColor)) {
1345
      if (fix_strtolower($bgColor) == 'transparent') {
1346
        $isTransparent = true;
1347
      }
1348
    }
1349
1350
    // *** If we use transparency, we need to color our curved mask with a unique color
1351
    if ($isTransparent) {
1352
      $bgColor = $this->findUnusedGreen();
1353
    }
1354
1355
    // *** Convert color
1356
    $rgbArray = $this->formatColor($bgColor);
1357
    $r = $rgbArray['r'];
1358
    $g = $rgbArray['g'];
1359
    $b = $rgbArray['b'];
1360
    if (isset($rgbArray['a'])) {$a = $rgbArray['a']; }
0 ignored issues
show
Unused Code introduced by
$a is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1361
1362
    // *** Create top-left corner mask (square)
1363
    $cornerImg = imagecreatetruecolor($radius, $radius);
1364
    //$cornerImg = imagecreate($radius, $radius);
1365
1366
      //imagealphablending($cornerImg, true);
1367
      //imagesavealpha($cornerImg, true);
1368
1369
      //imagealphablending($this->imageResized, false);
1370
      //imagesavealpha($this->imageResized, true);
1371
1372
    // *** Give it a color
1373
    $maskColor = imagecolorallocate($cornerImg, 0, 0, 0);
1374
1375
    // *** Replace the mask color (black) to transparent
1376
    imagecolortransparent($cornerImg, $maskColor);
1377
1378
    // *** Create the image background color
1379
    $imagebgColor = imagecolorallocate($cornerImg, $r, $g, $b);
1380
1381
    // *** Fill the corner area to the user defined color
1382
    imagefill($cornerImg, 0, 0, $imagebgColor);
1383
1384
    imagefilledellipse($cornerImg, $radius, $radius, $radius * 2, $radius * 2, $maskColor );
1385
1386
    // *** Map to top left corner
1387
    imagecopymerge($this->imageResized, $cornerImg, 0, 0, 0, 0, $radius, $radius, 100); #tl
1388
1389
    // *** Map rounded corner to other corners by rotating and applying the mask
1390
    $cornerImg = imagerotate($cornerImg, 90, 0);
1391
    imagecopymerge($this->imageResized, $cornerImg, 0, $this->height - $radius, 0, 0, $radius, $radius, 100); #bl
1392
1393
    $cornerImg = imagerotate($cornerImg, 90, 0);
1394
    imagecopymerge($this->imageResized, $cornerImg, $this->width - $radius, $this->height - $radius, 0, 0, $radius, $radius, 100); #br
1395
1396
    $cornerImg = imagerotate($cornerImg, 90, 0);
1397
    imagecopymerge($this->imageResized, $cornerImg, $this->width - $radius, 0, 0, 0, $radius, $radius, 100); #tr
1398
1399
1400
    // *** If corners are to be transparent, we fill our chromakey color as transparent.
1401
    if ($isTransparent) {
1402
      //imagecolortransparent($this->imageResized, $imagebgColor);
1403
      $this->imageResized = $this->transparentImage($this->imageResized);
1404
      imagesavealpha($this->imageResized, true);
1405
    }
1406
1407
  }
1408
1409
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*-
1410
  Shadow
1411
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*/
1412
1413
  public function addShadow($shadowAngle=45, $blur=15, $bgColor='transparent')
1414
  #
1415
  # Author:   Jarrod Oberto (Adapted from Pascal Naidon)
1416
  # Ref:    http://www.les-stooges.org/pascal/webdesign/vignettes/index.php?la=en
1417
  # Purpose:  Add a drop shadow to your image
1418
  # Params in:  (int) $angle: the angle of the shadow
1419
  #       (int) $blur: the blur distance
1420
  #       (mixed) $bgColor: the color of the background
1421
  # Params out:
1422
  # Notes:
1423
  #
1424
  {
1425
    // *** A higher number results in a smoother shadow
1426
    define('STEPS', $blur*2);
1427
1428
    // *** Set the shadow distance
1429
    $shadowDistance = $blur*0.25;
1430
1431
    // *** Set blur width and height
1432
    $blurWidth = $blurHeight = $blur;
1433
1434
    if ($shadowAngle == 0) {
1435
      $distWidth = 0;
1436
      $distHeight = 0;
1437
    } else {
1438
      $distWidth = $shadowDistance * cos(deg2rad($shadowAngle));
1439
      $distHeight = $shadowDistance * sin(deg2rad($shadowAngle));
1440
    }
1441
1442
    // *** Convert color
1443
    if (fix_strtolower($bgColor) != 'transparent') {
1444
      $rgbArray = $this->formatColor($bgColor);
1445
      $r0 = $rgbArray['r'];
1446
      $g0 = $rgbArray['g'];
1447
      $b0 = $rgbArray['b'];
1448
    }
1449
1450
    $image = $this->imageResized;
1451
    $width = $this->width;
1452
    $height = $this->height;
1453
1454
      $newImage = imagecreatetruecolor($width, $height);
1455
    imagecopyresampled($newImage, $image, 0, 0, 0, 0, $width, $height, $width, $height);
1456
1457
    // *** RGB
1458
    $rgb = imagecreatetruecolor($width+$blurWidth,$height+$blurHeight);
1459
    $colour = imagecolorallocate($rgb, 0, 0, 0);
1460
    imagefilledrectangle($rgb, 0, 0, $width+$blurWidth, $height+$blurHeight, $colour);
1461
    $colour = imagecolorallocate($rgb, 255, 255, 255);
1462
    //imagefilledrectangle($rgb, $blurWidth*0.5-$distWidth, $blurHeight*0.5-$distHeight, $width+$blurWidth*0.5-$distWidth, $height+$blurWidth*0.5-$distHeight, $colour);
1463
    imagefilledrectangle($rgb, $blurWidth*0.5-$distWidth, $blurHeight*0.5-$distHeight, $width+$blurWidth*0.5-$distWidth, $height+$blurWidth*0.5-$distHeight, $colour);
1464
    //imagecopymerge($rgb, $newImage, 1+$blurWidth*0.5-$distWidth, 1+$blurHeight*0.5-$distHeight, 0,0, $width, $height, 100);
1465
    imagecopymerge($rgb, $newImage, $blurWidth*0.5-$distWidth, $blurHeight*0.5-$distHeight, 0,0, $width+$blurWidth, $height+$blurHeight, 100);
1466
1467
    // *** Shadow (alpha)
1468
    $shadow = imagecreatetruecolor($width+$blurWidth,$height+$blurHeight);
1469
      imagealphablending($shadow, false);
1470
    $colour = imagecolorallocate($shadow, 0, 0, 0);
1471
    imagefilledrectangle($shadow, 0, 0, $width+$blurWidth, $height+$blurHeight, $colour);
1472
1473
    for($i=0;$i<=STEPS;++$i) {
1474
1475
      $t = ((1.0*$i)/STEPS);
1476
      $intensity = 255*$t*$t;
1477
1478
      $colour = imagecolorallocate($shadow, $intensity, $intensity, $intensity);
1479
      $points = array(
1480
        $blurWidth*$t,        $blurHeight,     // Point 1 (x, y)
1481
        $blurWidth,         $blurHeight*$t,  // Point 2 (x, y)
1482
        $width,           $blurHeight*$t,  // Point 3 (x, y)
1483
        $width+$blurWidth*(1-$t), $blurHeight,     // Point 4 (x, y)
1484
        $width+$blurWidth*(1-$t), $height,     // Point 5 (x, y)
1485
        $width,           $height+$blurHeight*(1-$t),  // Point 6 (x, y)
1486
        $blurWidth,         $height+$blurHeight*(1-$t),  // Point 7 (x, y)
1487
        $blurWidth*$t,        $height      // Point 8 (x, y)
1488
      );
1489
      imagepolygon($shadow, $points, 8, $colour);
1490
    }
1491
1492
    for($i=0;$i<=STEPS;++$i) {
1493
1494
      $t = ((1.0*$i)/STEPS);
1495
        $intensity = 255*$t*$t;
1496
1497
      $colour = imagecolorallocate($shadow, $intensity, $intensity, $intensity);
1498
      imagefilledarc($shadow, $blurWidth-1, $blurHeight-1, 2*(1-$t)*$blurWidth, 2*(1-$t)*$blurHeight, 180, 268, $colour, IMG_ARC_PIE);
1499
      imagefilledarc($shadow, $width, $blurHeight-1, 2*(1-$t)*$blurWidth, 2*(1-$t)*$blurHeight, 270, 358, $colour, IMG_ARC_PIE);
1500
      imagefilledarc($shadow, $width, $height, 2*(1-$t)*$blurWidth, 2*(1-$t)*$blurHeight, 0, 90, $colour, IMG_ARC_PIE);
1501
      imagefilledarc($shadow, $blurWidth-1, $height, 2*(1-$t)*$blurWidth, 2*(1-$t)*$blurHeight, 90, 180, $colour, IMG_ARC_PIE);
1502
    }
1503
1504
    $colour = imagecolorallocate($shadow, 255, 255, 255);
1505
    imagefilledrectangle($shadow, $blurWidth, $blurHeight, $width, $height, $colour);
1506
    imagefilledrectangle($shadow, $blurWidth*0.5-$distWidth, $blurHeight*0.5-$distHeight, $width+$blurWidth*0.5-1-$distWidth, $height+$blurHeight*0.5-1-$distHeight, $colour);
1507
1508
    // *** The magic
1509
        imagealphablending($rgb, false);
1510
1511
        for ($theX=0;$theX<imagesx($rgb);++$theX){
1512
      for ($theY=0;$theY<imagesy($rgb);++$theY){
1513
1514
        // *** Get the RGB values for every pixel of the RGB image
1515
        $colArray = imagecolorat($rgb,$theX,$theY);
1516
        $r = ($colArray >> 16) & 0xFF;
1517
        $g = ($colArray >> 8) & 0xFF;
1518
        $b = $colArray & 0xFF;
1519
1520
        // *** Get the alpha value for every pixel of the shadow image
1521
        $colArray = imagecolorat($shadow,$theX,$theY);
1522
        $a = $colArray & 0xFF;
1523
        $a = 127-floor($a/2);
1524
        $t = $a/128.0;
1525
1526
        // *** Create color
1527
        if(fix_strtolower($bgColor) == 'transparent') {
1528
          $myColour = imagecolorallocatealpha($rgb,$r,$g,$b,$a);
1529
        } else {
1530
          $myColour = imagecolorallocate($rgb,$r*(1.0-$t)+$r0*$t,$g*(1.0-$t)+$g0*$t,$b*(1.0-$t)+$b0*$t);
0 ignored issues
show
Bug introduced by
The variable $r0 does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Bug introduced by
The variable $g0 does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Bug introduced by
The variable $b0 does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1531
        }
1532
1533
        // *** Add color to new rgb image
1534
        imagesetpixel($rgb, $theX, $theY, $myColour);
1535
      }
1536
    }
1537
1538
    imagealphablending($rgb, true);
1539
    imagesavealpha($rgb, true);
1540
1541
    $this->imageResized = $rgb;
1542
1543
    imagedestroy($image);
1544
    imagedestroy($newImage);
1545
    imagedestroy($shadow);
1546
  }
1547
1548
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*-
1549
  Add Caption Box
1550
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*/
1551
1552
  public function addCaptionBox($side='b', $thickness=50, $padding=0, $bgColor='#000', $transaprencyAmount=30)
1553
  #
1554
  # Author:   Jarrod Oberto
1555
  # Date:   26 May 2011
1556
  # Purpose:  Add a caption box
1557
  # Params in:  (str) $side: the side to add the caption box (t, r, b, or l).
1558
  #       (int) $thickness: how thick you want the caption box to be.
1559
  #       (mixed) $bgColor: The color of the caption box.
1560
  #       (int) $transaprencyAmount: The amount of transparency to be
1561
  #       applied.
1562
  # Params out: n/a
1563
  # Notes:
1564
  #
1565
  {
1566
      $side = fix_strtolower($side);
1567
1568
      // *** Convert color
1569
      $rgbArray = $this->formatColor($bgColor);
1570
      $r = $rgbArray['r'];
1571
      $g = $rgbArray['g'];
1572
      $b = $rgbArray['b'];
1573
1574
      $positionArray = $this->calculateCaptionBoxPosition($side, $thickness, $padding);
1575
1576
      // *** Store incase we want to use method addTextToCaptionBox()
1577
      $this->captionBoxPositionArray = $positionArray;
1578
1579
      $transaprencyAmount = $this->invertTransparency($transaprencyAmount, 127, false);
1580
      $transparent = imagecolorallocatealpha($this->imageResized, $r, $g, $b, $transaprencyAmount);
1581
      imagefilledrectangle($this->imageResized, $positionArray['x1'], $positionArray['y1'], $positionArray['x2'], $positionArray['y2'], $transparent);
1582
  }
1583
1584
  ## --------------------------------------------------------
1585
1586
  public function addTextToCaptionBox($text, $fontColor='#fff', $fontSize = 12, $angle = 0, $font = null)
1587
  #
1588
  # Author:   Jarrod Oberto
1589
  # Date:   03 Aug 11
1590
  # Purpose:  Simplify adding text to a caption box by automatically
1591
  #       locating the center of the caption box
1592
  # Params in:  The usually text paams (less a couple)
1593
  # Params out: n/a
1594
  # Notes:
1595
  #
1596
  {
1597
1598
    // *** Get the caption box measurements
1599
    if (count($this->captionBoxPositionArray) == 4) {
1600
      $x1 = $this->captionBoxPositionArray['x1'];
1601
      $x2 = $this->captionBoxPositionArray['x2'];
1602
      $y1 = $this->captionBoxPositionArray['y1'];
1603
      $y2 = $this->captionBoxPositionArray['y2'];
1604
    } else {
1605
      if ($this->debug) { throw new Exception('No caption box found.'); }else{ return false; }
1606
    }
1607
1608
    // *** Get text font
1609
    $font = $this->getTextFont($font);
1610
1611
    // *** Get text size
1612
    $textSizeArray = $this->getTextSize($fontSize, $angle, $font, $text);
1613
    $textWidth = $textSizeArray['width'];
1614
    $textHeight = $textSizeArray['height'];
1615
1616
    // *** Find the width/height middle points
1617
    $boxXMiddle = (($x2 - $x1) / 2);
1618
    $boxYMiddle = (($y2 - $y1) / 2);
1619
1620
    // *** Box middle - half the text width/height
1621
    $xPos = ($x1 + $boxXMiddle) - ($textWidth/2);
1622
    $yPos = ($y1 + $boxYMiddle) - ($textHeight/2);
1623
1624
    $pos = $xPos . 'x' . $yPos;
1625
1626
    $this->addText($text, $pos, $padding = 0, $fontColor, $fontSize, $angle, $font);
1627
1628
  }
1629
1630
  ## --------------------------------------------------------
1631
1632
  private function calculateCaptionBoxPosition($side, $thickness, $padding)
1633
  {
1634
    $positionArray = array();
1635
1636
    switch ($side) {
1637
      case 't':
1638
        $positionArray['x1'] = 0;
1639
        $positionArray['y1'] = $padding;
1640
        $positionArray['x2'] = $this->width;
1641
        $positionArray['y2'] = $thickness + $padding;
1642
        break;
1643
      case 'r':
1644
        $positionArray['x1'] = $this->width - $thickness - $padding;
1645
        $positionArray['y1'] = 0;
1646
        $positionArray['x2'] = $this->width - $padding;
1647
        $positionArray['y2'] = $this->height;
1648
        break;
1649
      case 'b':
1650
        $positionArray['x1'] = 0;
1651
        $positionArray['y1'] = $this->height - $thickness - $padding;
1652
        $positionArray['x2'] = $this->width;
1653
        $positionArray['y2'] = $this->height - $padding;
1654
        break;
1655
      case 'l':
1656
        $positionArray['x1'] = $padding;
1657
        $positionArray['y1'] = 0;
1658
        $positionArray['x2'] = $thickness + $padding;
1659
        $positionArray['y2'] = $this->height;
1660
        break;
1661
1662
      default:
1663
        break;
1664
    }
1665
1666
    return $positionArray;
1667
1668
  }
1669
1670
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*-
1671
  Get EXIF Data
1672
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*/
1673
1674
  public function getExif($debug=false)
1675
    # Author:     Jarrod Oberto
1676
    # Date:       07-05-2011
1677
    # Purpose:    Get image EXIF data
1678
    # Param in:   n/a
1679
    # Param out:  An associate array of EXIF data
1680
    # Reference:
1681
    # Notes:
1682
    # 23 May 13 : added orientation flag -jco
1683
    #
1684
  {
1685
1686
    if (!$this->debug || !$debug) { $debug = false; }
1687
1688
    // *** Check all is good - check the EXIF library exists and the file exists, too.
1689
    if (!$this->testEXIFInstalled()) { if ($debug) { throw new Exception('The EXIF Library is not installed.'); }else{ return array(); }};
1690
    if (!file_exists($this->fileName)) { if ($debug) { throw new Exception('Image not found.'); }else{ return array(); }};
1691
    if ($this->fileExtension != '.jpg') { if ($debug) { throw new Exception('Metadata not supported for this image type.'); }else{ return array(); }};
1692
    $exifData = exif_read_data($this->fileName, 'IFD0');
1693
1694
    // *** Format the apperture value
1695
    $ev = $exifData['ApertureValue'];
1696
    $apPeicesArray = explode('/', $ev);
1697
    if (count($apPeicesArray) == 2) {
1698
      $apertureValue = round($apPeicesArray[0] / $apPeicesArray[1], 2, PHP_ROUND_HALF_DOWN) . ' EV';
1699
    } else { $apertureValue = '';}
1700
1701
    // *** Format the focal length
1702
    $focalLength = $exifData['FocalLength'];
1703
    $flPeicesArray = explode('/', $focalLength);
1704
    if (count($flPeicesArray) == 2) {
1705
      $focalLength = $flPeicesArray[0] / $flPeicesArray[1] . '.0 mm';
1706
    } else { $focalLength = '';}
1707
1708
    // *** Format fNumber
1709
    $fNumber = $exifData['FNumber'];
1710
    $fnPeicesArray = explode('/', $fNumber);
1711
    if (count($fnPeicesArray) == 2) {
1712
      $fNumber = $fnPeicesArray[0] / $fnPeicesArray[1];
1713
    } else { $fNumber = '';}
1714
1715
    // *** Resolve ExposureProgram
1716
    if (isset($exifData['ExposureProgram'])) { $ep =  $exifData['ExposureProgram']; }
1717
    if (isset($ep)) { $ep = $this->resolveExposureProgram($ep); }
1718
1719
    // *** Resolve MeteringMode
1720
    $mm = $exifData['MeteringMode'];
1721
    $mm = $this->resolveMeteringMode($mm);
1722
1723
    // *** Resolve Flash
1724
    $flash = $exifData['Flash'];
1725
    $flash = $this->resolveFlash($flash);
1726
1727
    if (isset($exifData['Make'])) {
1728
      $exifDataArray['make'] = $exifData['Make'];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$exifDataArray was never initialized. Although not strictly required by PHP, it is generally a good practice to add $exifDataArray = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
1729
    } else { $exifDataArray['make'] = ''; }
0 ignored issues
show
Coding Style Comprehensibility introduced by
$exifDataArray was never initialized. Although not strictly required by PHP, it is generally a good practice to add $exifDataArray = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
1730
1731
    if (isset($exifData['Model'])) {
1732
      $exifDataArray['model'] = $exifData['Model'];
1733
    } else { $exifDataArray['model'] = ''; }
1734
1735
    if (isset($exifData['DateTime'])) {
1736
      $exifDataArray['date'] = $exifData['DateTime'];
1737
    } else { $exifDataArray['date'] = ''; }
1738
1739
    if (isset($exifData['ExposureTime'])) {
1740
      $exifDataArray['exposure time'] = $exifData['ExposureTime'] . ' sec.';
1741
    } else { $exifDataArray['exposure time'] = ''; }
1742
1743
    if ($apertureValue != '') {
1744
      $exifDataArray['aperture value'] = $apertureValue;
1745
    } else { $exifDataArray['aperture value'] = ''; }
1746
1747
    if (isset($exifData['COMPUTED']['ApertureFNumber'])) {
1748
      $exifDataArray['f-stop'] = $exifData['COMPUTED']['ApertureFNumber'];
1749
    } else { $exifDataArray['f-stop'] = ''; }
1750
1751
    if (isset($exifData['FNumber'])) {
1752
      $exifDataArray['fnumber'] = $exifData['FNumber'];
1753
    } else { $exifDataArray['fnumber'] = ''; }
1754
1755
    if ($fNumber != '') {
1756
      $exifDataArray['fnumber value'] = $fNumber;
1757
    } else { $exifDataArray['fnumber value'] = ''; }
1758
1759
    if (isset($exifData['ISOSpeedRatings'])) {
1760
      $exifDataArray['iso'] = $exifData['ISOSpeedRatings'];
1761
    } else { $exifDataArray['iso'] = ''; }
1762
1763
    if ($focalLength != '') {
1764
      $exifDataArray['focal length'] = $focalLength;
1765
    } else { $exifDataArray['focal length'] = ''; }
1766
1767
    if (isset($ep)) {
1768
      $exifDataArray['exposure program'] = $ep;
1769
    } else { $exifDataArray['exposure program'] = ''; }
1770
1771
    if ($mm != '') {
1772
      $exifDataArray['metering mode'] = $mm;
1773
    } else { $exifDataArray['metering mode'] = ''; }
1774
1775
    if ($flash != '') {
1776
      $exifDataArray['flash status'] = $flash;
1777
    } else { $exifDataArray['flash status'] = ''; }
1778
1779
    if (isset($exifData['Artist'])) {
1780
      $exifDataArray['creator'] = $exifData['Artist'] ;
1781
    } else { $exifDataArray['creator'] = ''; }
1782
1783
    if (isset($exifData['Copyright'])) {
1784
      $exifDataArray['copyright'] = $exifData['Copyright'];
1785
    } else { $exifDataArray['copyright'] = ''; }
1786
1787
    // *** Orientation
1788
    if (isset($exifData['Orientation'])) {
1789
        $exifDataArray['orientation'] = $exifData['Orientation'];
1790
    } else { $exifDataArray['orientation'] = ''; }
1791
1792
    return $exifDataArray;
1793
  }
1794
1795
  ## --------------------------------------------------------
1796
1797
  private function resolveExposureProgram($ep)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
1798
  {
1799
    switch ($ep) {
1800
      case 0:
1801
        $ep = '';
1802
        break;
1803
      case 1:
1804
        $ep = 'manual';
1805
        break;
1806
      case 2:
1807
        $ep = 'normal program';
1808
        break;
1809
      case 3:
1810
        $ep = 'aperture priority';
1811
        break;
1812
      case 4:
1813
        $ep = 'shutter priority';
1814
        break;
1815
      case 5:
1816
        $ep = 'creative program';
1817
        break;
1818
      case 6:
1819
        $ep = 'action program';
1820
        break;
1821
      case 7:
1822
        $ep = 'portrait mode';
1823
        break;
1824
      case 8:
1825
        $ep = 'landscape mode';
1826
        break;
1827
1828
      default:
1829
        break;
1830
    }
1831
1832
    return $ep;
1833
  }
1834
1835
  ## --------------------------------------------------------
1836
1837
  private function resolveMeteringMode($mm)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
1838
  {
1839
    switch ($mm) {
1840
      case 0:
1841
        $mm = 'unknown';
1842
        break;
1843
      case 1:
1844
        $mm = 'average';
1845
        break;
1846
      case 2:
1847
        $mm = 'center weighted average';
1848
        break;
1849
      case 3:
1850
        $mm = 'spot';
1851
        break;
1852
      case 4:
1853
        $mm = 'multi spot';
1854
        break;
1855
      case 5:
1856
        $mm = 'pattern';
1857
        break;
1858
      case 6:
1859
        $mm = 'partial';
1860
        break;
1861
      case 255:
1862
        $mm = 'other';
1863
        break;
1864
1865
      default:
1866
        break;
1867
    }
1868
1869
    return $mm;
1870
  }
1871
1872
  ## --------------------------------------------------------
1873
1874
  private function resolveFlash($flash)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
1875
  {
1876
    switch ($flash) {
1877
      case 0:
1878
        $flash = 'flash did not fire';
1879
        break;
1880
      case 1:
1881
        $flash = 'flash fired';
1882
        break;
1883
      case 5:
1884
        $flash = 'strobe return light not detected';
1885
        break;
1886
      case 7:
1887
        $flash = 'strobe return light detected';
1888
        break;
1889
      case 9:
1890
        $flash = 'flash fired, compulsory flash mode';
1891
        break;
1892
      case 13:
1893
        $flash = 'flash fired, compulsory flash mode, return light not detected';
1894
        break;
1895
      case 15:
1896
        $flash = 'flash fired, compulsory flash mode, return light detected';
1897
        break;
1898
      case 16:
1899
        $flash = 'flash did not fire, compulsory flash mode';
1900
        break;
1901
      case 24:
1902
        $flash = 'flash did not fire, auto mode';
1903
        break;
1904
      case 25:
1905
        $flash = 'flash fired, auto mode';
1906
        break;
1907
      case 29:
1908
        $flash = 'flash fired, auto mode, return light not detected';
1909
        break;
1910
      case 31:
1911
        $flash = 'flash fired, auto mode, return light detected';
1912
        break;
1913
      case 32:
1914
        $flash = 'no flash function';
1915
        break;
1916
      case 65:
1917
        $flash = 'flash fired, red-eye reduction mode';
1918
        break;
1919
      case 69:
1920
        $flash = 'flash fired, red-eye reduction mode, return light not detected';
1921
        break;
1922
      case 71:
1923
        $flash = 'flash fired, red-eye reduction mode, return light detected';
1924
        break;
1925
      case 73:
1926
        $flash = 'flash fired, compulsory flash mode, red-eye reduction mode';
1927
        break;
1928
      case 77:
1929
        $flash = 'flash fired, compulsory flash mode, red-eye reduction mode, return light not detected';
1930
        break;
1931
      case 79:
1932
        $flash = 'flash fired, compulsory flash mode, red-eye reduction mode, return light detected';
1933
        break;
1934
      case 89:
1935
        $flash = 'flash fired, auto mode, red-eye reduction mode';
1936
        break;
1937
      case 93:
1938
        $flash = 'flash fired, auto mode, return light not detected, red-eye reduction mode';
1939
        break;
1940
      case 95:
1941
        $flash = 'flash fired, auto mode, return light detected, red-eye reduction mode';
1942
        break;
1943
1944
      default:
1945
        break;
1946
    }
1947
1948
    return $flash;
1949
1950
  }
1951
1952
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*-
1953
  Get IPTC Data
1954
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*/
1955
1956
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*-
1957
  Write IPTC Data
1958
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*/
1959
1960
  public function writeIPTCcaption($value)
1961
  # Caption
1962
  {
1963
    $this->writeIPTC(120, $value);
1964
  }
1965
1966
  ## --------------------------------------------------------
1967
1968
  public function writeIPTCwriter($value)
0 ignored issues
show
Unused Code introduced by
The parameter $value is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1969
  {
1970
    //$this->writeIPTC(65, $value);
1971
  }
1972
1973
  ## --------------------------------------------------------
1974
1975
  private function writeIPTC($dat, $value)
1976
  {
1977
1978
    # LIMIT TO JPG
1979
1980
    $caption_block = $this->iptc_maketag(2, $dat, $value);
1981
    $image_string = iptcembed($caption_block, $this->fileName);
1982
    file_put_contents('iptc.jpg', $image_string);
1983
  }
1984
1985
## --------------------------------------------------------
1986
1987
  private function iptc_maketag($rec,$dat,$val)
1988
  # Author:   Thies C. Arntzen
1989
  # Purpose:    Function to format the new IPTC text
1990
  # Param in:   $rec: Application record. (We’re working with #2)
1991
  #       $dat: Index. (120 for caption, 118 for contact. See the IPTC IIM
1992
  #         specification:
1993
  #         http://www.iptc.org/std/IIM/4.1/specification/IIMV4.1.pdf
1994
  #       $val: Value/data/text. Make sure this is within the length
1995
  #         constraints of the IPTC IIM specification
1996
  # Ref:      http://blog.peterhaza.no/working-with-image-meta-data-in-exif-and-iptc-headers-from-php/
1997
  #       http://php.net/manual/en/function.iptcembed.php
1998
  #
1999
  {
2000
    $len = strlen($val);
2001
    if ($len < 0x8000)
2002
      return chr(0x1c).chr($rec).chr($dat).
2003
      chr($len >> 8).
2004
      chr($len & 0xff).
2005
      $val;
2006
    else
2007
      return chr(0x1c).chr($rec).chr($dat).
2008
      chr(0x80).chr(0x04).
2009
      chr(($len >> 24) & 0xff).
2010
      chr(($len >> 16) & 0xff).
2011
      chr(($len >> 8 ) & 0xff).
2012
      chr(($len ) & 0xff).
2013
      $val;
2014
  }
2015
2016
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*-
2017
  Write XMP Data
2018
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*/
2019
2020
  //http://xmpphptoolkit.sourceforge.net/
2021
2022
2023
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*-
2024
  Add Text
2025
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*/
2026
2027
  public function addText($text, $pos = '20x20', $padding = 0, $fontColor='#fff', $fontSize = 12, $angle = 0, $font = null)
2028
    # Author:     Jarrod Oberto
2029
  # Date:       18-11-09
2030
    # Purpose:    Add text to an image
2031
    # Param in:
2032
    # Param out:
2033
    # Reference:  http://php.net/manual/en/function.imagettftext.php
2034
    # Notes:      Make sure you supply the font.
2035
    #
2036
  {
2037
2038
    // *** Convert color
2039
    $rgbArray = $this->formatColor($fontColor);
2040
    $r = $rgbArray['r'];
2041
    $g = $rgbArray['g'];
2042
    $b = $rgbArray['b'];
2043
2044
    // *** Get text font
2045
    $font = $this->getTextFont($font);
2046
2047
    // *** Get text size
2048
    $textSizeArray = $this->getTextSize($fontSize, $angle, $font, $text);
2049
    $textWidth = $textSizeArray['width'];
2050
    $textHeight = $textSizeArray['height'];
2051
2052
    // *** Find co-ords to place text
2053
    $posArray = $this->calculatePosition($pos, $padding, $textWidth, $textHeight, false);
2054
    $x = $posArray['width'];
2055
    $y = $posArray['height'];
2056
2057
    $fontColor = imagecolorallocate($this->imageResized, $r, $g, $b);
2058
2059
    // *** Add text
2060
    imagettftext($this->imageResized, $fontSize, $angle, $x, $y, $fontColor, $font, $text);
2061
  }
2062
2063
  ## --------------------------------------------------------
2064
2065
  private function getTextFont($font)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
2066
  {
2067
    // *** Font path (shou
2068
    $fontPath =  __DIR__ . '/' . $this->fontDir;
2069
2070
    // *** The below is/may be needed depending on your version (see ref)
2071
    putenv('GDFONTPATH=' . realpath('.'));
2072
2073
    // *** Check if the passed in font exsits...
2074
    if ($font == null || !file_exists($font)) {
2075
2076
      // *** ...If not, default to this font.
2077
      $font = $fontPath . '/arimo.ttf';
2078
2079
      // *** Check our default font exists...
2080
      if (!file_exists($font)) {
2081
2082
        // *** If not, return false
2083
        if ($this->debug) { throw new Exception('Font not found'); }else{ return false; }
2084
      }
2085
    }
2086
2087
    return $font;
2088
2089
  }
2090
2091
  ## --------------------------------------------------------
2092
2093
  private function getTextSize($fontSize, $angle, $font, $text)
2094
  {
2095
2096
    // *** Define box (so we can get the width)
2097
    $box = @imageTTFBbox($fontSize, $angle, $font, $text);
2098
2099
    // ***  Get width of text from dimensions
2100
    $textWidth = abs($box[4] - $box[0]);
2101
2102
    // ***  Get height of text from dimensions (should also be same as $fontSize)
2103
    $textHeight = abs($box[5] - $box[1]);
2104
2105
    return array('height' => $textHeight, 'width' => $textWidth);
2106
  }
2107
2108
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*-
2109
  Add Watermark
2110
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*/
2111
2112
  public function addWatermark($watermarkImage, $pos, $padding = 0, $opacity = 0)
2113
    # Author:     Jarrod Oberto
2114
    # Date:       18-11-09
2115
    # Purpose:    Add watermark image
2116
    # Param in:   (str) $watermark: The watermark image
2117
  #       (str) $pos: Could be a pre-determined position such as:
2118
  #           tl = top left,
2119
  #           t  = top (middle),
2120
  #           tr = top right,
2121
  #           l  = left,
2122
  #           m  = middle,
2123
  #           r  = right,
2124
  #           bl = bottom left,
2125
  #           b  = bottom (middle),
2126
  #           br = bottom right
2127
  #         Or, it could be a co-ordinate position such as: 50x100
2128
  #
2129
  #       (int) $padding: If using a pre-determined position you can
2130
  #         adjust the padding from the edges by passing an amount
2131
  #         in pixels. If using co-ordinates, this value is ignored.
2132
    # Param out:
2133
    # Reference:  http://www.php.net/manual/en/image.examples-watermark.php
2134
    # Notes:      Based on example in reference.
2135
  #
2136
    #
2137
  {
2138
2139
    // Load the stamp and the photo to apply the watermark to
2140
    $stamp = $this->openImage ($watermarkImage);    # stamp
2141
    $im = $this->imageResized;            # photo
2142
2143
    // *** Get stamps width and height
2144
    $sx = imagesx($stamp);
2145
    $sy = imagesy($stamp);
2146
2147
    // *** Find co-ords to place image
2148
    $posArray = $this->calculatePosition($pos, $padding, $sx, $sy);
2149
    $x = $posArray['width'];
2150
    $y = $posArray['height'];
2151
2152
    // *** Set watermark opacity
2153
    if (fix_strtolower(strrchr($watermarkImage, '.')) == '.png') {
2154
2155
      $opacity = $this->invertTransparency($opacity, 100);
2156
      $this->filterOpacity($stamp, $opacity);
2157
    }
2158
2159
    // Copy the watermark image onto our photo
2160
    imagecopy($im, $stamp, $x, $y, 0, 0, imagesx($stamp), imagesy($stamp));
2161
2162
  }
2163
2164
  ## --------------------------------------------------------
2165
2166
  private function calculatePosition($pos, $padding, $assetWidth, $assetHeight, $upperLeft = true)
2167
  #
2168
  # Author:   Jarrod Oberto
2169
  # Date:   08-05-11
2170
  # Purpose:  Calculate the x, y pixel cordinates of the asset to place
2171
  # Params in:  (str) $pos: Either something like: "tl", "l", "br" or an
2172
  #         exact position like: "100x50"
2173
  #       (int) $padding: The amount of padding from the edge. Only
2174
  #         used for the predefined $pos.
2175
  #       (int) $assetWidth: The width of the asset to add to the image
2176
  #       (int) $assetHeight: The height of the asset to add to the image
2177
  #       (bol) $upperLeft: if true, the asset will be positioned based
2178
  #         on the upper left x, y coords. If false, it means you're
2179
  #         using the lower left as the basepoint and this will
2180
  #         convert it to the upper left position
2181
  # Params out:
2182
  # NOTE: this is done from the UPPER left corner!! But will convert lower
2183
  #   left basepoints to upper left if $upperleft is set to false
2184
  #
2185
  #
2186
  {
2187
    $pos = fix_strtolower($pos);
2188
2189
    // *** If co-ords have been entered
2190
    if (strstr($pos, 'x')) {
2191
      $pos = str_replace(' ', '', $pos);
2192
2193
      $xyArray = explode('x', $pos);
2194
      list($width, $height) = $xyArray;
2195
2196
    } else {
2197
2198
      switch ($pos) {
2199
        case 'tl':
2200
          $width = 0 + $padding;
2201
          $height = 0 + $padding;
2202
          break;
2203
2204
        case 't':
2205
          $width = ($this->width / 2) - ($assetWidth / 2);
2206
          $height = 0 + $padding;
2207
          break;
2208
2209
        case 'tr':
2210
          $width = $this->width - $assetWidth - $padding;
2211
          $height = 0 + $padding;;
2212
          break;
2213
2214
        case 'l':
2215
          $width = 0 + $padding;
2216
          $height = ($this->height / 2) - ($assetHeight / 2);
2217
          break;
2218
2219
        case 'm':
2220
          $width = ($this->width / 2) - ($assetWidth / 2);
2221
          $height = ($this->height / 2) - ($assetHeight / 2);
2222
          break;
2223
2224
        case 'r':
2225
          $width = $this->width - $assetWidth - $padding;
2226
          $height = ($this->height / 2) - ($assetHeight / 2);
2227
          break;
2228
2229
        case 'bl':
2230
          $width = 0 + $padding;
2231
          $height = $this->height - $assetHeight - $padding;
2232
          break;
2233
2234
        case 'b':
2235
          $width = ($this->width / 2) - ($assetWidth / 2);
2236
          $height = $this->height - $assetHeight - $padding;
2237
          break;
2238
2239
        case 'br':
2240
          $width = $this->width - $assetWidth - $padding;
2241
          $height = $this->height - $assetHeight - $padding;
2242
          break;
2243
2244
        default:
2245
          $width = 0;
2246
          $height = 0;
2247
          break;
2248
      }
2249
    }
2250
2251
    if (!$upperLeft) {
2252
      $height = $height + $assetHeight;
2253
    }
2254
2255
    return array('width' => $width, 'height' => $height);
2256
  }
2257
2258
  ## --------------------------------------------------------
2259
2260
  private function filterOpacity(&$img, $opacity = 75)
2261
  #
2262
  # Author:     aiden dot mail at freemail dot hu
2263
  # Author date:  29-03-08 08:16
2264
  # Date added:   08-05-11
2265
  # Purpose:    Change opacity of image
2266
  # Params in:    $img: Image resource id
2267
  #         (int) $opacity: the opacity amount: 0-100, 100 being not opaque.
2268
  # Params out:   (bool) true on success, else false
2269
  # Ref:      http://www.php.net/manual/en/function.imagefilter.php#82162
2270
  # Notes:      png only
2271
  #
2272
  {
2273
2274
    if (!isset($opacity)) {
2275
      return false;
2276
    }
2277
2278
    if ($opacity == 100) {
2279
      return true;
2280
    }
2281
2282
    $opacity /= 100;
2283
2284
    //get image width and height
2285
    $w = imagesx($img);
2286
    $h = imagesy($img);
2287
2288
    //turn alpha blending off
2289
    imagealphablending($img, false);
2290
2291
    //find the most opaque pixel in the image (the one with the smallest alpha value)
2292
    $minalpha = 127;
2293
    for ($x = 0; $x < $w; ++$x)
2294
      for ($y = 0; $y < $h; ++$y) {
2295
        $alpha = ( imagecolorat($img, $x, $y) >> 24 ) & 0xFF;
2296
        if ($alpha < $minalpha) {
2297
          $minalpha = $alpha;
2298
        }
2299
      }
2300
2301
    //loop through image pixels and modify alpha for each
2302
    for ($x = 0; $x < $w; ++$x) {
2303
      for ($y = 0; $y < $h; ++$y) {
2304
        //get current alpha value (represents the TANSPARENCY!)
2305
        $colorxy = imagecolorat($img, $x, $y);
2306
        $alpha = ( $colorxy >> 24 ) & 0xFF;
2307
        //calculate new alpha
2308
        if ($minalpha !== 127) {
2309
          $alpha = 127 + 127 * $opacity * ( $alpha - 127 ) / ( 127 - $minalpha );
2310
        } else {
2311
          $alpha += 127 * $opacity;
2312
        }
2313
        //get the color index with new alpha
2314
        $alphacolorxy = imagecolorallocatealpha($img, ( $colorxy >> 16 ) & 0xFF, ( $colorxy >> 8 ) & 0xFF, $colorxy & 0xFF, $alpha);
2315
        //set pixel with the new color + opacity
2316
        if (!imagesetpixel($img, $x, $y, $alphacolorxy)) {
2317
2318
          return false;
2319
        }
2320
      }
2321
    }
2322
2323
    return true;
2324
  }
2325
2326
## --------------------------------------------------------
2327
2328
    private function openImage($file)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
2329
    # Author:     Jarrod Oberto
2330
    # Date:       27-02-08
2331
    # Purpose:
2332
    # Param in:
2333
    # Param out:  n/a
2334
    # Reference:
2335
    # Notes:
2336
    #
2337
    {
2338
2339
    if (!file_exists($file) && !$this->checkStringStartsWith('http://', $file)) { if ($this->debug) { throw new Exception('Image not found.'); }else{ throw new Exception(); }};
2340
2341
        // *** Get extension
2342
        $extension = strrchr($file, '.');
2343
        $extension = fix_strtolower($extension);
2344
        switch($extension)
2345
        {
2346
            case '.jpg':
2347
            case '.jpeg':
2348
                $img = @imagecreatefromjpeg($file);
2349
                break;
2350
            case '.gif':
2351
                $img = @imagecreatefromgif($file);
2352
                break;
2353
            case '.png':
2354
                $img = @imagecreatefrompng($file);
2355
                break;
2356
            case '.bmp':
2357
                $img = @$this->imagecreatefrombmp($file);
2358
                break;
2359
            case '.psd':
2360
                $img = @$this->imagecreatefrompsd($file);
2361
                break;
2362
2363
            // ... etc
2364
2365
            default:
2366
                $img = false;
2367
                break;
2368
        }
2369
2370
        return $img;
2371
    }
2372
2373
## --------------------------------------------------------
2374
2375
  public function reset()
2376
  #
2377
  # Author:   Jarrod Oberto
2378
  # Date:   30-08-11
2379
  # Purpose:  Reset the resource (allow further editing)
2380
  # Params in:
2381
  # Params out:
2382
  # Notes:
2383
  #
2384
  {
2385
    $this->__construct($this->fileName);
2386
  }
2387
2388
## --------------------------------------------------------
2389
2390
    public function saveImage($savePath, $imageQuality="100")
2391
    # Author:     Jarrod Oberto
2392
    # Date:       27-02-08
2393
    # Purpose:    Saves the image
2394
    # Param in:   $savePath: Where to save the image including filename:
2395
    #             $imageQuality: image quality you want the image saved at 0-100
2396
    # Param out:  n/a
2397
    # Reference:
2398
    # Notes:    * gif doesn't have a quality parameter
2399
  #       * jpg has a quality setting 0-100 (100 being the best)
2400
    #       * png has a quality setting 0-9 (0 being the best)
2401
  #
2402
  #             * bmp files have no native support for bmp files. We use a
2403
  #       third party class to save as bmp.
2404
    {
2405
2406
    // *** Perform a check or two.
2407
    if (!is_resource($this->imageResized)) { if ($this->debug) { throw new Exception('saveImage: This is not a resource.'); }else{ throw new Exception(); }}
2408
    $fileInfoArray = pathInfo($savePath);
2409
    clearstatcache();
2410
    if (!is_writable($fileInfoArray['dirname'])) {  if ($this->debug) { throw new Exception('The path is not writable. Please check your permissions.'); }else{ throw new Exception(); }}
2411
2412
    // *** Get extension
2413
        $extension = strrchr($savePath, '.');
2414
        $extension = fix_strtolower($extension);
2415
2416
    $error = '';
2417
2418
        switch($extension)
2419
        {
2420
            case '.jpg':
2421
            case '.jpeg':
2422
        $this->checkInterlaceImage($this->isInterlace);
2423
        if (imagetypes() & IMG_JPG) {
2424
          imagejpeg($this->imageResized, $savePath, $imageQuality);
2425
        } else { $error = 'jpg'; }
2426
                break;
2427
2428
            case '.gif':
2429
        $this->checkInterlaceImage($this->isInterlace);
2430
        if (imagetypes() & IMG_GIF) {
2431
          imagegif($this->imageResized, $savePath);
2432
        } else { $error = 'gif'; }
2433
                break;
2434
2435
            case '.png':
2436
        // *** Scale quality from 0-100 to 0-9
2437
        $scaleQuality = round(($imageQuality/100) * 9);
2438
2439
        // *** Invert qualit setting as 0 is best, not 9
2440
        $invertScaleQuality = 9 - $scaleQuality;
2441
2442
        $this->checkInterlaceImage($this->isInterlace);
2443
        if (imagetypes() & IMG_PNG) {
2444
           imagepng($this->imageResized, $savePath, $invertScaleQuality);
2445
        } else { $error = 'png'; }
2446
                break;
2447
2448
            case '.bmp':
2449
        file_put_contents($savePath, $this->GD2BMPstring($this->imageResized));
2450
          break;
2451
2452
            // ... etc
2453
2454
            default:
2455
        // *** No extension - No save.
2456
        $this->errorArray[] = 'This file type (' . $extension . ') is not supported. File not saved.';
2457
                break;
2458
        }
2459
2460
    //imagedestroy($this->imageResized);
2461
2462
    // *** Display error if a file type is not supported.
2463
    if ($error != '') {
2464
      $this->errorArray[] = $error . ' support is NOT enabled. File not saved.';
2465
    }
2466
    }
2467
2468
## --------------------------------------------------------
2469
2470
  public function displayImage($fileType = 'jpg', $imageQuality="100")
2471
    # Author:     Jarrod Oberto
2472
    # Date:       18-11-09
2473
    # Purpose:    Display images directly to the browser
2474
    # Param in:   The image type you want to display
2475
    # Param out:
2476
    # Reference:
2477
    # Notes:
2478
    #
2479
  {
2480
2481
    if (!is_resource($this->imageResized)) { if ($this->debug) { throw new Exception('saveImage: This is not a resource.'); }else{ throw new Exception(); }}
2482
2483
        switch($fileType)
2484
        {
2485
            case 'jpg':
2486
            case 'jpeg':
2487
        header('Content-type: image/jpeg');
2488
        imagejpeg($this->imageResized, '', $imageQuality);
2489
                break;
2490
            case 'gif':
2491
        header('Content-type: image/gif');
2492
        imagegif($this->imageResized);
2493
                break;
2494
            case 'png':
2495
        header('Content-type: image/png');
2496
2497
        // *** Scale quality from 0-100 to 0-9
2498
        $scaleQuality = round(($imageQuality/100) * 9);
2499
2500
        // *** Invert qualit setting as 0 is best, not 9
2501
        $invertScaleQuality = 9 - $scaleQuality;
2502
2503
        imagepng($this->imageResized, '', $invertScaleQuality);
2504
        break;
2505
      case 'bmp':
2506
        echo 'bmp file format is not supported.';
2507
        break;
2508
2509
            // ... etc
2510
2511
            default:
2512
        // *** No extension - No save.
2513
                break;
2514
        }
2515
2516
    //imagedestroy($this->imageResized);
2517
  }
2518
2519
## --------------------------------------------------------
2520
2521
  public function setTransparency($bool)
2522
  # Sep 2011
2523
  {
2524
    $this->keepTransparency = $bool;
2525
  }
2526
2527
## --------------------------------------------------------
2528
2529
  public function setFillColor($value)
2530
  # Sep 2011
2531
    # Param in:   (mixed) $value: (array) Could be an array of RGB
2532
  #               (str) Could be hex #ffffff or #fff, fff, ffffff
2533
  #
2534
  # If the keepTransparency is set to false, then no transparency is to be used.
2535
  # This is ideal when you want to save as jpg.
2536
  #
2537
  # this method allows you to set the background color to use instead of
2538
  # transparency.
2539
  #
2540
  {
2541
    $colorArray = $this->formatColor($value);
2542
    $this->fillColorArray = $colorArray;
2543
  }
2544
2545
## --------------------------------------------------------
2546
2547
  public function setCropFromTop($value)
2548
  # Sep 2011
2549
  {
2550
    $this->cropFromTopPercent = $value;
2551
  }
2552
2553
## --------------------------------------------------------
2554
2555
    public function testGDInstalled()
2556
    # Author:     Jarrod Oberto
2557
    # Date:       27-02-08
2558
    # Purpose:    Test to see if GD is installed
2559
    # Param in:   n/a
2560
    # Param out:  (bool) True is gd extension loaded otherwise false
2561
    # Reference:
2562
    # Notes:
2563
    #
2564
    {
2565
        if(extension_loaded('gd') && function_exists('gd_info'))
2566
        {
2567
            $gdInstalled = true;
2568
        }
2569
        else
2570
        {
2571
            $gdInstalled = false;
2572
        }
2573
2574
        return $gdInstalled;
2575
    }
2576
2577
## --------------------------------------------------------
2578
2579
    public function testEXIFInstalled()
2580
    # Author:     Jarrod Oberto
2581
    # Date:       08-05-11
2582
    # Purpose:    Test to see if EXIF is installed
2583
    # Param in:   n/a
2584
    # Param out:  (bool) True is exif extension loaded otherwise false
2585
    # Reference:
2586
    # Notes:
2587
    #
2588
    {
2589
        if(extension_loaded('exif'))
2590
        {
2591
            $exifInstalled = true;
2592
        }
2593
        else
2594
        {
2595
            $exifInstalled = false;
2596
        }
2597
2598
        return $exifInstalled;
2599
    }
2600
2601
## --------------------------------------------------------
2602
2603
    public function testIsImage($image)
2604
    # Author:     Jarrod Oberto
2605
    # Date:       27-02-08
2606
    # Purpose:    Test if file is an image
2607
    # Param in:   n/a
2608
    # Param out:  n/a
2609
    # Reference:
2610
    # Notes:
2611
    #
2612
    {
2613
        if ($image)
2614
        {
2615
            $fileIsImage = true;
2616
        }
2617
        else
2618
        {
2619
            $fileIsImage = false;
2620
        }
2621
2622
        return $fileIsImage;
2623
    }
2624
2625
## --------------------------------------------------------
2626
2627
    public function testFunct()
2628
    # Author:     Jarrod Oberto
2629
    # Date:       27-02-08
2630
    # Purpose:    Test Function
2631
    # Param in:   n/a
2632
    # Param out:  n/a
2633
    # Reference:
2634
    # Notes:
2635
    #
2636
    {
2637
        echo $this->height;
2638
    }
2639
2640
## --------------------------------------------------------
2641
2642
    public function setForceStretch($value)
2643
    # Author:     Jarrod Oberto
2644
    # Date:       23-12-10
2645
    # Purpose:
2646
    # Param in:   (bool) $value
2647
    # Param out:  n/a
2648
    # Reference:
2649
    # Notes:
2650
    #
2651
    {
2652
        $this->forceStretch = $value;
2653
    }
2654
2655
## --------------------------------------------------------
2656
2657
    public function setFile($fileName)
2658
    # Author:     Jarrod Oberto
2659
    # Date:       28-02-08
2660
    # Purpose:
2661
    # Param in:   n/a
2662
    # Param out:  n/a
2663
    # Reference:
2664
    # Notes:
2665
    #
2666
    {
2667
        self::__construct($fileName);
2668
    }
2669
2670
## --------------------------------------------------------
2671
2672
  public function getFileName()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
2673
    # Author:     Jarrod Oberto
2674
    # Date:       10-09-08
2675
    # Purpose:
2676
    # Param in:   n/a
2677
    # Param out:  n/a
2678
    # Reference:
2679
    # Notes:
2680
    #
2681
    {
2682
      return $this->fileName;
2683
    }
2684
2685
## --------------------------------------------------------
2686
2687
  public function getHeight()
2688
    {
2689
      return $this->height;
2690
    }
2691
2692
## --------------------------------------------------------
2693
2694
  public function getWidth()
2695
    {
2696
      return $this->width;
2697
    }
2698
2699
## --------------------------------------------------------
2700
2701
  public function getOriginalHeight()
2702
    {
2703
      return $this->heightOriginal;
2704
    }
2705
2706
## --------------------------------------------------------
2707
2708
  public function getOriginalWidth()
2709
    {
2710
      return $this->widthOriginal;
2711
    }
2712
2713
## --------------------------------------------------------
2714
2715
  public function getErrors()
2716
    # Author:     Jarrod Oberto
2717
    # Date:       19-11-09
2718
    # Purpose:    Returns the error array
2719
    # Param in:   n/a
2720
    # Param out:  Array of errors
2721
    # Reference:
2722
    # Notes:
2723
    #
2724
  {
2725
    return $this->errorArray;
2726
  }
2727
2728
## --------------------------------------------------------
2729
2730
  private function checkInterlaceImage($isEnabled)
2731
  # jpg will use progressive (they don't use interace)
2732
  {
2733
    if ($isEnabled) {
2734
      imageinterlace($this->imageResized, $isEnabled);
2735
    }
2736
  }
2737
2738
## --------------------------------------------------------
2739
2740
  protected function formatColor($value)
2741
    # Author:     Jarrod Oberto
2742
    # Date:       09-05-11
2743
    # Purpose:    Determine color method passed in and return color as RGB
2744
    # Param in:   (mixed) $value: (array) Could be an array of RGB
2745
  #               (str) Could be hex #ffffff or #fff, fff, ffffff
2746
    # Param out:
2747
    # Reference:
2748
    # Notes:
2749
    #
2750
  {
2751
    $rgbArray = array();
2752
2753
    // *** If it's an array it should be R, G, B
2754
    if (is_array($value)) {
2755
2756
      if (key($value) == 0 && count($value) == 3) {
2757
2758
        $rgbArray['r'] = $value[0];
2759
        $rgbArray['g'] = $value[1];
2760
        $rgbArray['b'] = $value[2];
2761
2762
      } else {
2763
        $rgbArray = $value;
2764
      }
2765
    } else if (fix_strtolower($value) == 'transparent') {
2766
2767
      $rgbArray = array(
2768
        'r' => 255,
2769
        'g' => 255,
2770
        'b' => 255,
2771
        'a' => 127
2772
      );
2773
2774
    } else {
2775
2776
      // *** ...Else it should be hex. Let's make it RGB
2777
      $rgbArray = $this -> hex2dec($value);
2778
    }
2779
2780
    return $rgbArray;
2781
  }
2782
2783
  ## --------------------------------------------------------
2784
2785
  function hex2dec($hex)
2786
  # Purpose:  Convert #hex color to RGB
2787
  {
2788
    $color = str_replace('#', '', $hex);
2789
2790
    if (strlen($color) == 3) {
2791
      $color = $color . $color;
2792
    }
2793
2794
    $rgb = array(
2795
      'r' => hexdec(substr($color, 0, 2)),
2796
      'g' => hexdec(substr($color, 2, 2)),
2797
      'b' => hexdec(substr($color, 4, 2)),
2798
      'a' => 0
2799
    );
2800
2801
    return $rgb;
2802
  }
2803
2804
  ## --------------------------------------------------------
2805
2806
  private function createImageColor ($colorArray)
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
2807
  {
2808
    $r = $colorArray['r'];
2809
    $g = $colorArray['g'];
2810
    $b = $colorArray['b'];
2811
2812
    return imagecolorallocate($this->imageResized, $r, $g, $b);
2813
  }
2814
2815
  ## --------------------------------------------------------
2816
2817
  private function testColorExists($colorArray)
2818
  {
2819
    $r = $colorArray['r'];
2820
    $g = $colorArray['g'];
2821
    $b = $colorArray['b'];
2822
2823
    if (imagecolorexact($this->imageResized, $r, $g, $b) == -1) {
2824
      return false;
2825
    } else {
2826
      return true;
2827
    }
2828
  }
2829
2830
  ## --------------------------------------------------------
2831
2832
  private function findUnusedGreen()
2833
  # Purpose:  We find a green color suitable to use like green-screen effect.
2834
  #     Therefore, the color must not exist in the image.
2835
  {
2836
    $green = 255;
2837
2838
    do {
2839
2840
      $greenChroma = array(0, $green, 0);
2841
      $colorArray = $this->formatColor($greenChroma);
2842
      $match = $this->testColorExists($colorArray);
2843
      $green--;
2844
2845
    } while ($match == false && $green > 0);
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
2846
2847
    // *** If no match, just bite the bullet and use green value of 255
2848
    if (!$match) {
2849
      $greenChroma = array(0, $green, 0);
2850
    }
2851
2852
    return $greenChroma;
2853
  }
2854
2855
  ## --------------------------------------------------------
2856
2857
  private function findUnusedBlue()
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
2858
  # Purpose:  We find a green color suitable to use like green-screen effect.
2859
  #     Therefore, the color must not exist in the image.
2860
  {
2861
    $blue = 255;
2862
2863
    do {
2864
2865
      $blueChroma = array(0, 0, $blue);
2866
      $colorArray = $this->formatColor($blueChroma);
2867
      $match = $this->testColorExists($colorArray);
2868
      $blue--;
2869
2870
    } while ($match == false && $blue > 0);
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
2871
2872
    // *** If no match, just bite the bullet and use blue value of 255
2873
    if (!$match) {
2874
      $blueChroma = array(0, 0, $blue);
2875
    }
2876
2877
    return $blueChroma;
2878
  }
2879
2880
  ## --------------------------------------------------------
2881
2882
  private function invertTransparency($value, $originalMax, $invert=true)
2883
  # Purpose:  This does two things:
2884
  #       1) Convert the range from 0-127 to 0-100
2885
  #       2) Inverts value to 100 is not transparent while 0 is fully
2886
  #          transparent (like Photoshop)
2887
  {
2888
    // *** Test max range
2889
    if ($value > $originalMax) {
2890
      $value = $originalMax;
2891
    }
2892
2893
    // *** Test min range
2894
    if ($value < 0) {
2895
      $value = 0;
2896
    }
2897
2898
    if ($invert) {
2899
      return $originalMax - (($value/100) * $originalMax);
2900
    } else {
2901
      return ($value/100) * $originalMax;
2902
    }
2903
  }
2904
2905
  ## --------------------------------------------------------
2906
2907
  private function transparentImage($src)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
2908
  {
2909
    // *** making images with white bg transparent
2910
    $r1 = 0;
0 ignored issues
show
Unused Code introduced by
$r1 is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2911
    $g1 = 255;
0 ignored issues
show
Unused Code introduced by
$g1 is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2912
    $b1 = 0;
0 ignored issues
show
Unused Code introduced by
$b1 is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2913
    for ($x = 0; $x < imagesx($src); ++$x) {
2914
      for ($y = 0; $y < imagesy($src); ++$y) {
2915
        $color = imagecolorat($src, $x, $y);
2916
        $r = ($color >> 16) & 0xFF;
2917
        $g = ($color >> 8) & 0xFF;
2918
        $b = $color & 0xFF;
2919
        for ($i = 0; $i < 270; ++$i) {
2920
          //if ($r . $g . $b == ($r1 + $i) . ($g1 + $i) . ($b1 + $i)) {
2921
          if ($r == 0 && $g == 255 && $b == 0) {
2922
          //if ($g == 255) {
2923
            $trans_colour = imagecolorallocatealpha($src, 0, 0, 0, 127);
2924
            imagefill($src, $x, $y, $trans_colour);
2925
          }
2926
        }
2927
      }
2928
    }
2929
2930
    return $src;
2931
  }
2932
2933
  ## --------------------------------------------------------
2934
2935
  function checkStringStartsWith($needle, $haystack)
2936
  # Check if a string starts with a specific pattern
2937
  {
2938
    return (substr($haystack, 0, strlen($needle))==$needle);
2939
  }
2940
2941
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*-
2942
  BMP SUPPORT (SAVING) - James Heinrich
2943
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*/
2944
2945
  private function GD2BMPstring(&$gd_image)
2946
    # Author:     James Heinrich
2947
    # Purpose:    Save file as type bmp
2948
    # Param in:   The image canvas (passed as ref)
2949
    # Param out:
2950
    # Reference:
2951
    # Notes:    This code was stripped out of two external files
2952
  #       (phpthumb.bmp.php,phpthumb.functions.php) and added below to
2953
  #       avoid dependancies.
2954
    #
2955
  {
2956
    $imageX = ImageSX($gd_image);
2957
    $imageY = ImageSY($gd_image);
2958
2959
    $BMP = '';
2960
    for ($y = ($imageY - 1); $y >= 0; $y--) {
2961
      $thisline = '';
2962
      for ($x = 0; $x < $imageX; ++$x) {
2963
        $argb = $this->GetPixelColor($gd_image, $x, $y);
2964
        $thisline .= chr($argb['blue']).chr($argb['green']).chr($argb['red']);
2965
      }
2966
      while (strlen($thisline) % 4) {
2967
        $thisline .= "\x00";
2968
      }
2969
      $BMP .= $thisline;
2970
    }
2971
2972
    $bmpSize = strlen($BMP) + 14 + 40;
2973
    // BITMAPFILEHEADER [14 bytes] - http://msdn.microsoft.com/library/en-us/gdi/bitmaps_62uq.asp
2974
    $BITMAPFILEHEADER  = 'BM';                                    // WORD    bfType;
2975
    $BITMAPFILEHEADER .= $this->LittleEndian2String($bmpSize, 4); // DWORD   bfSize;
2976
    $BITMAPFILEHEADER .= $this->LittleEndian2String(       0, 2); // WORD    bfReserved1;
2977
    $BITMAPFILEHEADER .= $this->LittleEndian2String(       0, 2); // WORD    bfReserved2;
2978
    $BITMAPFILEHEADER .= $this->LittleEndian2String(      54, 4); // DWORD   bfOffBits;
2979
2980
    // BITMAPINFOHEADER - [40 bytes] http://msdn.microsoft.com/library/en-us/gdi/bitmaps_1rw2.asp
2981
    $BITMAPINFOHEADER  = $this->LittleEndian2String(      40, 4); // DWORD  biSize;
2982
    $BITMAPINFOHEADER .= $this->LittleEndian2String( $imageX, 4); // LONG   biWidth;
2983
    $BITMAPINFOHEADER .= $this->LittleEndian2String( $imageY, 4); // LONG   biHeight;
2984
    $BITMAPINFOHEADER .= $this->LittleEndian2String(       1, 2); // WORD   biPlanes;
2985
    $BITMAPINFOHEADER .= $this->LittleEndian2String(      24, 2); // WORD   biBitCount;
2986
    $BITMAPINFOHEADER .= $this->LittleEndian2String(       0, 4); // DWORD  biCompression;
2987
    $BITMAPINFOHEADER .= $this->LittleEndian2String(       0, 4); // DWORD  biSizeImage;
2988
    $BITMAPINFOHEADER .= $this->LittleEndian2String(    2835, 4); // LONG   biXPelsPerMeter;
2989
    $BITMAPINFOHEADER .= $this->LittleEndian2String(    2835, 4); // LONG   biYPelsPerMeter;
2990
    $BITMAPINFOHEADER .= $this->LittleEndian2String(       0, 4); // DWORD  biClrUsed;
2991
    $BITMAPINFOHEADER .= $this->LittleEndian2String(       0, 4); // DWORD  biClrImportant;
2992
2993
    return $BITMAPFILEHEADER.$BITMAPINFOHEADER.$BMP;
2994
  }
2995
2996
## --------------------------------------------------------
2997
2998
  private function GetPixelColor(&$img, $x, $y)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
2999
    # Author:     James Heinrich
3000
    # Purpose:
3001
    # Param in:
3002
    # Param out:
3003
    # Reference:
3004
    # Notes:
3005
    #
3006
  {
3007
    if (!is_resource($img)) {
3008
      return false;
3009
    }
3010
3011
    return @ImageColorsForIndex($img, @ImageColorAt($img, $x, $y));
3012
  }
3013
3014
## --------------------------------------------------------
3015
3016
  private function LittleEndian2String($number, $minbytes=1)
3017
    # Author:     James Heinrich
3018
    # Purpose:    BMP SUPPORT (SAVING)
3019
    # Param in:
3020
    # Param out:
3021
    # Reference:
3022
    # Notes:
3023
    #
3024
  {
3025
    $intstring = '';
3026
    while ($number > 0) {
3027
      $intstring = $intstring.chr($number & 255);
3028
      $number >>= 8;
3029
    }
3030
3031
    return str_pad($intstring, $minbytes, "\x00", STR_PAD_RIGHT);
3032
  }
3033
3034
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*-
3035
  BMP SUPPORT (READING)
3036
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*/
3037
3038
  private function ImageCreateFromBMP($filename)
3039
    # Author:     DHKold
3040
    # Date:     The 15th of June 2005
3041
  # Version:    2.0B
3042
    # Purpose:    To create an image from a BMP file.
3043
    # Param in:   BMP file to open.
3044
    # Param out:  Return a resource like the other ImageCreateFrom functions
3045
    # Reference:  http://us3.php.net/manual/en/function.imagecreate.php#53879
3046
  # Bug fix:    Author:   domelca at terra dot es
3047
  #       Date:   06 March 2008
3048
  #       Fix:    Correct 16bit BMP support
3049
    # Notes:
3050
  #
3051
  {
3052
3053
    //Ouverture du fichier en mode binaire
3054
    if (! $f1 = fopen($filename,"rb")) return FALSE;
3055
3056
    //1 : Chargement des ent�tes FICHIER
3057
    $FILE = unpack("vfile_type/Vfile_size/Vreserved/Vbitmap_offset", fread($f1,14));
3058
    if ($FILE['file_type'] != 19778) return FALSE;
3059
3060
    //2 : Chargement des ent�tes BMP
3061
    $BMP = unpack('Vheader_size/Vwidth/Vheight/vplanes/vbits_per_pixel'.
3062
           '/Vcompression/Vsize_bitmap/Vhoriz_resolution'.
3063
           '/Vvert_resolution/Vcolors_used/Vcolors_important', fread($f1,40));
3064
    $BMP['colors'] = pow(2,$BMP['bits_per_pixel']);
3065
3066
    if ($BMP['size_bitmap'] == 0) $BMP['size_bitmap'] = $FILE['file_size'] - $FILE['bitmap_offset'];
3067
3068
    $BMP['bytes_per_pixel'] = $BMP['bits_per_pixel']/8;
3069
    $BMP['bytes_per_pixel2'] = ceil($BMP['bytes_per_pixel']);
3070
    $BMP['decal'] = ($BMP['width']*$BMP['bytes_per_pixel']/4);
3071
       $BMP['decal'] -= floor($BMP['width']*$BMP['bytes_per_pixel']/4);
3072
    $BMP['decal'] = 4-(4*$BMP['decal']);
3073
3074
    if ($BMP['decal'] == 4) $BMP['decal'] = 0;
3075
3076
    //3 : Chargement des couleurs de la palette
3077
    $PALETTE = array();
3078
    if ($BMP['colors'] < 16777216)
3079
    {
3080
      $PALETTE = unpack('V'.$BMP['colors'], fread($f1,$BMP['colors']*4));
3081
    }
3082
3083
    //4 : Cr�ation de l'image
3084
    $IMG = fread($f1,$BMP['size_bitmap']);
3085
    $VIDE = chr(0);
3086
3087
    $res = imagecreatetruecolor($BMP['width'],$BMP['height']);
3088
    $P = 0;
3089
    $Y = $BMP['height']-1;
3090
    while ($Y >= 0)
3091
    {
3092
      $X=0;
3093
      while ($X < $BMP['width'])
3094
      {
3095
        if ($BMP['bits_per_pixel'] == 24)
3096
          $COLOR = unpack("V",substr($IMG,$P,3).$VIDE);
3097
        elseif ($BMP['bits_per_pixel'] == 16)
3098
        {
3099
3100
          /*
3101
           * BMP 16bit fix
3102
           * =================
3103
           *
3104
           * Ref: http://us3.php.net/manual/en/function.imagecreate.php#81604
3105
           *
3106
           * Notes:
3107
           * "don't work with bmp 16 bits_per_pixel. change pixel
3108
           * generator for this."
3109
           *
3110
           */
3111
3112
          // *** Original code (don't work)
3113
          //$COLOR = unpack("n",substr($IMG,$P,2));
3114
          //$COLOR[1] = $PALETTE[$COLOR[1]+1];
3115
3116
          $COLOR = unpack("v",substr($IMG,$P,2));
3117
          $blue = ($COLOR[1] & 0x001f) << 3;
3118
          $green = ($COLOR[1] & 0x07e0) >> 3;
3119
          $red = ($COLOR[1] & 0xf800) >> 8;
3120
          $COLOR[1] = $red * 65536 + $green * 256 + $blue;
3121
3122
        }
3123
        elseif ($BMP['bits_per_pixel'] == 8)
3124
        {
3125
          $COLOR = unpack("n",$VIDE.substr($IMG,$P,1));
3126
          $COLOR[1] = $PALETTE[$COLOR[1]+1];
3127
        }
3128
        elseif ($BMP['bits_per_pixel'] == 4)
3129
        {
3130
          $COLOR = unpack("n",$VIDE.substr($IMG,floor($P),1));
3131
          if (($P*2)%2 == 0) $COLOR[1] = ($COLOR[1] >> 4) ; else $COLOR[1] = ($COLOR[1] & 0x0F);
3132
          $COLOR[1] = $PALETTE[$COLOR[1]+1];
3133
        }
3134
        elseif ($BMP['bits_per_pixel'] == 1)
3135
        {
3136
          $COLOR = unpack("n",$VIDE.substr($IMG,floor($P),1));
3137
          if     (($P*8)%8 == 0) $COLOR[1] =  $COLOR[1]        >>7;
3138
          elseif (($P*8)%8 == 1) $COLOR[1] = ($COLOR[1] & 0x40)>>6;
3139
          elseif (($P*8)%8 == 2) $COLOR[1] = ($COLOR[1] & 0x20)>>5;
3140
          elseif (($P*8)%8 == 3) $COLOR[1] = ($COLOR[1] & 0x10)>>4;
3141
          elseif (($P*8)%8 == 4) $COLOR[1] = ($COLOR[1] & 0x8)>>3;
3142
          elseif (($P*8)%8 == 5) $COLOR[1] = ($COLOR[1] & 0x4)>>2;
3143
          elseif (($P*8)%8 == 6) $COLOR[1] = ($COLOR[1] & 0x2)>>1;
3144
          elseif (($P*8)%8 == 7) $COLOR[1] = ($COLOR[1] & 0x1);
3145
          $COLOR[1] = $PALETTE[$COLOR[1]+1];
3146
        }
3147
        else
3148
          return FALSE;
3149
3150
        imagesetpixel($res,$X,$Y,$COLOR[1]);
3151
        ++$X;
3152
        $P += $BMP['bytes_per_pixel'];
3153
      }
3154
3155
      $Y--;
3156
      $P+=$BMP['decal'];
3157
    }
3158
    //Fermeture du fichier
3159
    fclose($f1);
3160
3161
    return $res;
3162
  }
3163
3164
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*-
3165
  PSD SUPPORT (READING)
3166
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*/
3167
3168
  private function imagecreatefrompsd($fileName)
3169
  # Author:     Tim de Koning
3170
  # Version:    1.3
3171
  # Purpose:    To create an image from a PSD file.
3172
  # Param in:   PSD file to open.
3173
  # Param out:  Return a resource like the other ImageCreateFrom functions
3174
  # Reference:  http://www.kingsquare.nl/phppsdreader
3175
  # Notes:
3176
  #
3177
  {
3178
    if (file_exists($this->psdReaderPath)) {
3179
3180
      include_once($this->psdReaderPath);
3181
3182
      $psdReader = new PhpPsdReader($fileName);
3183
3184
      if (isset($psdReader->infoArray['error'])) return '';
3185
      else return $psdReader->getImage();
3186
    } else {
3187
      return false;
3188
    }
3189
  }
3190
3191
## --------------------------------------------------------
3192
3193
    public function __destruct() {
3194
    if (is_resource($this->imageResized)) {
3195
      imagedestroy($this->imageResized);
3196
    }
3197
  }
3198
3199
## --------------------------------------------------------
3200
3201
}
3202
3203
/*
3204
 *    Example with some API calls (outdated):
3205
 *
3206
 *
3207
 *      ===============================
3208
 *      Compulsary
3209
 *      ===============================
3210
 *
3211
 *      include("classes/resize_class.php");
3212
 *
3213
 *      // *** Initialise object
3214
 *      $magicianObj = new resize('images/cars/large/a.jpg');
3215
 *
3216
 *      // *** Turn off stretching (optional)
3217
 *      $magicianObj -> setForceStretch(false);
3218
 *
3219
 *      // *** Resize object
3220
 *      $magicianObj -> resizeImage(150, 100, 0);
3221
 *
3222
 *      ===============================
3223
 *      Image options - can run none, one, or all.
3224
 *      ===============================
3225
 *
3226
 *      //  *** Add watermark
3227
 *        $magicianObj -> addWatermark('stamp.png');
3228
 *
3229
 *          // *** Add text
3230
 *      $magicianObj -> addText('testing...');
3231
 *
3232
 *      ===============================
3233
 *      Output options - can run one, or the other, or both.
3234
 *      ===============================
3235
 *
3236
 *      // *** Save image to disk
3237
 *      $magicianObj -> saveImage('images/cars/large/b.jpg', 100);
3238
 *
3239
 *          // *** Or output to screen (params in can be jpg, gif, png)
3240
 *      $magicianObj -> displayImage('png');
3241
 *
3242
 *      ===============================
3243
 *      Return options - return errors. nice for debuggin.
3244
 *      ===============================
3245
 *
3246
 *      // *** Return error array
3247
 *      $errorArray = $magicianObj -> getErrors();
3248
 *
3249
 *
3250
 *      ===============================
3251
 *      Cleanup options - not really neccessary, but good practice
3252
 *      ===============================
3253
 *
3254
 *      // *** Free used memory
3255
 *      $magicianObj -> __destruct();
3256
 */;
3257