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

## Source for file transformation.php

Documentation is available at transformation.php

1. <?php
2. /**
3. * File containing the ezcImageTransformation 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. * @see ezcImageConverter
23. *
24. * @package ImageConversion
25. * @version //autogentag//
26. * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
27. * @filesource
28. */
30. /**
31. * Provides transformations on images using filters and MIME conversions.
32. * Objects of this class group MIME type conversion and filtering of images
33. * into transformations of images. Transformations can be chained by referencing
34. * to another transformation so that multiple transformations will be produced
35. * after each other.
36. *
37. * <code>
38. * $filters = array(
39. * new ezcImageFilter( 'scaleDownByWidth',
40. * array(
41. * 'width' => 100
42. * )
43. * ),
44. * new ezcImageFilter( 'crop',
45. * array(
46. * 'x' => 0,
47. * 'y' => 0,
48. * 'width' => 100,
49. * 'height' => 100,
50. * )
51. * ),
52. * );
53. * $mimeTypes = array( 'image/jpeg', 'image/png' );
54. *
55. * // ezcImageTransformation object returned for further manipulation
56. * $thumbnail = $converter->createTransformation(
57. * 'thumbnail',
58. * $filters,
59. * $mimeTypes
60. * );
61. *
62. * $converter->transform( 'thumbnail', 'var/storage/myOriginal1.jpg',
63. * 'var/storage/myThumbnail1' ); // res: image/jpeg
64. * $converter->transform( 'thumbnail', 'var/storage/myOriginal2.png',
65. * 'var/storage/myThumbnail2' ); // res: image/png
66. * $converter->transform( 'thumbnail', 'var/storage/myOriginal3.gif',
67. * 'var/storage/myThumbnail3' ); // res: image/.png
68. *
69. * // Animated GIF, will simply be copied!
70. * $converter->transform( 'thumbnail', 'var/storage/myOriginal4.gif',
71. * 'var/storage/myThumbnail4' ); // res: image/gif
72. * </code>
73. *
74. * @see ezcImageConverter
75. *
76. * @package ImageConversion
77. * @version //autogentag//
78. */
79. class ezcImageTransformation
80. {
81. /**
82. * Array of MIME types allowed as output for this transformation.
83. * Leave empty, for all MIME types to be allowed.
84. *
85. * @var array(string)
86. */
87. protected $mimeOut ;
89. /**
90. * Stores the filters utilized by a transformation.
91. *
92. * @var array(ezcImageFilter)
93. */
94. protected $filters ;
96. /**
97. * Stores the name of this transformation.
98. *
99. * @var string
100. */
101. protected $name ;
103. /**
104. * The ezcImageConverter
105. *
106. * @var ezcImageConverter
107. */
108. protected $converter ;
110. /**
111. * The handler last used for filtering.
112. *
113. * @var ezcImageHandler
114. */
115. protected $lastHandler ;
117. /**
118. * Options for the final save step.
119. *
120. * @var ezcSaveOptions
121. */
122. protected $saveOptions ;
124. /**
125. * Initialize transformation.
126. *
127. * @param ezcImageConverter $converter The global converter.
128. * @param string $name Name for the transformation.
129. * @param array(ezcImageFilter) $filters Filters to apply.
130. * @param array(string) $mimeOut Output MIME types.
131. * @param ezcImageSaveOptions $saveOptions Options for saving images.
132. *
133. * @throws ezcImageFiltersException
134. * On invalid filter or filter settings error.
135. * @throws ezcImageMimeTypeUnsupportedException
136. * If the output type is unsupported.
137. */
138. public function __construct ( ezcImageConverter $converter, $name, array $filters = array(), array $mimeOut = array(), ezcImageSaveOptions $saveOptions = null )
139. {
140. $this-> converter = $converter;
141. $this-> name = $name;
142. $this-> setFilters ( $filters );
143. $this-> setMimeOut ( $mimeOut );
144. $this-> setSaveOptions ( $saveOptions !== null ? $saveOptions : new ezcImageSaveOptions () );
145. }
147. /**
148. * Add a filter to the conversion.
149. * Adds a filter with the specific settings. Filters can be added either
150. * before an existing filter or at the end (leave out $before parameter).
151. *
152. * @param ezcImageFilter $filter The filter definition.
153. * @param int $before Where to add the filter
154. * @return void
155. *
156. * @throws ezcImageFilterNotAvailableException
157. * If the given filter is not available.
158. */
159. public function addFilter ( ezcImageFilter $filter, $before = null )
160. {
161. if ( $this-> converter -> hasFilter ( $filter->name ) === false )
162. {
163. throw new ezcImageFilterNotAvailableException ( $filter->name );
164. }
165. if ( isset( $before ) && isset( $this-> filters [$before] ) )
166. {
167. array_splice ( $this-> filters , $before, 0, array( $filter ) );
168. return;
169. }
170. $this-> filters [] = $filter;
171. }
173. /**
174. * Determine output MIME type
175. * Returns the MIME type that the transformation will output.
176. *
177. * @param string $fileIn File that should deal as input for the transformation.
178. * @param string $mimeIn Specify the MIME type, so method does not need to.
179. *
180. * @return string MIME type the transformation will output.
181. *
182. * @throws ezcImageAnalyzerException If the input type is unsupported.
183. */
184. public function getOutMime ( $fileIn, $mimeIn = null )
185. {
186. if ( !isset( $mimeIn ) )
187. {
188. $analyzer = new ezcImageAnalyzer ( $fileIn );
189. $mimeIn = $analyzer->mime;
190. }
191. $mimeOut = $this-> converter -> getMimeOut ( $mimeIn );
192. // Is output type allowed by this transformation? Else use first allowed one...
193. return in_array ( $mimeOut, $this-> mimeOut ) ? $mimeOut : reset ( $this-> mimeOut );
194. }
196. /**
197. * Apply the given filters for the transformation.
198. * Applies the conversion as defined to the given file and saves it as
199. * defined.
200. *
201. * @param string $fileIn The file to transform.
202. * @param string $fileOut The file to save the transformed image to.
203. * @return void
204. *
205. * @throws ezcImageTransformationException If an error occurs during the
206. * transformation. The returned exception contains the exception
207. * the problem resulted from in it's public $parent attribute.
208. * @throws ezcBaseFileNotFoundException If the file you are trying to
209. * transform does not exists.
210. * @throws ezcBaseFilePermissionException If the file you are trying to
211. * transform is not readable.
212. */
213. public function transform ( $fileIn, $fileOut )
214. {
215. // Sanity checks
216. if ( ! is_file ( $fileIn ) )
217. {
218. throw new ezcBaseFileNotFoundException ( $fileIn );
219. }
220. if ( ! is_readable ( $fileIn ) )
221. {
222. throw new ezcBaseFilePermissionException ( $fileIn, ezcBaseFileException ::READ );
223. }
225. // Start atomic file operation
226. $fileTmp = tempnam ( dirname ( $fileOut ) . DIRECTORY_SEPARATOR, '.'. basename ( $fileOut ) );
227. copy ( $fileIn, $fileTmp );
229. try
230. {
231. // MIME types
232. $analyzer = new ezcImageAnalyzer ( $fileTmp );
234. // Do not process animated GIFs
235. if ( $analyzer->data->isAnimated )
236. {
237. copy ( $fileTmp, $fileOut );
238. unlink ( $fileTmp );
239. return;
240. }
242. $mimeIn = $analyzer->mime;
243. }
244. catch ( ezcImageAnalyzerException $e )
245. {
246. // Clean up
247. unlink ( $fileTmp );
248. // Rethrow
249. throw new ezcImageTransformationException ( $e );
250. }
252. $outMime = $this-> getOutMime ( $fileTmp, $mimeIn );
254. $ref = '';
256. // Catch exceptions for cleanup
257. try
258. {
259. // Apply the filters
260. foreach ( $this-> filters as $filter )
261. {
262. // Avoid reopening in same handler
263. if ( isset( $this-> lastHandler ) )
264. {
265. if ( $this-> lastHandler -> hasFilter ( $filter->name ) )
266. {
267. $this-> lastHandler -> applyFilter ( $ref, $filter );
268. continue;
269. }
270. else
271. {
272. // Handler does not support filter, save file
273. $this-> lastHandler -> save ( $ref );
274. $this-> lastHandler -> close ( $ref );
275. }
276. }
277. // Get handler to perform filter correctly
278. $this-> lastHandler = $this-> converter -> getHandler ( $filter->name, $mimeIn );
279. $ref = $this-> lastHandler -> load ( $fileTmp, $mimeIn );
280. $this-> lastHandler -> applyFilter ( $ref, $filter );
281. }
283. // When no filters are performed by a transformation, we might have no last handler here
284. if ( !isset( $this-> lastHandler ) )
285. {
286. $this-> lastHandler = $this-> converter -> getHandler ( null, $mimeIn, $outMime );
287. $ref = $this-> lastHandler -> load ( $fileTmp, $mimeIn );
288. }
290. // Perform conversion
291. if ( $this-> lastHandler -> allowsOutput ( ( $outMime ) ) )
292. {
293. $this-> lastHandler -> convert ( $ref, $outMime );
294. }
295. else
296. {
297. // Close in last handler
298. $this-> lastHandler -> save ( $ref );
299. $this-> lastHandler -> close ( $ref );
300. // Destroy invalid reference (has been closed)
301. $ref = null;
302. // Retreive correct handler
303. $this-> lastHandler = $this-> converter -> getHandler ( null, $mimeIn, $outMime );
304. // Load in new handler
305. $ref = $this-> lastHandler -> load ( $fileTmp );
306. // Perform conversion
307. $this-> lastHandler -> convert ( $ref, $outMime );
308. }
309. // Everything done, save and close
310. $this-> lastHandler -> save ( $ref, null, null, $this-> saveOptions );
311. $this-> lastHandler -> close ( $ref );
312. }
313. catch ( ezcImageException $e )
314. {
315. // Cleanup
316. if ( $ref !== null )
317. {
318. $this-> lastHandler -> close ( $ref );
319. }
320. if ( file_exists ( $fileTmp ) )
321. {
322. unlink ( $fileTmp );
323. }
324. $this-> lastHandler = null;
325. // Rethrow
326. throw new ezcImageTransformationException ( $e );
327. }
329. // Cleanup
330. $this-> lastHandler = null;
332. // Finalize atomic file operation
333. if ( ezcBaseFeatures :: os () === 'Windows' && file_exists ( $fileOut ) )
334. {
335. // Windows does not allows overwriting files using rename,
336. // therefore the file is unlinked here first.
337. if ( unlink ( $fileOut ) === false )
338. {
339. // Cleanup
340. unlink ( $fileTmp );
341. throw new ezcImageFileNotProcessableException ( $fileOut, 'The file exists and could not be unlinked.' );
342. }
343. }
344. if ( @ rename ( $fileTmp, $fileOut ) === false )
345. {
346. unlink ( $fileTmp );
347. throw new ezcImageFileNotProcessableException ( $fileOut, "The temporary file {$fileTmp} could not be renamed to {$fileOut}." );
348. }
349. }
351. /**
352. * Set the filters for this transformation.
353. * Checks if the filters defined are available and saves them to the created
354. * transformation if everything is okay.
355. *
356. * @param array(ezcImageFilter) $filters Array of {@link ezcImageFilter filter objects}.
357. * @return void
358. *
359. * @throws ezcImageFilterNotAvailableException
360. * If a filter is not available.
361. * @throws ezcBaseFileException
362. * If the filter array contains invalid object entries.
363. */
364. protected function setFilters ( array $filters )
365. {
366. foreach ( $filters as $id => $filter )
367. {
368. if ( !$filter instanceof ezcImageFilter )
369. {
370. throw new ezcBaseSettingValueException ( 'filters', 'array( int => ' . get_class ( $filter ) . ' )', 'array( int => ezcImageFilter )' );
371. }
372. if ( !$this-> converter -> hasFilter ( $filter->name ) )
373. {
374. throw new ezcImageFilterNotAvailableException ( $filter->name );
375. }
376. }
377. $this->filters = $filters;
378. }
380. /**
381. * Sets the MIME types which are allowed for output.
382. *
383. * @param array $mime MIME types to allow output for.
384. * @return void
385. *
386. * @throws ezcImageMimeTypeUnsupportedException
387. * If the MIME types cannot be used as output of any of the
388. * handlers in the converter.
389. */
390. protected function setMimeOut ( array $mime )
391. {
392. foreach ( $mime as $mimeType )
393. {
394. if ( !$this-> converter ->allowsOutput( $mimeType ) )
395. {
396. throw new ezcImageMimeTypeUnsupportedException ( $mimeType, 'output' );
397. }
398. }
399. $this-> mimeOut = $mime;
400. }
402. /**
403. * Sets the save options.
404. * Sets the save options, that are used for the final save step of the
405. * transformation.
406. *
407. * {@link ezcImageSaveOptions}
408. *
409. * @param ezcImageSaveOptions $options Save options.
410. * @return void
411. */
412. public function setSaveOptions ( ezcImageSaveOptions $options )
413. {
414. $this-> saveOptions = $options;
415. }
416. }
417. ?>

Documentation generated by phpDocumentor 1.4.3