Skip to content

Instantly share code, notes, and snippets.

@Ryuske
Created May 10, 2016 18:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Ryuske/a10c2dcdec0f849c653c646e9aec86d3 to your computer and use it in GitHub Desktop.
Save Ryuske/a10c2dcdec0f849c653c646e9aec86d3 to your computer and use it in GitHub Desktop.
Methods for uploading images
<?php
/**
* Methods for manipulating & storing images locally and on Amazon AWS.
*
*/
class ImagesHandler {
/**
* The name of the Amazon AWS bucket
*
* @var string
*/
protected $bucket = 'mymv3';
/**
* The name of the Amazon CDN domain
*
* @var string
*/
protected $domain = 'https://d9k47aak4t84n.cloudfront.net/';
/**
* Image uploader for non croppable images
*
* @param $campaign_id
* @param string $input
* @param string $type
* @return string
*/
public function processImage($campaign_id, $input='upload', $type='ckeditor') {
$path = storage_path() . '/tmp';
$file = Input::file($input)->getFileName() . '.' . Input::file($input)->getClientOriginalExtension();
$filepath = $path . '/' . $file;
Input::file($input)->move($path, $file);
// Figure out what kind of image it was, and load it into our libarary accordingly
switch (strtolower(Input::file($input)->getClientOriginalExtension())) {
case 'jpeg':
case 'jpg':
$original = imagecreatefromjpeg($filepath);
break;
case 'png':
$original = imagecreatefrompng($filepath);
}
if (!isset($original)) {
echo '<div style="display: inline-block; width: 100%;">There was an issue with that image! Please close this dialog box and try again.</div>';
return '';
}
// Create variables with information about the image
list($width, $height) = getimagesize($filepath);
if ($width > 640) {
// Create height that is within the correct aspect ratio
$ratio_height = $height * (640 / $width);
// Create blank for the image
$output_full = imagecreatetruecolor(640, $ratio_height);
imagefill($output_full, 0, 0, imagecolorallocate($output_full, 255, 255, 255));
// Fill in the blank with the scaled image (proportionally scale image)
imagecopyresampled($output_full, $original, 0, 0, 0, 0, 640, $ratio_height, $width, $height);
// Write out the changes
switch (strtolower(Input::file($input)->getClientOriginalExtension())) {
case 'jpeg':
case 'jpg':
imagejpeg($output_full, $filepath);
break;
case 'png':
imagepng($output_full, $filepath);
}
}
// Store the changes in the DB, upload to Amazon, and delete from the server
$this->store([
'id' => $campaign_id,
'filename' => $file,
'source' => $filepath
]);
if ('ckeditor' == $type) {
echo '<script type="text/javascript">
window.parent.CKEDITOR.tools.callFunction(' . Input::get('CKEditorFuncNum') . ', \'' . $this->domain . $campaign_id . '/' . $file . '\');
</script>';
echo 'Success!';
return '';
}
return $this->domain . $campaign_id . '/' . $file;
}
/**
* Image uploader used by CKEditor for branded pages
*
* @param $page_id
* @param string $image
* @return string
*/
static public function processPageImage($page_id, $image='upload') {
$path = public_path() . '/images/pages/' . $page_id;
$file = Input::file($image)->getFileName() . '.' . Input::file($image)->getClientOriginalExtension();
$filepath = $path . '/' . $file;
Input::file($image)->move($path, $file);
// Figure out what kind of image it was, and load it into our libarary accordingly
switch (strtolower(Input::file($image)->getClientOriginalExtension())) {
case 'jpeg':
case 'jpg':
$original = imagecreatefromjpeg($filepath);
break;
case 'png':
$original = imagecreatefrompng($filepath);
}
if (!isset($original))
echo 'There was an error!';
// Create variables with information about the image
list($width, $height, $type, $attributes) = getimagesize($filepath);
// Create blank for the image
$output_full = imagecreatetruecolor($width, $height);
imagefill($output_full, 0, 0, imagecolorallocatealpha($output_full, 255, 255, 255, 127));
// Fill in the blank with the scaled image (proportionally scale image)
imagecopyresampled($output_full, $original, 0, 0, 0, 0, $width, $height, $width, $height);
// Write out the changes
switch (strtolower(Input::file($image)->getClientOriginalExtension())) {
case 'jpeg':
case 'jpg':
imagejpeg($output_full, $filepath);
break;
case 'png':
imagealphablending($output_full, true);
imagesavealpha($output_full, true);
imagepng($output_full, $filepath);
}
if ('upload' === $image) {
echo '<script type="text/javascript">
window.parent.CKEDITOR.tools.callFunction(' . Input::get('CKEditorFuncNum') . ', \'' . Config::get('app.url') . '/images/pages/' . $page_id . '/' . $file . '\');
window.parnet.close();
</script>';
echo 'Success!';
} else {
return Config::get('app.url') . '/images/pages/' . $page_id . '/' . $file;
}
}
/**
* Used to crop and resize featured image for pages
*
* @param int $page_id
* @return mixed
*/
static public function processPageFeaturedImage($page_id) {
$path = public_path() . '/images/pages/' . $page_id;
$file = Input::file('featured-image')->getFileName() . '.' . Input::file('featured-image')->getClientOriginalExtension();
$filepath = $path . '/' . $file;
Input::file('featured-image')->move($path, $file);
// Figure out what kind of image it was, and load it into our libarary accordingly
switch (strtolower(Input::file('featured-image')->getClientOriginalExtension())) {
case 'jpeg':
case 'jpg':
$original = imagecreatefromjpeg($filepath);
break;
case 'png':
$original = imagecreatefrompng($filepath);
}
if (!isset($original))
return false;
// Create variables with information about the image
list($width, $height) = getimagesize($filepath);
// Create blanks for the images
$output = imagecreatetruecolor(252, 142);
imagefill($output, 0, 0, imagecolorallocate($output, 255, 255, 255));
// Scale down the previously modified image
imagecopyresampled($output, $original, 0, 0, 0, 0, 252, 142, $width, $height);
// Write out the changes
switch (strtolower(Input::file('featured-image')->getClientOriginalExtension())) {
case 'jpeg':
case 'jpg':
imagejpeg($output, $path . '/' . $file);
break;
case 'png':
imagepng($output, $path . '/' . $file);
}
return Config::get('app.url') . '/images/pages/' . $page_id . '/' . $file;
}
/**
* Used to crop and resize featured image; Also creates thumbnail size & uploads to Amazon S3
*
* @param object $campaign
* @return mixed
*/
public function processFeaturedImage($campaign) {
$path = storage_path() . '/tmp';
if (\Input::has('featured-image-url')) {
$filepath = public_path(Input::get('featured-image-url'));
if (false !== strpos($filepath, '?')) {
$filepath = str_replace(substr($filepath, strpos($filepath, '?')), '', $filepath);
}
$extension = pathinfo($filepath, PATHINFO_EXTENSION);
$filename = pathinfo($filepath, PATHINFO_FILENAME);
$file = $filename . '.' . $extension;
} else {
$filepath = public_path() . Input::get('fb-photo');
$extension = pathinfo($filepath, PATHINFO_EXTENSION);
$filename = pathinfo($filepath, PATHINFO_FILENAME);
$file = $filename . '.' . $extension;
}
// Figure out what kind of image it was, and load it into our libarary accordingly
switch (strtolower($extension)) {
case 'jpeg':
case 'jpg':
$original = imagecreatefromjpeg($filepath);
break;
case 'png':
$original = imagecreatefrompng($filepath);
}
if (false === $original) {
Log::warning('Process Featured Image Warning', ['context' => '$original = false; Unsure of errors.']);
return \Redirect::back()->withInput();
}
list($width, $height) = getimagesize($filepath);
// Create blanks for the images
$output_full = imagecreatetruecolor(745, 419);
imagefill($output_full, 0, 0, imagecolorallocate($output_full, 255, 255, 255));
$output_thumbnail = imagecreatetruecolor(252, 142);
imagefill($output_thumbnail, 0, 0, imagecolorallocate($output_thumbnail, 255, 255, 255));
if ($width >= 745 && $height >= 419) {
$w = (Input::has('w') && 10 < Input::get('w')) ? Input::get('w') : 348;
$h = (Input::has('h') && 10 < Input::get('h')) ? Input::get('h') : 196;
if (Input::has('y')) {
$y = (Input::get('y') * ($width / $w));
if ($y < 1) {
$y = 0;
}
imagecopyresampled($output_full, $original, 0, 0, 0, $y, 745, 419, $width, ($width * ($h / $w)));
} else {
imagecopyresampled($output_full, $original, 0, 0, 0, 0, 745, 419, $width, $height);
}
} else {
$multiplier = 1000/$width;
$small_centered_x = (745-$width)/2;
$small_centered_y = (419-$height)/2;
$big_centered_x = (745-($width*$multiplier))/2;
$big_centered_y = (419-($height*$multiplier))/2;
$ratio = $width/$height;
// Create blank for the image
imagefill($output_full, 0, 0, imagecolorallocate($output_full, 255, 255, 255));
imagecopyresampled($output_full, $original, $big_centered_x, $big_centered_y, 0, 0, $width*$multiplier, $height*$multiplier, $width, $height);
imagefilledrectangle($output_full, 0, 0, 745, 419, imagecolorallocatealpha($output_full, 75, 75, 75, 75));
if ($width > 745) {
$small_centered_y = (419-(745*$ratio))/2;
imagecopyresampled($output_full, $original, 0, $small_centered_y, 0, 0, 745, 745*$ratio, $width, $height);
} elseif ($height > 419) {
$small_centered_x = (745-(419*$ratio))/2;
imagecopyresampled($output_full, $original, $small_centered_x, 0, 0, 0, 419*$ratio, 419, $width, $height);
} else {
imagecopyresampled($output_full, $original, $small_centered_x, $small_centered_y, 0, 0, $width, $height, $width, $height);
}
}
// Scale down the previously modified image
imagecopyresampled($output_thumbnail, $output_full, 0, 0, 0, 0, 252, 142, 745, 419);
// Figure out what we're going to be calling our new thumbnail
$thumbnail_name = $filename . '-thumb.' . $extension;
// Write out the changes
switch (strtolower($extension)) {
case 'jpeg':
case 'jpg':
imagejpeg($output_full, $filepath);
imagejpeg($output_thumbnail, $path . '/' . $thumbnail_name);
break;
case 'png':
imagepng($output_full, $filepath);
imagepng($output_thumbnail, $path . '/' . $thumbnail_name);
}
// Store the changes in the DB, upload to Amazon, and delete from the server
$this->store([
'id' => $campaign->id,
'filename' => $file,
'source' => $filepath
]);
$this->store([
'id' => $campaign->id,
'filename' => $thumbnail_name,
'source' => $path . '/' . $thumbnail_name
]);
$response = $this->domain . $campaign->id . '/' . $file;
if (!$response) {
Log::warning('Process Featured Image Warning', ['context' => "$response = false;\n" + print_r($file, true)]);
return \Redirect::back()->withInput();
}
return $response;
}
/**
* Store a newly created image in storage.
*
* $data = [
* 'id' => $campaign->id
* 'filename' => 'myImage.jpg',
* 'source' => '/my/tmp/path/myImage.jpg'
* ]
*
* @param array $data
* @return bool
*/
public function store($data) {
// Rules that the form inputs must conform to
$rules = [
'id' => 'required|exists:campaigns,id|max:10',
'filename' => 'required',
'source' => 'required'
];
// Check input against rules
$validator = \Validator::make($data, $rules);
// If validation fails return false
if ($validator->fails()) {
return false;
}
exec("cd " . base_path() . "; php artisan file:send-s3 {$this->domain} {$this->bucket} {$data['id']}/{$data['filename']} {$data['source']} {$data['id']}");
return true;
}
public function tmpStore($data) {
// Rules that the form inputs must conform to
$rules = [
'filename' => 'required',
'source' => 'required'
];
// Check input against rules
$validator = \Validator::make($data, $rules);
// If validation fails return false
if ($validator->fails()) {
return false;
}
if (App::Environment('production')) {
Log::info("cd " . base_path() . "; php artisan file:send {$data['source']}");
exec("cd " . base_path() . "; php artisan file:send {$data['source']}");
}
return true;
}
/**
* Remove the specified resource from storage.
*
* @param string $url
* @return Response
*/
public function destroy($url) {
$s3 = AWS::get('s3');
$s3->deleteObject([
'Bucket' => $this->bucket,
'Key' => str_replace(['https://mymv3.s3.amazonaws.com/', $this->domain], '', $url)
]);
Image::where('url', '=', $url)->delete();
return true;
}
/**
* Used to download a photo from facebook for campaign featured image
*
* @return string
*/
public function downloadFacebookPhoto() {
$photo_url = Input::get('fb-photo');
try {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $photo_url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$photo = curl_exec($ch);
curl_close($ch);
$original = imagecreatefromstring($photo);
$filename = time() . '-' . rand(0, 9999);
$url_filepath = 'images/tmp/' . $filename;
$filepath = public_path($url_filepath);
$pathinfo = explode('?', pathinfo($photo_url, PATHINFO_EXTENSION));
switch (strtolower($pathinfo[0])) {
case 'jpeg':
case 'jpg':
$type = 'jpg';
imagejpeg($original, $filepath. '.' . $type);
break;
case 'png':
$type = 'png';
imagepng($original, $filepath . '.' . $type);
}
} catch(Exception $e) {
return json_encode(['error' => $e->getMessage()]);
}
//$image_contents = file_get_contents($filepath . '.' . $type);
$this->tmpStore([
'filename' => $url_filepath . '.' . $type,
'source' => public_path($url_filepath . '.' . $type)
]);
return json_encode([
//'dataurl' => 'data:image/' . $type . ';base64,' . base64_encode($image_contents),
'filepath' => '/' . $url_filepath . '.' . $type
]);
}
/**
* Used to upload an image for cropping
*
* @return bool|mixed|string|void
*/
public function uploadTmpImage() {
ini_set("memory_limit", "-1");
$validator = Validator::make(Input::all(), [
'featured-image' => 'required|image|mimes:jpeg,png|max:7168'
]);
if ($validator->fails()) {
return json_encode(['error' => $validator->errors()->first()]);
}
$path = public_path() . '/images/tmp';
$extension = Input::file('featured-image')->guessClientExtension();
$filename = Input::file('featured-image')->getFileName();
$file = $filename . '.' . $extension;
$filepath = $path . '/' . $file;
try {
Input::file('featured-image')->move($path, $file);
} catch (Exception $e) {
return json_encode(['error' => $e->getMessage()]);
}
// Figure out what kind of image it was, and load it into our libarary accordingly
switch (strtolower($extension)) {
case 'jpeg':
case 'jpg':
$original = imagecreatefromjpeg($filepath);
break;
case 'png':
$original = imagecreatefrompng($filepath);
}
if (!isset($original))
return json_encode(['error' => 'We were unable to process your image.']);
list($width, $height) = getimagesize($filepath);
$minimum_ratio = 348/196;
$image_ratio = $width/$height;
if (!Input::has('editor') && (223 > $width || 125 > $height)) {
return json_encode(['error' => 'Your picture must be at least 223x125']);
}
if (348/$image_ratio < 196) {
$new_width = $height * $minimum_ratio;
// Create blanks for the images
$output_full = imagecreatetruecolor($new_width, $height);
imagefill($output_full, 0, 0, imagecolorallocate($output_full, 255, 255, 255));
imagecopy($output_full, $original, 0, 0, 0, 0, $new_width, $height);
} else {
// Create blanks for the images
$output_full = imagecreatetruecolor($width, $height);
imagefill($output_full, 0, 0, imagecolorallocate($output_full, 255, 255, 255));
imagecopyresampled($output_full, $original, 0, 0, 0, 0, $width, $height, $width, $height);
}
// Write out the changes
switch (strtolower($extension)) {
case 'jpeg':
case 'jpg':
imagejpeg($output_full, $filepath);
break;
case 'png':
imagepng($output_full, $filepath);
}
$this->tmpStore([
'filename' => '/images/tmp/' . $file,
'source' => $filepath
]);
return json_encode(['file' => '/images/tmp/' . $file]);
}
/**
* Used to rotate an image clockwise 90*
*
* @return bool|mixed|string|void
*/
public function rotateImage() {
ini_set("memory_limit", "-1");
$validator = Validator::make(Input::all(), [
'image' => 'required'
]);
if ($validator->fails()) {
return json_encode(['error' => $validator->errors()->first()]);
}
$file = str_replace($this->domain, '', Input::get('image'));
if (false !== strpos($file, '?')) {
$file = str_replace(substr($file, strpos($file, '?')), '', $file);
}
$filepath = public_path($file);
$extension = pathinfo($filepath, PATHINFO_EXTENSION);
try {
// Figure out what kind of image it was, and load it into our library accordingly
switch (strtolower($extension)) {
case 'jpeg':
case 'jpg':
$original = imagecreatefromjpeg($filepath);
break;
case 'png':
$original = imagecreatefrompng($filepath);
}
} catch (Exception $e) {
return json_encode(['error' => $e->getMessage()]);
}
if (!isset($original))
return false;
list($width, $height) = getimagesize($filepath);
if (223 > $height || 125 > $width) {
return json_encode(['error' => 'Your rotated picture must be at least 223x125', 'file' => $file]);
}
$output_rotated = imagecreatetruecolor($height, $width);
imagefill($output_rotated, 0, 0, imagecolorallocate($output_rotated, 255, 255, 255));
$output_rotated = imagerotate($original, -90, imagecolorallocate($output_rotated, 255, 255, 255));
// Write out the changes
switch (strtolower($extension)) {
case 'jpeg':
case 'jpg':
imagejpeg($output_rotated, $filepath);
break;
case 'png':
imagepng($output_rotated, $filepath);
}
$this->tmpStore([
'filename' => $file,
'source' => $filepath
]);
return json_encode(['file' => $file . '?' . time()]);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment