PdfToImage::setPage()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 9
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

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

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

227
        $outputFormat = strtolower(/** @scrutinizer ignore-type */ $outputFormat);
Loading history...
228
229
        if (!$this->isValidOutputFormat($outputFormat)) {
230
            $outputFormat = 'jpg';
231
        }
232
233
        return $outputFormat;
234
    }
235
}
236