Created
October 15, 2014 18:29
-
-
Save chrisciampoli/3f2d4b21cb08a57fc0a9 to your computer and use it in GitHub Desktop.
Create a scaled image from PHP
This file contains 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
/** | |
* Creates scaled version of source image, optionally cropping. | |
* Handles scaling and centering in target size properly. | |
* | |
* $options = array( | |
* 'upload_dir' => thumbnail destination directory (required) | |
* 'thumb_name' => thumbnail filename in destination directory (required) | |
* 'dst_width' => target image width (required) | |
* 'dst_height' => target image height (required) | |
* 'target_format' => format to save to, defaults to source format, one of 'imagejpeg','imagegif','imagepng' | |
* 'x' => crop X start position | |
* 'y' => crop Y start position | |
* 'width' => crop width | |
* 'height' => crop height | |
* ); | |
*/ | |
function create_scaled_image($file_name, $options) { | |
$file_path = $options['upload_dir'].$file_name; | |
$new_file_path = $options['upload_dir'].$options['thumb_name']; | |
$img_data = getimagesize($file_path); | |
list($img_width, $img_height) = $img_data; | |
if (!$img_width || !$img_height) { | |
return array('status' => 'error', 'error' => 'Failed to get image dimensions.', 'src' => $file_path, 'dst' => $new_file_path); | |
} | |
$dst_x = 0; | |
$dst_y = 0; | |
if (isset($options['dst_width']) && !isset($options['dst_height'])) { | |
$options['dst_height'] = $options['dst_width'] / ($img_width / $img_height); | |
} elseif (isset($options['dst_height']) && !isset($options['dst_width'])) { | |
$options['dst_width'] = $options['dst_height'] * ($img_width / $img_height); | |
} elseif (!isset($options['dst_width']) && !isset($options['dst_height'])) { | |
error_log('Cannot create scaled image without dst_width and dst_height'); | |
return array('status' => 'error', 'error' => 'Cannot create scaled image without dst_width and dst_height'); | |
} | |
$dst_width_inner = $options['dst_width']; | |
$dst_height_inner = $options['dst_height']; | |
if (!isset($options['x']) && !isset($options['y']) && !isset($options['width']) && !isset($options['height'])) { | |
$options['width'] = $img_width; | |
$options['height'] = $img_height; | |
$options['x'] = 0; | |
$options['y'] = 0; | |
$src_aspect_ratio = $options['width'] / $options['height']; | |
$dst_aspect_ratio = $options['dst_width'] / $options['dst_height']; | |
if ($src_aspect_ratio < $dst_aspect_ratio) { // need x-padding | |
if(!$options['toggle']) { | |
$dst_x = ($options['dst_width'] - $options['dst_height'] * $src_aspect_ratio) / 2; | |
$dst_width_inner = $options['dst_height'] * $src_aspect_ratio; | |
} | |
} else if ($src_aspect_ratio > $dst_aspect_ratio) { // need y-padding | |
if(!$options['toggle']) { | |
$dst_y = ($options['dst_height'] - $options['dst_width'] / $src_aspect_ratio) / 2; | |
$dst_height_inner = $options['dst_width'] / $src_aspect_ratio; | |
} | |
} | |
} | |
/* | |
echo '<br />'; | |
echo 'source aspect ratio: '.@$src_aspect_ratio.'<br />'; | |
echo 'src_width: '.$options['width'].'<br />'; | |
echo 'src_height: '.$options['height'].'<br />'; | |
echo 'dst aspect ratio: '.@$dst_aspect_ratio.'<br />'; | |
echo 'dst_width: '.$options['dst_width'].'<br />'; | |
echo 'dst_height: '.$options['dst_height'].'<br />'; | |
echo 'dst_width_inner: '.$dst_width_inner.'<br />'; | |
echo 'dst_height_inner: '.$dst_height_inner.'<br />'; | |
echo 'dst_x: '.$dst_x.'<Br />'; | |
echo 'dst_y: '.$dst_y.'<br />'; | |
*/ | |
$new_width = $options['dst_width']; | |
$new_height = $options['dst_height']; | |
$new_img = imagecreatetruecolor($new_width, $new_height); | |
switch ($img_data['mime']) { | |
case 'image/jpg': | |
case 'image/jpeg': | |
$src_img = imagecreatefromjpeg($file_path); | |
$write_image = 'imagejpeg'; | |
break; | |
case 'image/gif': | |
imagecolortransparent($new_img, @imagecolorallocate($new_img, 0, 0, 0)); | |
$src_img = @imagecreatefromgif($file_path); | |
$write_image = 'imagegif'; | |
break; | |
case 'image/png': | |
imagecolortransparent($new_img, @imagecolorallocate($new_img, 0, 0, 0)); | |
imagealphablending($new_img, false); | |
imagesavealpha($new_img, true); | |
$src_img = @imagecreatefrompng($file_path); | |
$write_image = 'imagepng'; | |
break; | |
default: | |
$src_img = $image_method = null; | |
} | |
if (isset($options['target_format'])) { | |
$write_image = $options['target_format']; | |
} | |
$quality = null; | |
switch ($write_image) { | |
case 'imagepng': $quality = 9; break; | |
case 'imagejpeg': $quality = 95; break; | |
} | |
$success = $src_img && @imagecopyresampled( | |
$new_img, | |
$src_img, | |
$dst_x, | |
$dst_y, | |
$options['x'], | |
$options['y'], | |
$dst_width_inner, | |
$dst_height_inner, | |
$options['width'], | |
$options['height'] | |
) && $write_image($new_img, $new_file_path, $quality); | |
// Free up memory (imagedestroy does not delete files): | |
imagedestroy($src_img); | |
imagedestroy($new_img); | |
if ($success) { | |
if (USE_AMAZON) { | |
$s3 = new AmazonS3(); | |
$s3->ssl_verification = false; | |
$resp = $s3->create_object( | |
DATA_BUCKET, $new_file_path, | |
$opts = array('body' => file_get_contents($new_file_path), 'acl' => AmazonS3::ACL_PUBLIC) | |
); | |
} | |
$new_file_url = SITE_URI.'/uploads/'.$new_file_path; | |
return array( | |
'status' => 'ok', | |
'dst_file' => $new_file_url, | |
'dst_path' => $new_file_path, | |
'width' => $new_width, | |
'height' => $new_height | |
); | |
} else { | |
return array('status' => 'error', 'error' => 'There was a problem processing the image.'); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment