imagecache_autorotate.module 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. <?php
  2. /**
  3. * @file
  4. * Autorotate image based on EXIF Orientation tag.
  5. * http://sylvana.net/jpegcrop/exif_orientation.html
  6. *
  7. * This mini-module contributed by jonathan_hunt http://drupal.org/user/28976
  8. * September 1, 2009
  9. *
  10. * Tweaked by dman to add documentation
  11. */
  12. /* In Adobe PNGs and TIFF, this information MAY be present in the XMP
  13. * metadata like so:
  14. <x:xmpmeta xmlns:x="adobe:ns:meta/">
  15. <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
  16. <rdf:Description rdf:about="" xmlns:tiff="http://ns.adobe.com/tiff/1.0/">
  17. <tiff:Orientation>6</tiff:Orientation>
  18. </rdf:Description>
  19. </rdf:RDF>
  20. </x:xmpmeta>
  21. */
  22. function imagecache_autorotate_image_effect_info() {
  23. $effects = array();
  24. $effects['imagecache_autorotate'] = array(
  25. 'label' => t('Autorotate'),
  26. 'help' => t('Add autorotate image based on EXIF Orientation.'),
  27. 'effect callback' => 'imagecache_autorotate_image',
  28. 'dimensions callback' => 'imagecache_autorotate_dimensions',
  29. );
  30. return $effects;
  31. }
  32. /**
  33. * Declare dummy form, since we have no settings.
  34. *
  35. * @todo: A form is no longer needed, if this information still needs to be
  36. * displayed it should probably be moved to help.
  37. */
  38. function imagecache_autorotate_form() {
  39. $form = array();
  40. $form['help'] = array(
  41. '#type' => 'markup',
  42. '#value' => "<p>
  43. <b>There are no user-configurable options for this process.</b>
  44. </p><p>
  45. Certain cameras can embed <em>orientation</em> information into image
  46. files when they save them. This information is embedded in an EXIF tag
  47. and can be used to rotate images to their correct position for display.
  48. </p><p>
  49. <em>Not all cameras or images contain this information.</em>
  50. This process is only useful for those that do.
  51. </p><p>
  52. The expected/supported values are
  53. <br/><strong>Tag</strong>: <code>0x0112 Orientation</code>
  54. </p>
  55. <ul>
  56. <li>1 = Horizontal (normal)</li>
  57. <li>3 = Rotate 180</li>
  58. <li>6 = Rotate 90 CW</li>
  59. <li>8 = Rotate 270 CW</li>
  60. </ul>
  61. <p>
  62. <a href='http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html'>
  63. EXIF Reference</a>
  64. </p>
  65. ",
  66. );
  67. return $form;
  68. }
  69. /**
  70. * Autorotate image based on EXIF Orientation tag.
  71. *
  72. * See code at
  73. * http://sylvana.net/jpegcrop/exif_orientation.html
  74. *
  75. * and reference at
  76. * http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html
  77. *
  78. * @todo:
  79. * Add horizontal and vertical flips etc.
  80. * Need to create sample set for tests.
  81. */
  82. function imagecache_autorotate_image($image, $data) {
  83. // Test to see if EXIF is supported for image type (e.g. not PNG).
  84. if ($image->info['mime_type'] == 'image/jpeg') {
  85. if (!function_exists('exif_read_data')) {
  86. watchdog('image', 'The image %file could not be auto-rotated because the exif_read_data() function is not available in this PHP installation. You probably will have to enable the exif extension.', array('%file' => $image->source));
  87. return FALSE;
  88. }
  89. $exif = exif_read_data(drupal_realpath($image->source));
  90. if (isset($exif['Orientation'])) {
  91. switch ($exif['Orientation']) {
  92. case 3:
  93. $degrees = 180;
  94. break;
  95. case 6:
  96. $degrees = 90;
  97. break;
  98. case 8:
  99. $degrees = 270;
  100. break;
  101. default:
  102. $degrees = 0;
  103. }
  104. if ($degrees != 0) {
  105. $org_width = $image->info['width'];
  106. $org_height = $image->info['height'];
  107. image_rotate($image, $degrees);
  108. if (($degrees === 90 || $degrees === 270) && $image->info['width'] === $org_width) {
  109. // The toolkit failed to alter the dimensions (imagemagick currently
  110. // fails to do so). So we do it ourselves.
  111. $image->info['width'] = $org_height;
  112. $image->info['height'] = $org_width;
  113. }
  114. }
  115. }
  116. }
  117. return TRUE;
  118. }
  119. /**
  120. * Image dimensions callback; Auto-rotate.
  121. *
  122. * @param $dimensions
  123. * Dimensions to be modified - an array with components width and height, in
  124. * pixels.
  125. * @param $data
  126. * An array of attributes to use when performing the rotate effect containing
  127. * the following items:
  128. * - "degrees": The number of (clockwise) degrees to rotate the image.
  129. * - "random": A boolean indicating that a random rotation angle should be
  130. * used for this image. The angle specified in "degrees" is used as a
  131. * positive and negative maximum.
  132. */
  133. function imagecache_autorotate_dimensions(array &$dimensions, array $data) {
  134. $dimensions['width'] = $dimensions['height'] = NULL;
  135. }