1: <?php
2:
3: /*
4: * The MIT License
5: *
6: * Copyright 2015 Richard Jedlička <jedlicka.r@gmail.com> (http://uiii.cz)
7: *
8: * Permission is hereby granted, free of charge, to any person obtaining a copy
9: * of this software and associated documentation files (the "Software"), to deal
10: * in the Software without restriction, including without limitation the rights
11: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12: * copies of the Software, and to permit persons to whom the Software is
13: * furnished to do so, subject to the following conditions:
14: *
15: * The above copyright notice and this permission notice shall be included in
16: * all copies or substantial portions of the Software.
17: *
18: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24: * THE SOFTWARE.
25: */
26:
27: namespace FieldtypePDF;
28:
29: use Imagick;
30:
31: /**
32: * PDF to image converter
33: */
34: class PDFConverter
35: {
36: /**
37: * @var array
38: */
39: public static $defaultOptions = array(
40: 'format' => 'JPEG',
41: 'extension' => 'jpg',
42: 'background' => '#FFFFFF',
43: 'resolution' => '300x300',
44: 'colorspace' => Imagick::COLORSPACE_RGB,
45: 'imagickOptions' => array(
46: 'pdf:use-cropbox=true'
47: ),
48: );
49:
50: /**
51: * @var array
52: */
53: protected $options;
54:
55: /**
56: *
57: * @var string
58: */
59: protected $pdfFilename;
60:
61: /**
62: * Constructor
63: *
64: * @param string $pdfFilename PDF file to be converted
65: * @param array $options Converter options (Optional)
66: * @see setOptions()
67: */
68: public function __construct($pdfFilename, $options = array())
69: {
70: $this->pdfFilename = $pdfFilename;
71: $this->setOptions($options);
72: }
73:
74: /**
75: * Set converter options
76: *
77: * @param array $options
78: *
79: * Available options are:
80: *
81: * - format (string) - format of the image
82: * - extension (string) - image file extension
83: * - background (string) - image background (used when the PDF's background is transparent),
84: * to leave the background transparent set NULL
85: * - resolution (string) - resolution used when reading the PDF (e.g. '300x300')
86: * - colorspace (int) - colorspace used when reading the PDF (Imagick::COLORSPACE_* constant)
87: * - imagickOptions (string[]) - ImageMagick options (each option in format 'key=value')
88: *
89: * For converter default options see {@link $defaultOptions}
90: */
91: public function setOptions(array $options)
92: {
93: $options = array_replace(self::$defaultOptions, $options);
94:
95: if (isset($options['resolution']) && $options['resolution']) {
96: $resolution = $options['resolution'];
97:
98: if (is_string($resolution)) {
99: $resolution = explode('x', $options['resolution']);
100: } elseif (is_numeric($resolution)) {
101: $resolution = array($resolution);
102: }
103:
104: if (is_array($resolution)) {
105: // append the resolution's second dimension if not set
106: if (count($resolution) === 1) {
107: $resolution[] = $resolution[0];
108: }
109:
110: $options['resolution'] = $resolution;
111: }
112: }
113:
114: if (isset($options['imagickOptions']) && ! is_array($options['imagickOptions'])) {
115: $options['imagickOptions'] = array($options['imagickOptions']);
116: }
117:
118: $this->options = $options;
119: }
120:
121: /**
122: * Get converter options
123: *
124: * @return array
125: */
126: public function getOptions()
127: {
128: return $this->options;
129: }
130:
131: /**
132: * Convert PDF to image specified by filename.
133: *
134: * @param int $page Number of PDF's page to be converted to image (indexed from 0)
135: * @param string $imageFilename Filename of output image
136: */
137: public function toImage($page, $imageFilename)
138: {
139: $options = $this->options;
140:
141: $imagick = new Imagick();
142: $backgroundImagick = new Imagick();
143:
144: if ($options['resolution']) {
145: $resolution = $options['resolution'];
146: $imagick->setResolution($resolution[0], $resolution[1]);
147: $backgroundImagick->setResolution($resolution[0], $resolution[1]);
148: }
149:
150: foreach($options['imagickOptions'] as $defition) {
151: $defition = explode('=', $defition);
152: $imagick->setOption($defition[0], $defition[1]);
153: }
154:
155: if ($options['colorspace']) {
156: $imagick->setColorspace($options['colorspace']);
157: }
158:
159: $imagick->readimage(sprintf('%s[%s]', $this->pdfFilename, $page));
160:
161: $image = $imagick;
162:
163: if ($options['background'] !== 'transparent') {
164: $backgroundImagick->newImage(
165: $imagick->getimagewidth(),
166: $imagick->getimageheight(),
167: $options['background']
168: );
169:
170: $backgroundImagick->compositeimage($imagick, Imagick::COMPOSITE_OVER, 0, 0);
171: $image = $backgroundImagick;
172: }
173:
174: $image->writeImage(sprintf('%s:%s', $options['format'], $imageFilename));
175:
176: $backgroundImagick->clear();
177: $imagick->clear();
178: }
179: }
180: