Created
July 19, 2013 04:18
-
-
Save felipelavinz/6035203 to your computer and use it in GitHub Desktop.
Create image thumbnails with PHP and Imagick
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$abs_start = microtime(true); | |
$path = __DIR__; | |
$Directory = new RecursiveDirectoryIterator('.'); | |
$img_extensions = array('jpg', 'jpeg', 'gif', 'png'); | |
$desired_sizes = array( | |
'300x300', | |
'800x450', | |
'220x260', | |
'125x80', | |
'340x220', | |
'365x255', | |
'660x430', | |
'940x345', | |
'940x450', | |
'960x960' | |
); | |
foreach ( new RecursiveIteratorIterator($Directory) as $filename => $file ){ | |
if ( $file->isDir() ) | |
continue; | |
$fullpath = $file->getPathName(); | |
$path = pathinfo( $fullpath, PATHINFO_DIRNAME ); | |
$filename = pathinfo( $fullpath, PATHINFO_BASENAME ); | |
$extension = strtolower(pathinfo( $fullpath, PATHINFO_EXTENSION )); | |
$noext = str_replace( '.'. $extension, '', $filename ); | |
// si no es imagen, chao pescao | |
if ( ! in_array($extension, $img_extensions) ) | |
continue; | |
$parts = explode( '-', str_replace( '.'.$extension, '', $filename) ); | |
if ( $parts > 1 ) { | |
$maybe_size = end($parts); | |
$matches = array(); | |
if ( preg_match('/([0-9]{1,4})(x){1}([0-9]{1,4})/', $maybe_size, $matches) === 1 ){ | |
// print_r($matches); | |
// unlink( $fullpath ); | |
continue; | |
} else { | |
echo $fullpath."\n"; | |
} | |
} | |
// continue; | |
$start = microtime(true); | |
$image_size = getimagesize( $fullpath ); | |
list($w, $h) = $image_size; | |
foreach ( $desired_sizes as $size ){ | |
$image = new Imagick( $fullpath ); | |
$dimensions = explode('x', $size); | |
$crop = $size === '960x960' ? false : true; | |
list( $dw, $dh ) = $dimensions; | |
$dims = image_resize_dimensions( $w, $h, $dw, $dh, $crop ); | |
list( $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h ) = $dims; | |
if ( $crop ) { | |
$image->cropThumbnailImage( $dw, $dh ); | |
// $image->cropImage( $src_w, $src_h, $src_x, $src_y ); | |
// $image->setImagePage( $src_w, $src_h, 0, 0); | |
// if ( $dst_w || $dst_h ) { | |
// // If destination width/height isn't specified, use same as | |
// // width/height from source. | |
// if ( ! $dst_w ) | |
// $dst_w = $src_w; | |
// if ( ! $dst_h ) | |
// $dst_h = $src_h; | |
// $image->scaleImage( $dst_w, $dst_h ); | |
// } else { | |
// $size = $image->getImageGeometry(); | |
// } | |
} | |
$dest_filename = "{$path}/{$noext}-{$size}.{$extension}"; | |
echo $dest_filename ."\n"; | |
$image->writeImage( $dest_filename ); | |
unset($image); | |
} | |
echo 'hecho en: '. ( microtime(true) - $start ) .' segundos'."\n"; | |
echo '---'."\n"; | |
} | |
echo 'TIEMPO TOTAL: '. ( microtime(true) - $abs_start ) .' segundos'."\n"; | |
function image_resize_dimensions($orig_w, $orig_h, $dest_w, $dest_h, $crop = false) { | |
if ($orig_w <= 0 || $orig_h <= 0) | |
return false; | |
// at least one of dest_w or dest_h must be specific | |
if ($dest_w <= 0 && $dest_h <= 0) | |
return false; | |
if ( $crop ) { | |
// crop the largest possible portion of the original image that we can size to $dest_w x $dest_h | |
$aspect_ratio = $orig_w / $orig_h; | |
$new_w = min($dest_w, $orig_w); | |
$new_h = min($dest_h, $orig_h); | |
if ( !$new_w ) { | |
$new_w = intval($new_h * $aspect_ratio); | |
} | |
if ( !$new_h ) { | |
$new_h = intval($new_w / $aspect_ratio); | |
} | |
$size_ratio = max($new_w / $orig_w, $new_h / $orig_h); | |
$crop_w = round($new_w / $size_ratio); | |
$crop_h = round($new_h / $size_ratio); | |
$s_x = floor( ($orig_w - $crop_w) / 2 ); | |
$s_y = floor( ($orig_h - $crop_h) / 2 ); | |
} else { | |
// don't crop, just resize using $dest_w x $dest_h as a maximum bounding box | |
$crop_w = $orig_w; | |
$crop_h = $orig_h; | |
$s_x = 0; | |
$s_y = 0; | |
list( $new_w, $new_h ) = wp_constrain_dimensions( $orig_w, $orig_h, $dest_w, $dest_h ); | |
} | |
// if the resulting image would be the same size or larger we don't want to resize it | |
if ( $new_w >= $orig_w && $new_h >= $orig_h ) | |
return false; | |
// the return array matches the parameters to imagecopyresampled() | |
// int dst_x, int dst_y, int src_x, int src_y, int dst_w, int dst_h, int src_w, int src_h | |
return array( 0, 0, (int) $s_x, (int) $s_y, (int) $new_w, (int) $new_h, (int) $crop_w, (int) $crop_h ); | |
} | |
function wp_constrain_dimensions( $current_width, $current_height, $max_width=0, $max_height=0 ) { | |
if ( !$max_width and !$max_height ) | |
return array( $current_width, $current_height ); | |
$width_ratio = $height_ratio = 1.0; | |
$did_width = $did_height = false; | |
if ( $max_width > 0 && $current_width > 0 && $current_width > $max_width ) { | |
$width_ratio = $max_width / $current_width; | |
$did_width = true; | |
} | |
if ( $max_height > 0 && $current_height > 0 && $current_height > $max_height ) { | |
$height_ratio = $max_height / $current_height; | |
$did_height = true; | |
} | |
// Calculate the larger/smaller ratios | |
$smaller_ratio = min( $width_ratio, $height_ratio ); | |
$larger_ratio = max( $width_ratio, $height_ratio ); | |
if ( intval( $current_width * $larger_ratio ) > $max_width || intval( $current_height * $larger_ratio ) > $max_height ) | |
// The larger ratio is too big. It would result in an overflow. | |
$ratio = $smaller_ratio; | |
else | |
// The larger ratio fits, and is likely to be a more "snug" fit. | |
$ratio = $larger_ratio; | |
$w = intval( $current_width * $ratio ); | |
$h = intval( $current_height * $ratio ); | |
// Sometimes, due to rounding, we'll end up with a result like this: 465x700 in a 177x177 box is 117x176... a pixel short | |
// We also have issues with recursive calls resulting in an ever-changing result. Constraining to the result of a constraint should yield the original result. | |
// Thus we look for dimensions that are one pixel shy of the max value and bump them up | |
if ( $did_width && $w == $max_width - 1 ) | |
$w = $max_width; // Round it up | |
if ( $did_height && $h == $max_height - 1 ) | |
$h = $max_height; // Round it up | |
return array( $w, $h ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment