## Apache Zeta Components Manual :: File Source for converter.php

## Source for file converter.php

Documentation is available at converter.php

1. <?php
2. /**
3. * File containing the ezcImageConverter class.
4. *
5. * Licensed to the Apache Software Foundation (ASF) under one
6. * or more contributor license agreements. See the NOTICE file
7. * distributed with this work for additional information
8. * regarding copyright ownership. The ASF licenses this file
9. * to you under the Apache License, Version 2.0 (the
10. * "License"); you may not use this file except in compliance
11. * with the License. You may obtain a copy of the License at
12. *
13. * http://www.apache.org/licenses/LICENSE-2.0
14. *
15. * Unless required by applicable law or agreed to in writing,
16. * software distributed under the License is distributed on an
17. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18. * KIND, either express or implied. See the License for the
19. * specific language governing permissions and limitations
20. * under the License.
21. *
22. * @package ImageConversion
23. * @version //autogentag//
24. * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
25. * @filesource
26. */
28. /**
29. * Class to manage conversion and filtering of image files.
30. * This class is highly recommended to be used with an external
31. * singleton pattern to have just 1 converter in place over the whole
32. * application.
33. *
34. * As back-ends 2 handler classes are available, of which at least 1 has to be
35. * configured during the instantiation of the ezcImageConverter. Both handlers
36. * utilize different image manipulation tools and are capable of different
37. * sets of filters:
38. *
39. * <ul>
40. * <li>ezcImageGdHandler
41. * <ul>
42. * <li>Uses PHP's GD extension for image manipulation.</li>
43. * <li>Implements the following filter interfaces
44. * <ul>
45. * <li>{@link ezcImageGeometryFilters}</li>
46. * <li>{@link ezcImageColorspaceFilters}</li>
47. * </ul>
48. * </li>
49. * </ul>
50. * </li>
51. * <li>ezcImageImagemagickHandler
52. * <ul>
53. * <li>Uses the external "convert" program, contained in ImageMagick</li>
54. * <li>Implements the following interfaces:
55. * <ul>
56. * <li>{@link ezcImageGeometryFilters}</li>
57. * <li>{@link ezcImageColorspaceFilters}</li>
58. * <li>{@link ezcImageEffectFilters}</li>
59. * </ul>
60. * </li>
61. * </ul>
62. * </li>
63. * </ul>
64. *
65. * A general example, how to use ezcImageConversion to convert images:
66. * <code>
67. * // Prepare settings for ezcImageConverter
68. * // Defines the handlers to utilize and auto conversions.
69. * $settings = new ezcImageConverterSettings(
70. * array(
71. * new ezcImageHandlerSettings( 'GD', 'ezcImageGdHandler' ),
72. * new ezcImageHandlerSettings( 'ImageMagick', 'ezcImageImagemagickHandler' ),
73. * ),
74. * array(
75. * 'image/gif' => 'image/png',
76. * 'image/bmp' => 'image/jpeg',
77. * )
78. * );
79. *
80. * // Create the converter itself.
81. * $converter = new ezcImageConverter( $settings );
82. *
83. * // Define a transformation
84. * $filters = array(
85. * new ezcImageFilter(
86. * 'scaleWidth',
87. * array(
88. * 'width' => 100,
89. * 'direction' => ezcImageGeometryFilters::SCALE_BOTH,
90. * )
91. * ),
92. * new ezcImageFilter(
93. * 'colorspace',
94. * array(
95. * 'space' => ezcImageColorspaceFilters::COLORSPACE_GREY,
96. * )
97. * ),
98. * );
99. *
100. * // Which MIME types the conversion may output
101. * $mimeTypes = array( 'image/jpeg', 'image/png' );
102. *
103. * // Create the transformation inside the manager
104. * $converter->createTransformation( 'thumbnail', $filters, $mimeTypes );
105. *
106. * // Transform an image.
107. * $converter->transform( 'thumbnail', dirname(__FILE__).'/jpeg.jpg', dirname(__FILE__).'/jpeg_thumb.jpg' );
108. * </code>
109. *
110. * It's recommended to create only a single ezcImageConverter instance in your
111. * application to avoid creating multiple instances of it's internal objects.
112. * You can implement a singleton pattern for this, which might look similar to
113. * the following example:
114. * <code>
115. * function getImageConverterInstance()
116. * {
117. * if ( !isset( $GLOBALS['_ezcImageConverterInstance'] ) )
118. * {
119. * // Prepare settings for ezcImageConverter
120. * // Defines the handlers to utilize and auto conversions.
121. * $settings = new ezcImageConverterSettings(
122. * array(
123. * new ezcImageHandlerSettings( 'GD', 'ezcImageGdHandler' ),
124. * new ezcImageHandlerSettings( 'ImageMagick', 'ezcImageImagemagickHandler' ),
125. * ),
126. * array(
127. * 'image/gif' => 'image/png',
128. * 'image/bmp' => 'image/jpeg',
129. * )
130. * );
131. *
132. *
133. * // Create the converter itself.
134. * $converter = new ezcImageConverter( $settings );
135. *
136. * // Define a transformation
137. * $filters = array(
138. * new ezcImageFilter(
139. * 'scale',
140. * array(
141. * 'width' => 100,
142. * 'height' => 300,
143. * 'direction' => ezcImageGeometryFilters::SCALE_BOTH,
144. * )
145. * ),
146. * new ezcImageFilter(
147. * 'colorspace',
148. * array(
149. * 'space' => ezcImageColorspaceFilters::COLORSPACE_SEPIA,
150. * )
151. * ),
152. * new ezcImageFilter(
153. * 'border',
154. * array(
155. * 'width' => 5,
156. * 'color' => array(255, 0, 0),
157. * )
158. * ),
159. * );
160. *
161. * // Which MIME types the conversion may output
162. * $mimeTypes = array( 'image/jpeg', 'image/png' );
163. *
164. * // Create the transformation inside the manager
165. * $converter->createTransformation( 'funny', $filters, $mimeTypes );
166. *
167. * // Assign singleton instance
168. * $GLOBALS['_ezcImageConverterInstance'] = $converter;
169. * }
170. *
171. * // Return singleton instance
172. * return $GLOBALS['_ezcImageConverterInstance'];
173. * }
174. *
175. * // ...
176. * // Somewhere else in the code...
177. * // Transform an image.
178. * getImageConverterInstance()->transform( 'funny', dirname(__FILE__).'/jpeg.jpg', dirname(__FILE__).'/jpeg_singleton.jpg' );
179. *
180. * </code>
181. *
182. * @see ezcImageHandler
183. * @see ezcImageTransformation
184. *
185. * @package ImageConversion
186. * @version //autogentag//
187. * @mainclass
188. */
189. class ezcImageConverter
190. {
191. /**
192. * Manager settings
193. * Settings basis for all image manipulations.
194. *
195. * @var ezcImageConverterSettings
196. */
197. protected $settings ;
199. /**
200. * Keeps the handlers used by the converter.
201. *
202. * @var array(ezcImageHandler)
203. */
204. protected $handlers = array();
206. /**
207. * Stores transformation registered with this converter.
208. *
209. * @var array
210. */
211. protected $transformations = array();
213. /**
214. * Initialize converter with settings object.
215. * The ezcImageConverter can be directly instantiated, but it's
216. * highly recommended to use a manual singleton implementation
217. * to have just 1 instance of a ezcImageConverter per Request.
218. *
219. * ATTENTION: The ezcImageConverter does not support animated
220. * GIFs. Animated GIFs will simply be ignored by all filters and
221. * conversions.
222. *
223. * @param ezcImageConverterSettings $settings Settings for the converter.
224. *
225. * @throws ezcImageHandlerSettingsInvalidException
226. * If handler settings are invalid.
227. * @throws ezcImageMimeTypeUnsupportedException
228. * If a given MIME type is not supported.
229. */
230. public function __construct ( ezcImageConverterSettings $settings )
231. {
232. // Initialize handlers
233. foreach ( $settings->handlers as $i => $handlerSettings )
234. {
235. if ( !$handlerSettings instanceof ezcImageHandlerSettings )
236. {
237. throw new ezcImageHandlerSettingsInvalidException ();
238. }
239. $handlerClass = $handlerSettings->className;
240. if ( ! ezcBaseFeatures :: classExists ( $handlerClass ) )
241. {
242. throw new ezcImageHandlerNotAvailableException ( $handlerClass );
243. }
244. $handler = new $handlerClass( $handlerSettings );
245. $this-> handlers [$handlerSettings->referenceName] = $handler;
246. }
247. // Check implicit conversions
248. foreach ( $settings->conversions as $mimeIn => $mimeOut )
249. {
250. if ( !$this-> allowsInput ( $mimeIn ) )
251. {
252. throw new ezcImageMimeTypeUnsupportedException ( $mimeIn, 'input' );
253. }
254. if ( !$this-> allowsOutput ( $mimeOut ) )
255. {
256. throw new ezcImageMimeTypeUnsupportedException ( $mimeOut, 'output' );
257. }
258. }
259. $this-> settings = $settings;
260. }
262. /**
263. * Create a transformation in the manager.
264. *
265. * Creates a transformation and stores it in the manager. A reference to the
266. * transformation is returned by this method for further manipulation and
267. * to set options on it. The $name can later be used to remove a
268. * transfromation using {@link removeTransformation()} or to execute it
269. * using {@link transform()}. The $filters and $mimeOut parameters specify
270. * the transformation actions as described with {@link }
271. * ezcImageTransformation::__construct()}. The $saveOptions are used when
272. * the finally created image is saved and can configure compression and
273. * quality options.
274. *
275. * @param string $name Name for the transformation.
276. * @param array(ezcImageFilter) $filters Filters.
277. * @param array(string) $mimeOut Output MIME types.
278. * @param ezcImageSaveOptions $saveOptions Save options.
279. *
280. * @return ezcImageTransformation
281. *
282. * @throws ezcImageFiltersException
283. * If a given filter does not exist.
284. * @throws ezcImageTransformationAlreadyExists
285. * If a transformation with the given name does already exist.
286. */
287. public function createTransformation ( $name, array $filters, array $mimeOut, ezcImageSaveOptions $saveOptions = null )
288. {
289. if ( isset( $this->transformations[$name] ) )
290. {
291. throw new ezcImageTransformationAlreadyExistsException ( $name );
292. }
293. $this->transformations[$name] = new ezcImageTransformation( $this, $name, $filters, $mimeOut, $saveOptions );
294. return $this->transformations[$name];
295. }
297. /**
298. * Removes a transformation from the manager.
299. *
300. * @param string $name Name of the transformation to remove
301. *
302. * @return ezcImageTransformation The removed transformation
303. *
304. * @throws ezcImageTransformationNotAvailableExeption
305. * If the requested transformation is unknown.
306. */
307. public function removeTransformation ( $name )
308. {
309. if ( !isset( $this-> transformations [$name] ) )
310. {
311. throw new ezcImageTransformationNotAvailableException ( $name );
312. }
313. unset( $this-> transformations [$name] );
314. }
316. /**
317. * Apply transformation on a file.
318. * This applies the given transformation to the given file.
319. *
320. * @param string $name Name of the transformation to perform
321. * @param string $inFile The file to transform
322. * @param string $outFile The file to save transformed version to
323. *
324. * @throws ezcImageTransformationNotAvailableExeption
325. * If the requested transformation is unknown.
326. * @throws ezcImageTransformationException If an error occurs during the
327. * transformation. The returned exception contains the exception
328. * the problem resulted from in it's public $parent attribute.
329. * @throws ezcBaseFileNotFoundException If the file you are trying to
330. * transform does not exists.
331. * @throws ezcBaseFilePermissionException If the file you are trying to
332. * transform is not readable.
333. */
334. public function transform ( $name, $inFile, $outFile )
335. {
336. if ( !isset( $this-> transformations [$name] ) )
337. {
338. throw new ezcImageTransformationNotAvailableException ( $name );
339. }
340. $this-> transformations [$name]-> transform ( $inFile, $outFile );
341. }
343. /**
344. * Returns if a handler is found, supporting the given MIME type for output.
345. *
346. * @param string $mime The MIME type to check for.
347. * @return bool Whether the MIME type is supported.
348. */
349. public function allowsInput ( $mime )
350. {
351. foreach ( $this-> handlers as $handler )
352. {
353. if ( $handler-> allowsInput ( $mime ) )
354. {
355. return true;
356. }
357. }
358. return false;
359. }
361. /**
362. * Returns if a handler is found, supporting the given MIME type for output.
363. *
364. * @param string $mime The MIME type to check for.
365. * @return bool Whether the MIME type is supported.
366. */
367. public function allowsOutput ( $mime )
368. {
369. foreach ( $this-> handlers as $handler )
370. {
371. if ( $handler-> allowsOutput ( $mime ) )
372. {
373. return true;
374. }
375. }
376. return false;
377. }
379. /**
380. * Returns the MIME type that will be outputted for a given input type.
381. * Checks whether the given input type can be processed. If not, an
382. * exception is thrown. Checks then, if an implicit conversion for that
383. * MIME type is defined. If so, outputs the given output MIME type. In
384. * every other case, just outputs the MIME type given, because no
385. * conversion is implicitly required.
386. *
387. * @param string $mimeIn Input MIME type.
388. * @return string Output MIME type.
389. *
390. * @throws ezcImageMimeTypeUnsupportedException
391. * If the input MIME type is not supported.
392. */
393. public function getMimeOut ( $mimeIn )
394. {
395. if ( $this-> allowsInput ( $mimeIn ) === false )
396. {
397. throw new ezcImageMimeTypeUnsupportedException ( $mimeIn, 'input' );
398. }
399. if ( isset( $this-> settings ->conversions[$mimeIn] ) )
400. {
401. return $this-> settings ->conversions[$mimeIn];
402. }
403. return $mimeIn;
404. }
406. /**
407. * Returns if a given filter is available.
408. * Returns either an array of handler names this filter
409. * is available in or false if the filter is not enabled.
410. *
411. * @param string $name Name of the filter to query existance for
412. *
413. * @return mixed Array of handlers on success, otherwise false.
414. */
415. public function hasFilter ( $name )
416. {
417. foreach ( $this-> handlers as $handler )
418. {
419. if ( $handler-> hasFilter ( $name ) )
420. {
421. return true;
422. }
423. }
424. return false;
425. }
427. /**
428. * Returns a list of enabled filters.
429. * Gives you an overview on filters enabled in the manager.
430. * Format is:
431. * <code>
432. * array(
433. * '<filterName>',
434. * );
435. * </code>
436. *
437. * @return array(string)
438. */
439. public function getFilterNames ()
440. {
441. $filters = array();
442. foreach ( $this-> handlers as $handler )
443. {
444. $filters = array_merge ( $filters, $handler-> getFilterNames () );
445. }
446. return array_unique ( $filters );
447. }
449. /**
450. * Apply a single filter to an image.
451. * Applies just a single filter to an image. Optionally you can select
452. * a handler yourself, which is not recommended, but possible. If the
453. * specific handler does not have that filter, ImageConverter will try
454. * to fall back on another handler.
455. *
456. * @param ezcImageFilter $filter Filter object to apply.
457. * @param string $inFile Name of the input file.
458. * @param string $outFile Name of the output file.
459. * @param string $handlerName
460. * To choose a specific handler, this is the reference named passed
461. * to {@link ezcImageHandlerSettings}.
462. * @return void
463. *
464. *
465. * @throws ezcImageHandlerNotAvailableException
466. * If fitting handler is not available.
467. * @throws ezcImageFilterNotAvailableException
468. * If filter is not available.
469. * @throws ezcImageFileNameInvalidException
470. * If an invalid character (", ', $) is found in the file name.
471. */
472. public function applyFilter ( ezcImageFilter $filter, $inFile, $outFile, $handlerName = null )
473. {
474. $handlerObj = false;
475. // Do we have an explicit handler given?
476. if ( $handlerName !== null )
477. {
478. if ( !isset( $this-> handlers [$handlerName] ) )
479. {
480. throw new ezcImageHandlerNotAvailableException ( $handlerName );
481. }
482. if ( $this-> handlers [$handlerName]-> hasFilter ( $filter->name ) === true )
483. {
484. $handlerObj = $this-> handlers [$handlerName];
485. }
486. }
487. // Either no handler explicitly given or try to fall back.
488. if ( $handlerObj === false )
489. {
490. foreach ( $this-> handlers as $regHandler )
491. {
492. if ( $regHandler-> hasFilter ( $filter->name ) )
493. {
494. $handlerObj = $regHandler;
495. break;
496. }
497. }
498. }
499. // No handler found to apply filter with.
500. if ( $handlerObj === false )
501. {
502. throw new ezcImageFilterNotAvailableException ( $filter->name );
503. }
504. $imgRef = $handlerObj->load( $inFile );
505. $handlerObj-> applyFilter ( $imgRef, $filter );
506. $handlerObj->save( $imgRef, $outFile );
507. }
509. /**
510. * Returns a handler object for direct use.
511. * Returns the handler with the highest priority, that supports the given
512. * filter, MIME input type and MIME output type. All parameters are
513. * optional, if none is specified, the highest prioritized handler is
514. * returned.
515. *
516. * If no handler is found, that supports the criteria named, an exception
517. * of type {@link ezcImageHandlerNotAvailableException} will be thrown.
518. *
519. * @param string $filterName Name of the filter to search for.
520. * @param string $mimeIn Input MIME type.
521. * @param string $mimeOut Output MIME type.
522. *
523. * @return ezcImageHandler
524. *
525. * @throws ezcImageHandlerNotAvailableException
526. * If a handler for the given specification could not be found.
527. */
528. public function getHandler ( $filterName = null, $mimeIn = null, $mimeOut = null )
529. {
530. foreach ( $this-> handlers as $handler )
531. {
532. if ( ( !isset( $filterName ) || $handler-> hasFilter ( $filterName ) )
533. && ( !isset( $mimeIn ) || $handler-> allowsInput ( $mimeIn ) )
534. && ( !isset( $mimeOut ) || $handler-> allowsOutput ( $mimeOut ) )
535. )
536. {
537. return $handler;
538. }
539. }
540. throw new ezcImageHandlerNotAvailableException ( 'unknown' );
541. }
542. }
543. ?>

Documentation generated by phpDocumentor 1.4.3