Completed
Pull Request — master (#106)
by Matheus
01:39 queued 28s
created

Pdf::getFileName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace Spatie\PdfToImage;
4
5
use Imagick;
6
use Spatie\PdfToImage\Exceptions\InvalidFormat;
7
use Spatie\PdfToImage\Exceptions\PdfDoesNotExist;
8
use Spatie\PdfToImage\Exceptions\PageDoesNotExist;
9
use Spatie\PdfToImage\Exceptions\InvalidLayerMethod;
10
11
class Pdf
12
{
13
    protected $pdfFile;
14
15
    protected $resolution = 144;
16
17
    protected $outputFormat = 'jpg';
18
19
    protected $page = 1;
20
21
    public $imagick;
22
23
    protected $numberOfPages;
24
25
    protected $validOutputFormats = ['jpg', 'jpeg', 'png'];
26
27
    protected $layerMethod = Imagick::LAYERMETHOD_FLATTEN;
28
29
    protected $colorspace;
30
31
    protected $compressionQuality;
32
33
    protected $fileName;
34
35
    /**
36
     * @param string $pdfFile The path or url to the pdffile.
37
     *
38
     * @throws \Spatie\PdfToImage\Exceptions\PdfDoesNotExist
39
     */
40
    public function __construct($pdfFile)
41
    {
42
        if (! filter_var($pdfFile, FILTER_VALIDATE_URL) && ! file_exists($pdfFile)) {
43
            throw new PdfDoesNotExist();
44
        }
45
46
        $this->imagick = new Imagick($pdfFile);
47
48
        $this->numberOfPages = $this->imagick->getNumberImages();
49
50
        $this->pdfFile = $pdfFile;
51
    }
52
53
    /**
54
     * Set the raster resolution.
55
     *
56
     * @param int $resolution
57
     *
58
     * @return $this
59
     */
60
    public function setResolution($resolution)
61
    {
62
        $this->resolution = $resolution;
63
64
        return $this;
65
    }
66
67
    /**
68
     * Set the output format.
69
     *
70
     * @param string $outputFormat
71
     *
72
     * @return $this
73
     *
74
     * @throws \Spatie\PdfToImage\Exceptions\InvalidFormat
75
     */
76
    public function setOutputFormat($outputFormat)
77
    {
78
        if (! $this->isValidOutputFormat($outputFormat)) {
79
            throw new InvalidFormat("Format {$outputFormat} is not supported");
80
        }
81
82
        $this->outputFormat = $outputFormat;
83
84
        return $this;
85
    }
86
87
    /**
88
     * Get the output format.
89
     *
90
     * @return string
91
     */
92
    public function getOutputFormat()
93
    {
94
        return $this->outputFormat;
95
    }
96
97
    /**
98
     * Sets the layer method for Imagick::mergeImageLayers()
99
     * If int, should correspond to a predefined LAYERMETHOD constant.
100
     * If null, Imagick::mergeImageLayers() will not be called.
101
     *
102
     * @param int|null
103
     *
104
     * @return $this
105
     *
106
     * @throws \Spatie\PdfToImage\Exceptions\InvalidLayerMethod
107
     *
108
     * @see https://secure.php.net/manual/en/imagick.constants.php
109
     * @see Pdf::getImageData()
110
     */
111
    public function setLayerMethod($layerMethod)
112
    {
113
        if (
114
            is_int($layerMethod) === false &&
115
            is_null($layerMethod) === false
116
        ) {
117
            throw new InvalidLayerMethod('LayerMethod must be an integer or null');
118
        }
119
120
        $this->layerMethod = $layerMethod;
121
122
        return $this;
123
    }
124
125
    /**
126
     * Determine if the given format is a valid output format.
127
     *
128
     * @param $outputFormat
129
     *
130
     * @return bool
131
     */
132
    public function isValidOutputFormat($outputFormat)
133
    {
134
        return in_array($outputFormat, $this->validOutputFormats);
135
    }
136
137
    /**
138
     * Set the page number that should be rendered.
139
     *
140
     * @param int $page
141
     *
142
     * @return $this
143
     *
144
     * @throws \Spatie\PdfToImage\Exceptions\PageDoesNotExist
145
     */
146
    public function setPage($page)
147
    {
148
        if ($page > $this->getNumberOfPages() || $page < 1) {
149
            throw new PageDoesNotExist("Page {$page} does not exist");
150
        }
151
152
        $this->page = $page;
153
154
        return $this;
155
    }
156
157
    /**
158
     * Get the number of pages in the pdf file.
159
     *
160
     * @return int
161
     */
162
    public function getNumberOfPages()
163
    {
164
        return $this->numberOfPages;
165
    }
166
167
    /**
168
     * Defines a custom name to save the file.
169
     *
170
     * @return $this
171
     */
172
    public function setFileName($fileName)
173
    {
174
        $this->fileName = $fileName;
175
176
        return $this;
177
    }
178
179
    /**
180
     * Returns the current file name that is going to be used to save the file.
181
     *
182
     * @return string|null
183
     */
184
    public function getFileName()
185
    {
186
        return $this->fileName;
187
    }
188
189
    /**
190
     * Save the image to the given path.
191
     *
192
     * @param string $pathToImage
193
     *
194
     * @return bool
195
     */
196
    public function saveImage($pathToImage)
197
    {
198
        if (is_dir($pathToImage)) {
199
            $fileName = $this->fileName ? $this->fileName : $this->page;
200
201
            $pathToImage = rtrim($pathToImage, '\/').DIRECTORY_SEPARATOR.$fileName.'.'.$this->outputFormat;
202
        }
203
204
        $imageData = $this->getImageData($pathToImage);
205
206
        return file_put_contents($pathToImage, $imageData) !== false;
207
    }
208
209
    /**
210
     * Save the file as images to the given directory.
211
     *
212
     * @param string $directory
213
     * @param string $prefix
214
     *
215
     * @return array $files the paths to the created images
216
     */
217
    public function saveAllPagesAsImages($directory, $prefix = '')
218
    {
219
        $numberOfPages = $this->getNumberOfPages();
220
221
        if ($numberOfPages === 0) {
222
            return [];
223
        }
224
225
        return array_map(function ($pageNumber) use ($directory, $prefix) {
226
            $this->setPage($pageNumber);
227
228
            $destination = "{$directory}/{$prefix}{$pageNumber}.{$this->outputFormat}";
229
230
            $this->saveImage($destination);
231
232
            return $destination;
233
        }, range(1, $numberOfPages));
234
    }
235
236
    /**
237
     * Return raw image data.
238
     *
239
     * @param string $pathToImage
240
     *
241
     * @return \Imagick
242
     */
243
    public function getImageData($pathToImage)
244
    {
245
        /*
246
         * Reinitialize imagick because the target resolution must be set
247
         * before reading the actual image.
248
         */
249
        $this->imagick = new Imagick();
250
251
        $this->imagick->setResolution($this->resolution, $this->resolution);
252
253
        if ($this->colorspace !== null) {
254
            $this->imagick->setColorspace($this->colorspace);
255
        }
256
257
        if ($this->compressionQuality !== null) {
258
            $this->imagick->setCompressionQuality($this->compressionQuality);
259
        }
260
261
        if (filter_var($this->pdfFile, FILTER_VALIDATE_URL)) {
262
            return $this->getRemoteImageData($pathToImage);
263
        }
264
265
        $this->imagick->readImage(sprintf('%s[%s]', $this->pdfFile, $this->page - 1));
266
267
        if (is_int($this->layerMethod)) {
268
            $this->imagick = $this->imagick->mergeImageLayers($this->layerMethod);
269
        }
270
271
        $this->imagick->setFormat($this->determineOutputFormat($pathToImage));
272
273
        return $this->imagick;
274
    }
275
276
    /**
277
     * @param int $colorspace
278
     *
279
     * @return $this
280
     */
281
    public function setColorspace(int $colorspace)
282
    {
283
        $this->colorspace = $colorspace;
284
285
        return $this;
286
    }
287
288
    /**
289
     * @param int $compressionQuality
290
     *
291
     * @return $this
292
     */
293
    public function setCompressionQuality(int $compressionQuality)
294
    {
295
        $this->compressionQuality = $compressionQuality;
296
297
        return $this;
298
    }
299
300
    /**
301
     * Return remote raw image data.
302
     *
303
     * @param string $pathToImage
304
     *
305
     * @return \Imagick
306
     */
307
    protected function getRemoteImageData($pathToImage)
308
    {
309
        $this->imagick->readImage($this->pdfFile);
310
311
        $this->imagick->setIteratorIndex($this->page - 1);
312
313
        if (is_int($this->layerMethod)) {
314
            $this->imagick = $this->imagick->mergeImageLayers($this->layerMethod);
315
        }
316
317
        $this->imagick->setFormat($this->determineOutputFormat($pathToImage));
318
319
        return $this->imagick;
320
    }
321
322
    /**
323
     * Determine in which format the image must be rendered.
324
     *
325
     * @param $pathToImage
326
     *
327
     * @return string
328
     */
329
    protected function determineOutputFormat($pathToImage)
330
    {
331
        $outputFormat = pathinfo($pathToImage, PATHINFO_EXTENSION);
332
333
        if ($this->outputFormat != '') {
334
            $outputFormat = $this->outputFormat;
335
        }
336
337
        $outputFormat = strtolower($outputFormat);
338
339
        if (! $this->isValidOutputFormat($outputFormat)) {
340
            $outputFormat = 'jpg';
341
        }
342
343
        return $outputFormat;
344
    }
345
}
346