Completed
Push — 2.0 ( 1bc459...d65881 )
by Rob
10s
created

AutoRotateFilterLoader::load()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 21
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 21
c 0
b 0
f 0
rs 8.7624
cc 6
eloc 10
nc 6
nop 2
1
<?php
2
3
/*
4
 * This file is part of the `liip/LiipImagineBundle` project.
5
 *
6
 * (c) https://github.com/liip/LiipImagineBundle/graphs/contributors
7
 *
8
 * For the full copyright and license information, please view the LICENSE.md
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Liip\ImagineBundle\Imagine\Filter\Loader;
13
14
use Imagine\Image\ImageInterface;
15
16
/**
17
 * AutoRotateFilterLoader - rotates an Image based on its EXIF Data.
18
 *
19
 * @author Robert Schönthal <[email protected]>
20
 */
21
class AutoRotateFilterLoader implements LoaderInterface
22
{
23
    protected $orientationKeys = [
24
        'exif.Orientation',
25
        'ifd0.Orientation',
26
    ];
27
28
    /**
29
     * {@inheritdoc}
30
     */
31
    public function load(ImageInterface $image, array $options = [])
32
    {
33
        if (null !== $orientation = $this->getOrientation($image)) {
34
            if ($orientation < 1 || $orientation > 8) {
35
                return $image;
36
            }
37
38
            // Rotates if necessary.
39
            $degree = $this->calculateRotation($orientation);
40
            if ($degree !== 0) {
41
                $image->rotate($degree);
42
            }
43
44
            // Flips if necessary.
45
            if ($this->isFlipped($orientation)) {
46
                $image->flipHorizontally();
47
            }
48
        }
49
50
        return $image;
51
    }
52
53
    /**
54
     * calculates to rotation degree from the EXIF Orientation.
55
     *
56
     * @param int $orientation
57
     *
58
     * @return int
59
     */
60
    private function calculateRotation($orientation)
61
    {
62
        switch ($orientation) {
63
            case 1:
64
            case 2:
65
                return 0;
66
            case 3:
67
            case 4:
68
                return 180;
69
            case 5:
70
            case 6:
71
                return 90;
72
            case 7:
73
            case 8:
74
                return -90;
75
        }
76
    }
77
78
    /**
79
     * @param ImageInterface $image
80
     *
81
     * @return int|null
82
     */
83
    private function getOrientation(ImageInterface $image)
84
    {
85
        foreach ($this->orientationKeys as $orientationKey) {
86
            $orientation = $image->metadata()->offsetGet($orientationKey);
87
88
            if ($orientation) {
89
                $image->metadata()->offsetSet($orientationKey, '1');
90
91
                return intval($orientation);
92
            }
93
        }
94
95
        return null;
96
    }
97
98
    /**
99
     * Returns true if the image is flipped, false otherwise.
100
     *
101
     * @param int $orientation
102
     *
103
     * @return bool
104
     */
105
    private function isFlipped($orientation)
106
    {
107
        return in_array((int) $orientation, [2, 4, 5, 7]);
108
    }
109
}
110