Skip to content

Instantly share code, notes, and snippets.

@chrisciampoli
Created October 15, 2014 18:29
Show Gist options
  • Save chrisciampoli/3f2d4b21cb08a57fc0a9 to your computer and use it in GitHub Desktop.
Save chrisciampoli/3f2d4b21cb08a57fc0a9 to your computer and use it in GitHub Desktop.
Create a scaled image from PHP
/**
* 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