mp-wp_genesis 1 <?php
mp-wp_genesis 2 /**
mp-wp_genesis 3 * File contains all the administration image manipulation functions.
mp-wp_genesis 4 *
mp-wp_genesis 5 * @package WordPress
mp-wp_genesis 6 * @subpackage Administration
mp-wp_genesis 7 */
mp-wp_genesis 8
mp-wp_genesis 9 /**
mp-wp_genesis 10 * Create a thumbnail from an Image given a maximum side size.
mp-wp_genesis 11 *
mp-wp_genesis 12 * This function can handle most image file formats which PHP supports. If PHP
mp-wp_genesis 13 * does not have the functionality to save in a file of the same format, the
mp-wp_genesis 14 * thumbnail will be created as a jpeg.
mp-wp_genesis 15 *
mp-wp_genesis 16 * @since 1.2.0
mp-wp_genesis 17 *
mp-wp_genesis 18 * @param mixed $file Filename of the original image, Or attachment id.
mp-wp_genesis 19 * @param int $max_side Maximum length of a single side for the thumbnail.
mp-wp_genesis 20 * @return string Thumbnail path on success, Error string on failure.
mp-wp_genesis 21 */
mp-wp_genesis 22 function wp_create_thumbnail( $file, $max_side, $deprecated = '' ) {
mp-wp_genesis 23 $thumbpath = image_resize( $file, $max_side, $max_side );
mp-wp_genesis 24 return apply_filters( 'wp_create_thumbnail', $thumbpath );
mp-wp_genesis 25 }
mp-wp_genesis 26
mp-wp_genesis 27 /**
mp-wp_genesis 28 * Crop an Image to a given size.
mp-wp_genesis 29 *
mp-wp_genesis 30 * @since 2.1.0
mp-wp_genesis 31 *
mp-wp_genesis 32 * @param string|int $src_file The source file or Attachment ID.
mp-wp_genesis 33 * @param int $src_x The start x position to crop from.
mp-wp_genesis 34 * @param int $src_y The start y position to crop from.
mp-wp_genesis 35 * @param int $src_w The width to crop.
mp-wp_genesis 36 * @param int $src_h The height to crop.
mp-wp_genesis 37 * @param int $dst_w The destination width.
mp-wp_genesis 38 * @param int $dst_h The destination height.
mp-wp_genesis 39 * @param int $src_abs Optional. If the source crop points are absolute.
mp-wp_genesis 40 * @param string $dst_file Optional. The destination file to write to.
mp-wp_genesis 41 * @return string New filepath on success, String error message on failure.
mp-wp_genesis 42 */
mp-wp_genesis 43 function wp_crop_image( $src_file, $src_x, $src_y, $src_w, $src_h, $dst_w, $dst_h, $src_abs = false, $dst_file = false ) {
mp-wp_genesis 44 if ( is_numeric( $src_file ) ) // Handle int as attachment ID
mp-wp_genesis 45 $src_file = get_attached_file( $src_file );
mp-wp_genesis 46
mp-wp_genesis 47 $src = wp_load_image( $src_file );
mp-wp_genesis 48
mp-wp_genesis 49 if ( !is_resource( $src ))
mp-wp_genesis 50 return $src;
mp-wp_genesis 51
mp-wp_genesis 52 $dst = imagecreatetruecolor( $dst_w, $dst_h );
mp-wp_genesis 53
mp-wp_genesis 54 if ( $src_abs ) {
mp-wp_genesis 55 $src_w -= $src_x;
mp-wp_genesis 56 $src_h -= $src_y;
mp-wp_genesis 57 }
mp-wp_genesis 58
mp-wp_genesis 59 if (function_exists('imageantialias'))
mp-wp_genesis 60 imageantialias( $dst, true );
mp-wp_genesis 61
mp-wp_genesis 62 imagecopyresampled( $dst, $src, 0, 0, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h );
mp-wp_genesis 63
mp-wp_genesis 64 imagedestroy( $src ); // Free up memory
mp-wp_genesis 65
mp-wp_genesis 66 if ( ! $dst_file )
mp-wp_genesis 67 $dst_file = str_replace( basename( $src_file ), 'cropped-' . basename( $src_file ), $src_file );
mp-wp_genesis 68
mp-wp_genesis 69 $dst_file = preg_replace( '/\\.[^\\.]+$/', '.jpg', $dst_file );
mp-wp_genesis 70
mp-wp_genesis 71 if ( imagejpeg( $dst, $dst_file ) )
mp-wp_genesis 72 return $dst_file;
mp-wp_genesis 73 else
mp-wp_genesis 74 return false;
mp-wp_genesis 75 }
mp-wp_genesis 76
mp-wp_genesis 77 /**
mp-wp_genesis 78 * Generate post image attachment meta data.
mp-wp_genesis 79 *
mp-wp_genesis 80 * @since 2.1.0
mp-wp_genesis 81 *
mp-wp_genesis 82 * @param int $attachment_id Attachment Id to process.
mp-wp_genesis 83 * @param string $file Filepath of the Attached image.
mp-wp_genesis 84 * @return mixed Metadata for attachment.
mp-wp_genesis 85 */
mp-wp_genesis 86 function wp_generate_attachment_metadata( $attachment_id, $file ) {
mp-wp_genesis 87 $attachment = get_post( $attachment_id );
mp-wp_genesis 88
mp-wp_genesis 89 $metadata = array();
mp-wp_genesis 90 if ( preg_match('!^image/!', get_post_mime_type( $attachment )) && file_is_displayable_image($file) ) {
mp-wp_genesis 91 $full_path_file = $file;
mp-wp_genesis 92 $imagesize = getimagesize( $full_path_file );
mp-wp_genesis 93 $metadata['width'] = $imagesize[0];
mp-wp_genesis 94 $metadata['height'] = $imagesize[1];
mp-wp_genesis 95 list($uwidth, $uheight) = wp_shrink_dimensions($metadata['width'], $metadata['height']);
mp-wp_genesis 96 $metadata['hwstring_small'] = "height='$uheight' width='$uwidth'";
mp-wp_genesis 97
mp-wp_genesis 98 // Make the file path relative to the upload dir
mp-wp_genesis 99 if ( ($uploads = wp_upload_dir()) && false === $uploads['error'] ) { // Get upload directory
mp-wp_genesis 100 if ( 0 === strpos($file, $uploads['basedir']) ) {// Check that the upload base exists in the file path
mp-wp_genesis 101 $file = str_replace($uploads['basedir'], '', $file); // Remove upload dir from the file path
mp-wp_genesis 102 $file = ltrim($file, '/');
mp-wp_genesis 103 }
mp-wp_genesis 104 }
mp-wp_genesis 105 $metadata['file'] = $file;
mp-wp_genesis 106
mp-wp_genesis 107 // make thumbnails and other intermediate sizes
mp-wp_genesis 108 $sizes = array('thumbnail', 'medium', 'large');
mp-wp_genesis 109 $sizes = apply_filters('intermediate_image_sizes', $sizes);
mp-wp_genesis 110
mp-wp_genesis 111 foreach ($sizes as $size) {
mp-wp_genesis 112 $resized = image_make_intermediate_size( $full_path_file, get_option("{$size}_size_w"), get_option("{$size}_size_h"), get_option("{$size}_crop") );
mp-wp_genesis 113 if ( $resized )
mp-wp_genesis 114 $metadata['sizes'][$size] = $resized;
mp-wp_genesis 115 }
mp-wp_genesis 116
mp-wp_genesis 117 // fetch additional metadata from exif/iptc
mp-wp_genesis 118 $image_meta = wp_read_image_metadata( $full_path_file );
mp-wp_genesis 119 if ($image_meta)
mp-wp_genesis 120 $metadata['image_meta'] = $image_meta;
mp-wp_genesis 121
mp-wp_genesis 122 }
mp-wp_genesis 123
mp-wp_genesis 124 return apply_filters( 'wp_generate_attachment_metadata', $metadata );
mp-wp_genesis 125 }
mp-wp_genesis 126
mp-wp_genesis 127 /**
mp-wp_genesis 128 * Load an image from a string, if PHP supports it.
mp-wp_genesis 129 *
mp-wp_genesis 130 * @since 2.1.0
mp-wp_genesis 131 *
mp-wp_genesis 132 * @param string $file Filename of the image to load.
mp-wp_genesis 133 * @return resource The resulting image resource on success, Error string on failure.
mp-wp_genesis 134 */
mp-wp_genesis 135 function wp_load_image( $file ) {
mp-wp_genesis 136 if ( is_numeric( $file ) )
mp-wp_genesis 137 $file = get_attached_file( $file );
mp-wp_genesis 138
mp-wp_genesis 139 if ( ! file_exists( $file ) )
mp-wp_genesis 140 return sprintf(__("File '%s' doesn't exist?"), $file);
mp-wp_genesis 141
mp-wp_genesis 142 if ( ! function_exists('imagecreatefromstring') )
mp-wp_genesis 143 return __('The GD image library is not installed.');
mp-wp_genesis 144
mp-wp_genesis 145 // Set artificially high because GD uses uncompressed images in memory
mp-wp_genesis 146 @ini_set('memory_limit', '256M');
mp-wp_genesis 147 $image = imagecreatefromstring( file_get_contents( $file ) );
mp-wp_genesis 148
mp-wp_genesis 149 if ( !is_resource( $image ) )
mp-wp_genesis 150 return sprintf(__("File '%s' is not an image."), $file);
mp-wp_genesis 151
mp-wp_genesis 152 return $image;
mp-wp_genesis 153 }
mp-wp_genesis 154
mp-wp_genesis 155 /**
mp-wp_genesis 156 * Calculated the new dimentions for a downsampled image.
mp-wp_genesis 157 *
mp-wp_genesis 158 * @since 2.0.0
mp-wp_genesis 159 * @see wp_shrink_dimensions()
mp-wp_genesis 160 *
mp-wp_genesis 161 * @param int $width Current width of the image
mp-wp_genesis 162 * @param int $height Current height of the image
mp-wp_genesis 163 * @return mixed Array(height,width) of shrunk dimensions.
mp-wp_genesis 164 */
mp-wp_genesis 165 function get_udims( $width, $height) {
mp-wp_genesis 166 return wp_shrink_dimensions( $width, $height );
mp-wp_genesis 167 }
mp-wp_genesis 168
mp-wp_genesis 169 /**
mp-wp_genesis 170 * Calculates the new dimentions for a downsampled image.
mp-wp_genesis 171 *
mp-wp_genesis 172 * @since 2.0.0
mp-wp_genesis 173 * @see wp_constrain_dimensions()
mp-wp_genesis 174 *
mp-wp_genesis 175 * @param int $width Current width of the image
mp-wp_genesis 176 * @param int $height Current height of the image
mp-wp_genesis 177 * @param int $wmax Maximum wanted width
mp-wp_genesis 178 * @param int $hmax Maximum wanted height
mp-wp_genesis 179 * @return mixed Array(height,width) of shrunk dimensions.
mp-wp_genesis 180 */
mp-wp_genesis 181 function wp_shrink_dimensions( $width, $height, $wmax = 128, $hmax = 96 ) {
mp-wp_genesis 182 return wp_constrain_dimensions( $width, $height, $wmax, $hmax );
mp-wp_genesis 183 }
mp-wp_genesis 184
mp-wp_genesis 185 /**
mp-wp_genesis 186 * Convert a fraction string to a decimal.
mp-wp_genesis 187 *
mp-wp_genesis 188 * @since 2.5.0
mp-wp_genesis 189 *
mp-wp_genesis 190 * @param string $str
mp-wp_genesis 191 * @return int|float
mp-wp_genesis 192 */
mp-wp_genesis 193 function wp_exif_frac2dec($str) {
mp-wp_genesis 194 @list( $n, $d ) = explode( '/', $str );
mp-wp_genesis 195 if ( !empty($d) )
mp-wp_genesis 196 return $n / $d;
mp-wp_genesis 197 return $str;
mp-wp_genesis 198 }
mp-wp_genesis 199
mp-wp_genesis 200 /**
mp-wp_genesis 201 * Convert the exif date format to a unix timestamp.
mp-wp_genesis 202 *
mp-wp_genesis 203 * @since 2.5.0
mp-wp_genesis 204 *
mp-wp_genesis 205 * @param string $str
mp-wp_genesis 206 * @return int
mp-wp_genesis 207 */
mp-wp_genesis 208 function wp_exif_date2ts($str) {
mp-wp_genesis 209 @list( $date, $time ) = explode( ' ', trim($str) );
mp-wp_genesis 210 @list( $y, $m, $d ) = explode( ':', $date );
mp-wp_genesis 211
mp-wp_genesis 212 return strtotime( "{$y}-{$m}-{$d} {$time}" );
mp-wp_genesis 213 }
mp-wp_genesis 214
mp-wp_genesis 215 /**
mp-wp_genesis 216 * Get extended image metadata, exif or iptc as available.
mp-wp_genesis 217 *
mp-wp_genesis 218 * Retrieves the EXIF metadata aperture, credit, camera, caption, copyright, iso
mp-wp_genesis 219 * created_timestamp, focal_length, shutter_speed, and title.
mp-wp_genesis 220 *
mp-wp_genesis 221 * The IPTC metadata that is retrieved is APP13, credit, byline, created date
mp-wp_genesis 222 * and time, caption, copyright, and title. Also includes FNumber, Model,
mp-wp_genesis 223 * DateTimeDigitized, FocalLength, ISOSpeedRatings, and ExposureTime.
mp-wp_genesis 224 *
mp-wp_genesis 225 * @todo Try other exif libraries if available.
mp-wp_genesis 226 * @since 2.5.0
mp-wp_genesis 227 *
mp-wp_genesis 228 * @param string $file
mp-wp_genesis 229 * @return bool|array False on failure. Image metadata array on success.
mp-wp_genesis 230 */
mp-wp_genesis 231 function wp_read_image_metadata( $file ) {
mp-wp_genesis 232 if ( !file_exists( $file ) )
mp-wp_genesis 233 return false;
mp-wp_genesis 234
mp-wp_genesis 235 list(,,$sourceImageType) = getimagesize( $file );
mp-wp_genesis 236
mp-wp_genesis 237 // exif contains a bunch of data we'll probably never need formatted in ways
mp-wp_genesis 238 // that are difficult to use. We'll normalize it and just extract the fields
mp-wp_genesis 239 // that are likely to be useful. Fractions and numbers are converted to
mp-wp_genesis 240 // floats, dates to unix timestamps, and everything else to strings.
mp-wp_genesis 241 $meta = array(
mp-wp_genesis 242 'aperture' => 0,
mp-wp_genesis 243 'credit' => '',
mp-wp_genesis 244 'camera' => '',
mp-wp_genesis 245 'caption' => '',
mp-wp_genesis 246 'created_timestamp' => 0,
mp-wp_genesis 247 'copyright' => '',
mp-wp_genesis 248 'focal_length' => 0,
mp-wp_genesis 249 'iso' => 0,
mp-wp_genesis 250 'shutter_speed' => 0,
mp-wp_genesis 251 'title' => '',
mp-wp_genesis 252 );
mp-wp_genesis 253
mp-wp_genesis 254 // read iptc first, since it might contain data not available in exif such
mp-wp_genesis 255 // as caption, description etc
mp-wp_genesis 256 if ( is_callable('iptcparse') ) {
mp-wp_genesis 257 getimagesize($file, $info);
mp-wp_genesis 258 if ( !empty($info['APP13']) ) {
mp-wp_genesis 259 $iptc = iptcparse($info['APP13']);
mp-wp_genesis 260 if ( !empty($iptc['2#110'][0]) ) // credit
mp-wp_genesis 261 $meta['credit'] = utf8_encode(trim($iptc['2#110'][0]));
mp-wp_genesis 262 elseif ( !empty($iptc['2#080'][0]) ) // byline
mp-wp_genesis 263 $meta['credit'] = utf8_encode(trim($iptc['2#080'][0]));
mp-wp_genesis 264 if ( !empty($iptc['2#055'][0]) and !empty($iptc['2#060'][0]) ) // created date and time
mp-wp_genesis 265 $meta['created_timestamp'] = strtotime($iptc['2#055'][0] . ' ' . $iptc['2#060'][0]);
mp-wp_genesis 266 if ( !empty($iptc['2#120'][0]) ) // caption
mp-wp_genesis 267 $meta['caption'] = utf8_encode(trim($iptc['2#120'][0]));
mp-wp_genesis 268 if ( !empty($iptc['2#116'][0]) ) // copyright
mp-wp_genesis 269 $meta['copyright'] = utf8_encode(trim($iptc['2#116'][0]));
mp-wp_genesis 270 if ( !empty($iptc['2#005'][0]) ) // title
mp-wp_genesis 271 $meta['title'] = utf8_encode(trim($iptc['2#005'][0]));
mp-wp_genesis 272 }
mp-wp_genesis 273 }
mp-wp_genesis 274
mp-wp_genesis 275 // fetch additional info from exif if available
mp-wp_genesis 276 if ( is_callable('exif_read_data') && in_array($sourceImageType, apply_filters('wp_read_image_metadata_types', array(IMAGETYPE_JPEG, IMAGETYPE_TIFF_II, IMAGETYPE_TIFF_MM)) ) ) {
mp-wp_genesis 277 $exif = @exif_read_data( $file );
mp-wp_genesis 278 if (!empty($exif['FNumber']))
mp-wp_genesis 279 $meta['aperture'] = round( wp_exif_frac2dec( $exif['FNumber'] ), 2 );
mp-wp_genesis 280 if (!empty($exif['Model']))
mp-wp_genesis 281 $meta['camera'] = trim( $exif['Model'] );
mp-wp_genesis 282 if (!empty($exif['DateTimeDigitized']))
mp-wp_genesis 283 $meta['created_timestamp'] = wp_exif_date2ts($exif['DateTimeDigitized']);
mp-wp_genesis 284 if (!empty($exif['FocalLength']))
mp-wp_genesis 285 $meta['focal_length'] = wp_exif_frac2dec( $exif['FocalLength'] );
mp-wp_genesis 286 if (!empty($exif['ISOSpeedRatings']))
mp-wp_genesis 287 $meta['iso'] = $exif['ISOSpeedRatings'];
mp-wp_genesis 288 if (!empty($exif['ExposureTime']))
mp-wp_genesis 289 $meta['shutter_speed'] = wp_exif_frac2dec( $exif['ExposureTime'] );
mp-wp_genesis 290 }
mp-wp_genesis 291
mp-wp_genesis 292 return apply_filters( 'wp_read_image_metadata', $meta, $file, $sourceImageType );
mp-wp_genesis 293
mp-wp_genesis 294 }
mp-wp_genesis 295
mp-wp_genesis 296 /**
mp-wp_genesis 297 * Validate that file is an image.
mp-wp_genesis 298 *
mp-wp_genesis 299 * @since 2.5.0
mp-wp_genesis 300 *
mp-wp_genesis 301 * @param string $path File path to test if valid image.
mp-wp_genesis 302 * @return bool True if valid image, false if not valid image.
mp-wp_genesis 303 */
mp-wp_genesis 304 function file_is_valid_image($path) {
mp-wp_genesis 305 $size = @getimagesize($path);
mp-wp_genesis 306 return !empty($size);
mp-wp_genesis 307 }
mp-wp_genesis 308
mp-wp_genesis 309 /**
mp-wp_genesis 310 * Validate that file is suitable for displaying within a web page.
mp-wp_genesis 311 *
mp-wp_genesis 312 * @since 2.5.0
mp-wp_genesis 313 * @uses apply_filters() Calls 'file_is_displayable_image' on $result and $path.
mp-wp_genesis 314 *
mp-wp_genesis 315 * @param string $path File path to test.
mp-wp_genesis 316 * @return bool True if suitable, false if not suitable.
mp-wp_genesis 317 */
mp-wp_genesis 318 function file_is_displayable_image($path) {
mp-wp_genesis 319 $info = @getimagesize($path);
mp-wp_genesis 320 if ( empty($info) )
mp-wp_genesis 321 $result = false;
mp-wp_genesis 322 elseif ( !in_array($info[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG)) ) // only gif, jpeg and png images can reliably be displayed
mp-wp_genesis 323 $result = false;
mp-wp_genesis 324 else
mp-wp_genesis 325 $result = true;
mp-wp_genesis 326
mp-wp_genesis 327 return apply_filters('file_is_displayable_image', $result, $path);
mp-wp_genesis 328 }
mp-wp_genesis 329
mp-wp_genesis 330 ?>