Completed
Pull Request — master (#155)
by
unknown
01:01
created

Pdf::setAlphaChannel()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
namespace Spatie\PdfToImage;
4
5
use Imagick;
6
use Spatie\PdfToImage\Exceptions\InvalidFormat;
7
use Spatie\PdfToImage\Exceptions\PageDoesNotExist;
8
use Spatie\PdfToImage\Exceptions\PdfDoesNotExist;
9
10
class Pdf
11
{
12
    protected $pdfFile;
13
14
    protected $resolution = 144;
15
16
    protected $outputFormat = 'jpg';
17
18
    protected $page = 1;
19
20
    public $imagick;
21
22
    protected $numberOfPages;
23
24
    protected $validOutputFormats = ['jpg', 'jpeg', 'png'];
25
26
    protected $layerMethod = Imagick::LAYERMETHOD_FLATTEN;
27
    
28
    protected $alphaChannel;
29
30
    protected $colorspace;
31
32
    protected $compressionQuality;
33
34
    public function __construct(string $pdfFile)
35
    {
36
        if (! file_exists($pdfFile)) {
37
            throw new PdfDoesNotExist("File `{$pdfFile}` does not exist");
38
        }
39
40
        $this->imagick = new Imagick();
41
42
        $this->imagick->pingImage($pdfFile);
43
44
        $this->numberOfPages = $this->imagick->getNumberImages();
45
46
        $this->pdfFile = $pdfFile;
47
    }
48
49
    public function setResolution(int $resolution)
50
    {
51
        $this->resolution = $resolution;
52
53
        return $this;
54
    }
55
56
    public function setOutputFormat(string $outputFormat)
57
    {
58
        if (! $this->isValidOutputFormat($outputFormat)) {
59
            throw new InvalidFormat("Format {$outputFormat} is not supported");
60
        }
61
62
        $this->outputFormat = $outputFormat;
63
64
        return $this;
65
    }
66
67
    public function getOutputFormat(): string
68
    {
69
        return $this->outputFormat;
70
    }
71
72
    /**
73
     * Sets the layer method for Imagick::mergeImageLayers()
74
     * If int, should correspond to a predefined LAYERMETHOD constant.
75
     * If null, Imagick::mergeImageLayers() will not be called.
76
     *
77
     * @param int|null
78
     *
79
     * @return $this
80
     *
81
     * @throws \Spatie\PdfToImage\Exceptions\InvalidLayerMethod
82
     *
83
     * @see https://secure.php.net/manual/en/imagick.constants.php
84
     * @see Pdf::getImageData()
85
     */
86
    public function setLayerMethod(?int $layerMethod)
87
    {
88
        $this->layerMethod = $layerMethod;
89
90
        return $this;
91
    }
92
    
93
    public function setAlphaChannel(?int $alphaChannel)
94
    {
95
        $this->alphaChannel = $alphaChannel;
96
        
97
        return $this;
98
    }
99
100
    public function isValidOutputFormat(string $outputFormat): bool
101
    {
102
        return in_array($outputFormat, $this->validOutputFormats);
103
    }
104
105
    public function setPage(int $page)
106
    {
107
        if ($page > $this->getNumberOfPages() || $page < 1) {
108
            throw new PageDoesNotExist("Page {$page} does not exist");
109
        }
110
111
        $this->page = $page;
112
113
        return $this;
114
    }
115
116
    public function getNumberOfPages(): int
117
    {
118
        return $this->numberOfPages;
119
    }
120
121
    public function saveImage(string $pathToImage): bool
122
    {
123
        if (is_dir($pathToImage)) {
124
            $pathToImage = rtrim($pathToImage, '\/').DIRECTORY_SEPARATOR.$this->page.'.'.$this->outputFormat;
125
        }
126
127
        $imageData = $this->getImageData($pathToImage);
128
129
        return file_put_contents($pathToImage, $imageData) !== false;
130
    }
131
132
    public function saveAllPagesAsImages(string $directory, string $prefix = ''): array
133
    {
134
        $numberOfPages = $this->getNumberOfPages();
135
136
        if ($numberOfPages === 0) {
137
            return [];
138
        }
139
140
        return array_map(function ($pageNumber) use ($directory, $prefix) {
141
            $this->setPage($pageNumber);
142
143
            $destination = "{$directory}/{$prefix}{$pageNumber}.{$this->outputFormat}";
144
145
            $this->saveImage($destination);
146
147
            return $destination;
148
        }, range(1, $numberOfPages));
149
    }
150
151
    public function getImageData(string $pathToImage): Imagick
152
    {
153
        /*
154
         * Reinitialize imagick because the target resolution must be set
155
         * before reading the actual image.
156
         */
157
        $this->imagick = new Imagick();
158
159
        $this->imagick->setResolution($this->resolution, $this->resolution);
160
161
        if ($this->colorspace !== null) {
162
            $this->imagick->setColorspace($this->colorspace);
163
        }
164
        
165
        if ($this->alphaChannel !== null) {
166
            $this->imagick->setImageAlphaChannel($this->alphaChannel);
167
        }
168
169
        if ($this->compressionQuality !== null) {
170
            $this->imagick->setCompressionQuality($this->compressionQuality);
171
        }
172
173
        if (filter_var($this->pdfFile, FILTER_VALIDATE_URL)) {
174
            return $this->getRemoteImageData($pathToImage);
175
        }
176
177
        $this->imagick->readImage(sprintf('%s[%s]', $this->pdfFile, $this->page - 1));
178
179
        if (is_int($this->layerMethod)) {
180
            $this->imagick = $this->imagick->mergeImageLayers($this->layerMethod);
181
        }
182
183
        $this->imagick->setFormat($this->determineOutputFormat($pathToImage));
184
185
        return $this->imagick;
186
    }
187
188
    public function setColorspace(int $colorspace)
189
    {
190
        $this->colorspace = $colorspace;
191
192
        return $this;
193
    }
194
195
    public function setCompressionQuality(int $compressionQuality)
196
    {
197
        $this->compressionQuality = $compressionQuality;
198
199
        return $this;
200
    }
201
202
    protected function getRemoteImageData(string $pathToImage): Imagick
203
    {
204
        $this->imagick->readImage($this->pdfFile);
205
206
        $this->imagick->setIteratorIndex($this->page - 1);
207
208
        if (is_int($this->layerMethod)) {
209
            $this->imagick = $this->imagick->mergeImageLayers($this->layerMethod);
210
        }
211
212
        $this->imagick->setFormat($this->determineOutputFormat($pathToImage));
213
214
        return $this->imagick;
215
    }
216
217
    protected function determineOutputFormat(string $pathToImage): string
218
    {
219
        $outputFormat = pathinfo($pathToImage, PATHINFO_EXTENSION);
220
221
        if ($this->outputFormat != '') {
222
            $outputFormat = $this->outputFormat;
223
        }
224
225
        $outputFormat = strtolower($outputFormat);
226
227
        if (! $this->isValidOutputFormat($outputFormat)) {
228
            $outputFormat = 'jpg';
229
        }
230
231
        return $outputFormat;
232
    }
233
}
234