Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
58.33% covered (warning)
58.33%
35 / 60
57.14% covered (warning)
57.14%
12 / 21
CRAP
0.00% covered (danger)
0.00%
0 / 1
AbstractAdapter
58.33% covered (warning)
58.33%
35 / 60
57.14% covered (warning)
57.14%
12 / 21
176.75
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
9
 createResource
n/a
0 / 0
n/a
0 / 0
0
 getResource
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasResource
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getName
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getWidth
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getHeight
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getColorspace
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isIndexed
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getFormat
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getExif
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isGray
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isRgb
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isCmyk
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setAdjust
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 setDraw
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 setEffect
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 setFilter
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 setLayer
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 setType
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 sendHeaders
63.64% covered (warning)
63.64%
7 / 11
0.00% covered (danger)
0.00%
0 / 1
11.08
 __get
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
72
 load
n/a
0 / 0
n/a
0 / 0
0
 loadFromString
n/a
0 / 0
n/a
0 / 0
0
 create
n/a
0 / 0
n/a
0 / 0
0
 createIndex
n/a
0 / 0
n/a
0 / 0
0
 resizeToWidth
n/a
0 / 0
n/a
0 / 0
0
 resizeToHeight
n/a
0 / 0
n/a
0 / 0
0
 resize
n/a
0 / 0
n/a
0 / 0
0
 scale
n/a
0 / 0
n/a
0 / 0
0
 crop
n/a
0 / 0
n/a
0 / 0
0
 cropThumb
n/a
0 / 0
n/a
0 / 0
0
 rotate
n/a
0 / 0
n/a
0 / 0
0
 flip
n/a
0 / 0
n/a
0 / 0
0
 flop
n/a
0 / 0
n/a
0 / 0
0
 adjust
n/a
0 / 0
n/a
0 / 0
0
 filter
n/a
0 / 0
n/a
0 / 0
0
 layer
n/a
0 / 0
n/a
0 / 0
0
 draw
n/a
0 / 0
n/a
0 / 0
0
 effect
n/a
0 / 0
n/a
0 / 0
0
 type
n/a
0 / 0
n/a
0 / 0
0
 convert
n/a
0 / 0
n/a
0 / 0
0
 writeToFile
n/a
0 / 0
n/a
0 / 0
0
 outputToHttp
n/a
0 / 0
n/a
0 / 0
0
 destroy
n/a
0 / 0
n/a
0 / 0
0
 createColor
n/a
0 / 0
n/a
0 / 0
0
 __toString
n/a
0 / 0
n/a
0 / 0
0
1<?php
2/**
3 * Pop PHP Framework (http://www.popphp.org/)
4 *
5 * @link       https://github.com/popphp/popphp-framework
6 * @author     Nick Sagona, III <dev@nolainteractive.com>
7 * @copyright  Copyright (c) 2009-2023 NOLA Interactive, LLC. (http://www.nolainteractive.com)
8 * @license    http://www.popphp.org/license     New BSD License
9 */
10
11/**
12 * @namespace
13 */
14namespace Pop\Image\Adapter;
15
16use Pop\Image\Adjust;
17use Pop\Image\Color;
18use Pop\Image\Draw;
19use Pop\Image\Effect;
20use Pop\Image\Filter;
21use Pop\Image\Layer;
22use Pop\Image\Type;
23
24/**
25 * Abstract adapter class
26 *
27 * @category   Pop
28 * @package    Pop\Image
29 * @author     Nick Sagona, III <dev@nolainteractive.com>
30 * @copyright  Copyright (c) 2009-2023 NOLA Interactive, LLC. (http://www.nolainteractive.com)
31 * @license    http://www.popphp.org/license     New BSD License
32 * @version    3.4.0
33 */
34abstract class AbstractAdapter
35{
36
37    /**
38     * Colorspace constants
39     */
40    const IMAGE_GRAY = 1;
41    const IMAGE_RGB  = 2;
42    const IMAGE_CMYK = 3;
43
44    /**
45     * Image resource
46     * @var mixed
47     */
48    protected $resource = null;
49
50    /**
51     * Image name
52     * @var string
53     */
54    protected $name = 'pop-image.jpg';
55
56    /**
57     * Image width
58     * @var int
59     */
60    protected $width = 640;
61
62    /**
63     * Image height
64     * @var int
65     */
66    protected $height = 480;
67
68    /**
69     * Image format
70     * @var string
71     */
72    protected $format = 'jpg';
73
74    /**
75     * Image colorspace
76     * @var int
77     */
78    protected $colorspace = 2;
79
80    /**
81     * Index color flag
82     * @var boolean
83     */
84    protected $indexed = false;
85
86    /**
87     * EXIF data
88     * @var array
89     */
90    protected $exif = [];
91
92    /**
93     * Image adjust object
94     * @var Adjust\AdjustInterface
95     */
96    protected $adjust = null;
97
98    /**
99     * Image draw object
100     * @var Draw\DrawInterface
101     */
102    protected $draw = null;
103
104    /**
105     * Image effect object
106     * @var Effect\EffectInterface
107     */
108    protected $effect = null;
109
110    /**
111     * Image filter object
112     * @var Filter\FilterInterface
113     */
114    protected $filter = null;
115
116    /**
117     * Image layer object
118     * @var Layer\LayerInterface
119     */
120    protected $layer = null;
121
122    /**
123     * Image type object
124     * @var Type\TypeInterface
125     */
126    protected $type = null;
127
128    /**
129     * Constructor
130     *
131     * Instantiate an image object based on either a pre-existing image
132     * file on disk, or a new image file.
133     *
134     */
135    public function __construct()
136    {
137        $args = func_get_args();
138
139        $this->createResource();
140
141        // $image
142        if (isset($args[0]) && !is_numeric($args[0]) && file_exists($args[0])) {
143            $this->name = $args[0];
144            $this->load();
145        // $width, $height, $name
146        } else if ((count($args) >= 2) && is_numeric($args[0]) && is_numeric($args[1])) {
147            $this->width  = $args[0];
148            $this->height = $args[1];
149            if (isset($args[2]) && !is_numeric($args[2])) {
150                $this->name = $args[2];
151            }
152            $this->create();
153        }
154    }
155
156    /**
157     * Create the image resource
158     *
159     * @return void
160     */
161    abstract public function createResource();
162
163    /**
164     * Get the image resource
165     *
166     * @return resource
167     */
168    public function getResource()
169    {
170        return $this->resource;
171    }
172
173    /**
174     * Determine if there is an image resource
175     *
176     * @return boolean
177     */
178    public function hasResource()
179    {
180        return (null !== $this->resource);
181    }
182
183    /**
184     * Get the image name
185     *
186     * @return string
187     */
188    public function getName()
189    {
190        return $this->name;
191    }
192
193    /**
194     * Get the image width
195     *
196     * @return int
197     */
198    public function getWidth()
199    {
200        return $this->width;
201    }
202
203    /**
204     * Get the image height
205     *
206     * @return int
207     */
208    public function getHeight()
209    {
210        return $this->height;
211    }
212
213    /**
214     * Get the colorspace
215     *
216     * @return int
217     */
218    public function getColorspace()
219    {
220        return $this->colorspace;
221    }
222
223    /**
224     * Determine if the image is index color
225     *
226     * @return boolean
227     */
228    public function isIndexed()
229    {
230        return $this->indexed;
231    }
232
233    /**
234     * Get the image format
235     *
236     * @return string
237     */
238    public function getFormat()
239    {
240        return $this->format;
241    }
242
243    /**
244     * Get the image EXIF data
245     *
246     * @return array
247     */
248    public function getExif()
249    {
250        return $this->exif;
251    }
252
253    /**
254     * Determine if the image is grayscale
255     *
256     * @return boolean
257     */
258    public function isGray()
259    {
260        return ($this->colorspace == self::IMAGE_GRAY);
261    }
262
263    /**
264     * Determine if the image is RGB
265     *
266     * @return boolean
267     */
268    public function isRgb()
269    {
270        return ($this->colorspace == self::IMAGE_RGB);
271    }
272
273    /**
274     * Determine if the image is CMYK
275     *
276     * @return boolean
277     */
278    public function isCmyk()
279    {
280        return ($this->colorspace == self::IMAGE_CMYK);
281    }
282
283    /**
284     * Set the image adjust object
285     *
286     * @param  Adjust\AdjustInterface $adjust
287     * @return AbstractAdapter
288     */
289    public function setAdjust(Adjust\AdjustInterface $adjust)
290    {
291        $this->adjust = $adjust;
292        return $this;
293    }
294
295    /**
296     * Set the image draw object
297     *
298     * @param  Draw\DrawInterface $draw
299     * @return AbstractAdapter
300     */
301    public function setDraw(Draw\DrawInterface $draw)
302    {
303        $this->draw = $draw;
304        return $this;
305    }
306
307    /**
308     * Set the image effect object
309     *
310     * @param  Effect\EffectInterface $effect
311     * @return AbstractAdapter
312     */
313    public function setEffect(Effect\EffectInterface $effect)
314    {
315        $this->effect = $effect;
316        return $this;
317    }
318
319    /**
320     * Set the image filter object
321     *
322     * @param  Filter\FilterInterface $filter
323     * @return AbstractAdapter
324     */
325    public function setFilter(Filter\FilterInterface $filter)
326    {
327        $this->filter = $filter;
328        return $this;
329    }
330    /**
331     * Set the image layer object
332     *
333     * @param  Layer\LayerInterface $layer
334     * @return AbstractAdapter
335     */
336    public function setLayer(Layer\LayerInterface $layer)
337    {
338        $this->layer = $layer;
339        return $this;
340    }
341
342    /**
343     * Set the image type object
344     *
345     * @param  Type\TypeInterface $type
346     * @return AbstractAdapter
347     */
348    public function setType(Type\TypeInterface $type)
349    {
350        $this->type = $type;
351        return $this;
352    }
353
354    /**
355     * Send image headers the image
356     *
357     * @param  string  $to
358     * @param  boolean $download
359     * @param  array   $additionalHeaders
360     * @return void
361     */
362    public function sendHeaders($to = null, $download = false, array $additionalHeaders = [])
363    {
364        if (null === $to) {
365            $to = (null !== $this->name) ? basename($this->name) : 'pop-image.' . $this->format;
366        }
367
368        // Determine if the force download argument has been passed.
369        $headers = [
370            'Content-type'        => 'image/' . (($this->format == 'jpg') ? 'jpeg' : $this->format),
371            'Content-disposition' => (($download) ? 'attachment; ' : null) . 'filename=' . $to
372        ];
373
374        if (!empty($additionalHeaders)) {
375            $headers = $headers + $additionalHeaders;
376        }
377
378        // Send the headers and output the image
379        if (!headers_sent()) {
380            header('HTTP/1.1 200 OK');
381            foreach ($headers as $name => $value) {
382                header($name . ': ' . $value);
383            }
384        }
385    }
386
387    /**
388     * Magic get method to return a manipulation object
389     *
390     * @param  string $name
391     * @return mixed
392     */
393    public function __get($name)
394    {
395        switch ($name) {
396            case 'adjust':
397                return $this->adjust();
398            case 'filter':
399                return $this->filter();
400            case 'layer':
401                return $this->layer();
402            case 'draw':
403                return $this->draw();
404            case 'effect':
405                return $this->effect();
406            case 'type':
407                return $this->type();
408            default:
409                return null;
410        }
411    }
412
413    /**
414     * Load the image resource from the existing image file
415     *
416     * @param  string $name
417     * @return AbstractAdapter
418     */
419    abstract public function load($name = null);
420
421    /**
422     * Load the image resource from data
423     *
424     * @param  string $data
425     * @param  string $name
426     * @return AbstractAdapter
427     */
428    abstract public function loadFromString($data, $name = null);
429
430    /**
431     * Create a new image resource
432     *
433     * @param  int    $width
434     * @param  int    $height
435     * @param  string $name
436     * @return AbstractAdapter
437     */
438    abstract public function create($width = null, $height = null, $name = null);
439
440    /**
441     * Create a new indexed image resource
442     *
443     * @param  int    $width
444     * @param  int    $height
445     * @param  string $name
446     * @return AbstractAdapter
447     */
448    abstract public function createIndex($width = null, $height = null, $name = null);
449
450    /**
451     * Resize the image object to the width parameter passed
452     *
453     * @param  int $w
454     * @return AbstractAdapter
455     */
456    abstract public function resizeToWidth($w);
457
458    /**
459     * Resize the image object to the height parameter passed
460     *
461     * @param  int $h
462     * @return AbstractAdapter
463     */
464    abstract public function resizeToHeight($h);
465
466    /**
467     * Resize the image object, allowing for the largest dimension
468     * to be scaled to the value of the $px argument.
469     *
470     * @param  int $px
471     * @return AbstractAdapter
472     */
473    abstract public function resize($px);
474
475    /**
476     * Scale the image object, allowing for the dimensions to be scaled
477     * proportionally to the value of the $scl argument.
478     *
479     * @param  float $scale
480     * @return AbstractAdapter
481     */
482    abstract public function scale($scale);
483
484    /**
485     * Crop the image object to a image whose dimensions are based on the
486     * value of the $wid and $hgt argument. The optional $x and $y arguments
487     * allow for the adjustment of the crop to select a certain area of the
488     * image to be cropped.
489     *
490     * @param  int $w
491     * @param  int $h
492     * @param  int $x
493     * @param  int $y
494     * @return AbstractAdapter
495     */
496    abstract public function crop($w, $h, $x = 0, $y = 0);
497
498    /**
499     * Crop the image object to a square image whose dimensions are based on the
500     * value of the $px argument. The optional $offset argument allows for the
501     * adjustment of the crop to select a certain area of the image to be cropped.
502     *
503     * @param  int $px
504     * @param  int $offset
505     * @return AbstractAdapter
506     */
507    abstract public function cropThumb($px, $offset = null);
508
509    /**
510     * Rotate the image object
511     *
512     * @param  int                  $degrees
513     * @param  Color\ColorInterface $bgColor
514     * @throws Exception
515     * @return Gd
516     */
517    abstract public function rotate($degrees, Color\ColorInterface $bgColor = null);
518
519    /**
520     * Method to flip the image over the x-axis
521     *
522     * @return AbstractAdapter
523     */
524    abstract public function flip();
525
526    /**
527     * Method to flip the image over the y-axis
528     *
529     * @return AbstractAdapter
530     */
531    abstract public function flop();
532
533    /**
534     * Get the image adjust object
535     *
536     * @return Adjust\AdjustInterface
537     */
538    abstract public function adjust();
539
540    /**
541     * Get the image filter object
542     *
543     * @return Filter\FilterInterface
544     */
545    abstract public function filter();
546
547    /**
548     * Get the image layer object
549     *
550     * @return Layer\LayerInterface
551     */
552    abstract public function layer();
553
554    /**
555     * Get the image draw object
556     *
557     * @return Draw\DrawInterface
558     */
559    abstract public function draw();
560
561    /**
562     * Get the image effect object
563     *
564     * @return Effect\EffectInterface
565     */
566    abstract public function effect();
567
568    /**
569     * Get the image type object
570     *
571     * @return Type\TypeInterface
572     */
573    abstract public function type();
574
575    /**
576     * Convert the image object to another format
577     *
578     * @param  string $type
579     * @throws Exception
580     * @return AbstractAdapter
581     */
582    abstract public function convert($type);
583
584    /**
585     * Write the image object to a file on disk
586     *
587     * @param  string $to
588     * @param  int    $quality
589     * @throws Exception
590     * @return void
591     */
592    abstract public function writeToFile($to = null, $quality = 100);
593
594    /**
595     * Output the image object directly to HTTP
596     *
597     * @param  int     $quality
598     * @param  string  $to
599     * @param  boolean $download
600     * @param  boolean $sendHeaders
601     * @throws Exception
602     * @return void
603     */
604    abstract public function outputToHttp($quality = 100, $to = null, $download = false, $sendHeaders = true);
605
606    /**
607     * Destroy the image object and the related image file directly
608     *
609     * @param  boolean $delete
610     * @return void
611     */
612    abstract public function destroy($delete = false);
613
614    /**
615     * Create and return a color.
616     *
617     * @param  Color\ColorInterface $color
618     * @param  int                  $alpha
619     * @throws Exception
620     * @return mixed
621     */
622    abstract public function createColor(Color\ColorInterface $color = null, $alpha = 100);
623
624    /**
625     * Output the image
626     *
627     * @return string
628     */
629    abstract public function __toString();
630
631}