image_example.module

Module file for image_example

Functions

File

image_example/image_example.module
View source
  1. <?php
  2. /**
  3. * @file
  4. * Module file for image_example
  5. */
  6. /**
  7. * @defgroup image_example Example: Image
  8. * @ingroup examples
  9. * @{
  10. * Demonstrates the basic use of image API.
  11. *
  12. * This module demonstrates the use of Drupal 7's new image styles and effects
  13. * including the following topics.
  14. * - Define default image styles in code. Useful for modules that want to ship
  15. * with predefined image styles and for site developers who want their image
  16. * style configurations to be in version control.
  17. * hook_image_default_styles().
  18. * - Define new image effects. Demonstrates how a module can add additional
  19. * effects to the options available when creating image styles.
  20. * hook_image_effect_info().
  21. * - Alter existing image styles. Demonstrates the use of
  22. * hook_image_styles_alter() to modify existing image effects, especially
  23. * those defined by other modules in hook_image_default_styles() without
  24. * having to override the styles.
  25. * - Demonstrates the use of hook_image_style_save() and
  26. * hook_image_style_delete() to update module specific variables when an
  27. * image style is either re-named or deleted.
  28. * - Generate a form with a field of type #managed_file that allows the user
  29. * to upload an image and choose a style to use when displaying that image.
  30. * - Demonstrates the use of theme_image_style() to display images using an
  31. * image style.
  32. *
  33. * @see hook_image_default_styles().
  34. * @see hook_image_effect_info().
  35. * @see hook_image_style_save().
  36. * @see hook_image_style_delete().
  37. * @see theme_image_style().
  38. */
  39. /**
  40. * Implements hook_menu().
  41. *
  42. * Provide a menu item and a page to demonstrate features of this example
  43. * module.
  44. */
  45. function image_example_menu() {
  46. $items = array();
  47. $items['image_example/styles'] = array(
  48. 'title' => 'Image Example',
  49. 'page callback' => 'drupal_get_form',
  50. 'page arguments' => array('image_example_style_form'),
  51. 'access arguments' => array('access content'),
  52. 'file' => 'image_example.pages.inc',
  53. );
  54. return $items;
  55. }
  56. /**
  57. * Implements hook_help().
  58. */
  59. function image_example_help($path) {
  60. switch ($path) {
  61. case 'image_example/styles':
  62. $output = '<p>' . t('Use this form to upload an image and choose an Image Style to use when displaying the image. This demonstrates basic use of the Drupal 7 Image styles & effects system.') . '</p>';
  63. $output .= '<p>' . t('Image styles can be added/edited using the !link.', array('!link' => l(t('Image styles UI'), 'admin/config/media/image-styles'))) . '</p>';
  64. return $output;
  65. }
  66. }
  67. /**
  68. * Implements hook_image_default_styles().
  69. *
  70. * hook_image_default_styles() declares to Drupal any image styles that are
  71. * provided by the module. An image style is a collection of image effects that
  72. * are performed in a specified order, manipulating the image and generating a
  73. * new derivative image.
  74. *
  75. * This hook can be used to declare image styles that your module depends on or
  76. * allow you to define image styles in code and gain the benefits of using
  77. * a version control system.
  78. */
  79. function image_example_image_default_styles() {
  80. // This hook returns an array, each component of which describes an image
  81. // style. The array keys are the machine-readable image style names and
  82. // to avoid namespace conflicts should begin with the name of the
  83. // implementing module. e.g.) 'mymodule_stylename'. Styles names should
  84. // use only alpha-numeric characters, underscores (_), and hyphens (-).
  85. $styles = array();
  86. $styles['image_example_style'] = array();
  87. // Each style array consists of an 'effects' array that is made up of
  88. // sub-arrays which define the individual image effects that are combined
  89. // together to create the image style.
  90. $styles['image_example_style']['effects'] = array(
  91. array(
  92. // Name of the image effect. See image_image_effect_info() in
  93. // modules/image/image.effects.inc for a list of image effects available
  94. // in Drupal 7 core.
  95. 'name' => 'image_scale',
  96. // Arguments to pass to the effect callback function.
  97. // The arguments that an effect accepts are documented with each
  98. // individual image_EFFECT_NAME_effect function. See image_scale_effect()
  99. // for an example.
  100. 'data' => array(
  101. 'width' => 100,
  102. 'height' => 100,
  103. 'upscale' => 1,
  104. ),
  105. // The order in which image effects should be applied when using this
  106. // style.
  107. 'weight' => 0,
  108. ),
  109. // Add a second effect to this image style. Effects are executed in order
  110. // and are cummulative. When applying an image style to an image the result
  111. // will be the combination of all effects associated with that style.
  112. array(
  113. 'name' => 'image_example_colorize',
  114. 'data' => array(
  115. 'color' => '#FFFF66',
  116. ),
  117. 'weight' => 1,
  118. ),
  119. );
  120. return $styles;
  121. }
  122. /**
  123. * Implements hook_image_style_save().
  124. *
  125. * Allows modules to respond to updates to an image style's
  126. * settings.
  127. */
  128. function image_example_image_style_save($style) {
  129. // The $style parameter is an image style array with one notable exception.
  130. // When a user has choosen to replace a deleted style with another style the
  131. // $style['name'] property contains the name of the replacement style and
  132. // $style['old_name'] contains the name of the style being deleted.
  133. // Here we update a variable that contains the name of the image style that
  134. // the block provided by this module uses when formating images to use the
  135. // new user choosen style name.
  136. if (isset($style['old_name']) && $style['old_name'] == variable_get('image_example_style_name', '')) {
  137. variable_set('image_example_style_name', $style['name']);
  138. }
  139. }
  140. /**
  141. * Implements hook_image_style_delete().
  142. *
  143. * This hook allows modules to respond to image styles being deleted.
  144. *
  145. * @see image_example_style_save()
  146. */
  147. function image_example_image_style_delete($style) {
  148. // See information about $style paramater in documentation for
  149. // image_example_style_save().
  150. // Update the modules variable that contains the name of the image style
  151. // being deleted to the name of the replacement style.
  152. if (isset($style['old_name']) && $style['old_name'] == variable_get('image_example_style_name', '')) {
  153. variable_set('image_example_style_name', $style['name']);
  154. }
  155. }
  156. /**
  157. * Implements hook_image_style_flush().
  158. *
  159. * This hook allows modules to respond when a style is being flushed. Styles
  160. * are flushed any time a style is updated, an effect associated with the style
  161. * is updated, a new effect is added to the style, or an existing effect is
  162. * removed.
  163. *
  164. * Flushing removes all images generated using this style from the host. Once a
  165. * style has been flushed derivative images will need to be regenerated. New
  166. * images will be generated automatically as needed but it is worth noting that
  167. * on a busy site with lots of images this could have an impact on performance.
  168. *
  169. * Note: This function does not currently have any effect as the example module
  170. * does not use any caches. It is demonstrated here for completeness sake only.
  171. */
  172. function image_example_style_flush($style) {
  173. // The $style parameter is an image style array.
  174. // Empty any caches populated by our module that could contain stale data
  175. // after the style has been flushed. Stale data occurs because the module may
  176. // have cached content with a reference to the derivative image which is
  177. // being deleted.
  178. cache_clear_all('*', 'image_example', TRUE);
  179. }
  180. /**
  181. * Implements hook_image_styles_alter().
  182. *
  183. * Allows your module to modify, add, or remove image styles provided
  184. * by other modules. The best use of this hook is to modify default styles that
  185. * have not been overriden by the user. Altering styles that have been
  186. * overriden by the user could have an adverse affect on the user experience.
  187. * If you add an effect to a style through this hook and the user attempts to
  188. * remove the effect it will immediatly be re-applied.
  189. */
  190. function image_example_image_styles_alter(&$styles) {
  191. // The $styles paramater is an array of image style arrays keyed by style
  192. // name. You can check to see if a style has been overriden by checking the
  193. // $styles['stylename']['storage'] property.
  194. // Verify that the effect has not been overriden.
  195. if ($styles['thumbnail']['storage'] == IMAGE_STORAGE_DEFAULT) {
  196. // Add an additional colorize effect to the system provided thumbnail
  197. // effect.
  198. $styles['thumbnail']['effects'][] = array(
  199. 'label' => t('Colorize #FFFF66'),
  200. 'name' => 'image_example_colorize',
  201. 'effect callback' => 'image_example_colorize_effect',
  202. 'data' => array(
  203. 'color' => '#FFFF66',
  204. ),
  205. 'weight' => 1,
  206. );
  207. }
  208. }
  209. /**
  210. * Implements hook_image_effect_info().
  211. *
  212. * This hook allows your module to define additional image manipulation effects
  213. * that can be used with image styles.
  214. */
  215. function image_example_image_effect_info() {
  216. $effects = array();
  217. // The array is keyed on the machine-readable effect name.
  218. $effects['image_example_colorize'] = array(
  219. // Human readable name of the effect.
  220. 'label' => t('Colorize'),
  221. // (optional) Brief description of the effect that will be shown when
  222. // adding or configuring this image effect.
  223. 'help' => t('The colorize effect will first remove all color from the source image and then tint the image using the color specified.'),
  224. // Name of function called to perform this effect.
  225. 'effect callback' => 'image_example_colorize_effect',
  226. // (optional) Name of function that provides a $form array with options for
  227. // configuring the effect. Note that you only need to return the fields
  228. // specific to your module. Submit buttons will be added automatically, and
  229. // configuration options will be serailized and added to the 'data' element
  230. // of the effect. The function will recieve the $effect['data'] array as
  231. // its only parameter.
  232. 'form callback' => 'image_example_colorize_form',
  233. // (optional) Name of a theme function that will output a summary of this
  234. // effects configuation. Used when displaying list of effects associated
  235. // with an image style. In this example the function
  236. // theme_image_example_colorize_summary will be called via the theme()
  237. // function. Your module must also implement hook_theme() in order for this
  238. // function to work correctly. See image_example_theme() and
  239. // theme_image_example_colorize_summary().
  240. 'summary theme' => 'image_example_colorize_summary',
  241. );
  242. return $effects;
  243. }
  244. /**
  245. * Form Builder; Configuration settings for colorize effect.
  246. *
  247. * Create a $form array with the fields necessary for configuring the
  248. * image_example_colorize effect.
  249. *
  250. * Note that this is not a complete form, it only contains the portion of the
  251. * form for configuring the colorize options. Therefore it does not not need to
  252. * include metadata about the effect, nor a submit button.
  253. *
  254. * @param $data
  255. * The current configuration for this colorize effect.
  256. */
  257. function image_example_colorize_form($data) {
  258. $form = array();
  259. // You do not need to worry about handling saving/updating/deleting of the
  260. // data collected. The image module will automatically serialize and store
  261. // all data associated with an effect.
  262. $form['color'] = array(
  263. '#type' => 'textfield',
  264. '#title' => t('Color'),
  265. '#description' => t('The color to use when colorizing the image. Use web-style hex colors. e.g.) #FF6633.'),
  266. '#default_value' => isset($data['color']) ? $data['color'] : '',
  267. '#size' => 7,
  268. '#max_length' => 7,
  269. '#required' => TRUE,
  270. );
  271. return $form;
  272. }
  273. /**
  274. * Image effect callback; Colorize an image resource.
  275. *
  276. * @param $image
  277. * An image object returned by image_load().
  278. * @param $data
  279. * An array of attributes to use when performing the colorize effect with the
  280. * following items:
  281. * - "color": The web-style hex color to use when colorizing the image.
  282. * @return
  283. * TRUE on success. FALSE on failure to colorize image.
  284. */
  285. function image_example_colorize_effect(&$image, $data) {
  286. // Image manipulation should be done to the $image->resource, which will be
  287. // automatically saved as a new image once all effects have been applied.
  288. // If your effect makes changes to the $image->resource that relate to any
  289. // information stored in the $image->info array (width, height, etc.) you
  290. // should update that information as well. See modules/system/image.gd.inc
  291. // for examples of functions that perform image manipulations.
  292. // Not all GD installations are created equal. It is a good idea to check for
  293. // the existence of image manipulation functions before using them.
  294. // PHP installations using non-bundled GD do not have imagefilter(). More
  295. // information about image manipulation functions is available in the PHP
  296. // manual. http://www.php.net/manual/en/book.image.php
  297. if (!function_exists('imagefilter')) {
  298. watchdog('image', 'The image %image could not be colorized because the imagefilter() function is not available in this PHP installation.', array('%file' => $image->source));
  299. return FALSE;
  300. }
  301. // Verify that Drupal is using the PHP GD library for image manipulations
  302. // since this effect depends on functions in the GD library.
  303. if ($image->toolkit != 'gd') {
  304. watchdog('image', 'Image colorize failed on %path. Using non GD toolkit.', array('%path' => $image->source), WATCHDOG_ERROR);
  305. return FALSE;
  306. }
  307. // Convert short #FFF syntax to full #FFFFFF syntax.
  308. if (strlen($data['color']) == 4) {
  309. $c = $data['color'];
  310. $data['color'] = $c[0] . $c[1] . $c[1] . $c[2] . $c[2] . $c[3] . $c[3];
  311. }
  312. // Convert #FFFFFF syntax to hexadecimal colors.
  313. $data['color'] = hexdec(str_replace('#', '0x', $data['color']));
  314. // Convert the hexadecimal color value to a color index value.
  315. $rgb = array();
  316. for ($i = 16; $i >= 0; $i -= 8) {
  317. $rgb[] = (($data['color'] >> $i) & 0xFF);
  318. }
  319. // First desaturate the image, and then apply the new color.
  320. imagefilter($image->resource, IMG_FILTER_GRAYSCALE);
  321. imagefilter($image->resource, IMG_FILTER_COLORIZE, $rgb[0], $rgb[1], $rgb[2]);
  322. return TRUE;
  323. }
  324. /**
  325. * Implements hook_theme().
  326. */
  327. function image_example_theme() {
  328. return array(
  329. 'image_example_colorize_summary' => array(
  330. 'variables' => array('data' => NULL),
  331. ),
  332. 'image_example_image' => array(
  333. 'variables' => array('image' => NULL, 'style' => NULL),
  334. 'file' => 'image_example.pages.inc',
  335. ),
  336. );
  337. }
  338. /**
  339. * Formats a summary of an image colorize effect.
  340. *
  341. * @param $variables
  342. * An associative array containing:
  343. * - data: The current configuration for this colorize effect.
  344. */
  345. function theme_image_example_colorize_summary($variables) {
  346. $data = $variables['data'];
  347. return t('as color #@color.', array('@color' => $data['color']));
  348. }
  349. /**
  350. * @} End of "defgroup image_example".
  351. */