Use imagick with S3 AWS - php

These are my first steps with AWS S3, so and my goal is to use imagick for manipulating the image before I upload to S3 AWS.
I use this function for resize and scale the image (works perfect on output browser):
function resizeImg($img, $width, $height) {
$i = new Imagick($img);
$gig = $i->getImageGeometry();
// crop the image
if(($gig['width']/$width) < ($gig['height']/$height)) {
$i->cropImage($gig['width'], floor($height * $gig['width'] / $width), 0, (($gig['height'] - ($height * $gig['width'] / $width)) / 2));
} else {
$i->cropImage(ceil($width * $gig['height'] / $height), $gig['height'], (($gig['width'] - ($width * $gig['height'] / $height)) / 2), 0);
}
$i->ThumbnailImage($width, $height, true);
$i->setImageFormat("jpeg");
$i->setImageCompressionQuality(90);
$i->getimageblob(); // I tried it with and without getimageblob
return $i;
}
Thats my attempt, Upload to S3:
$tmpImg = $_FILES['inputImage']['tmp_name'];
$newImgFile = resizeImg($tmpImg, 100, 100);
$s3->putObjectFile($newImgFile, BUCKET_NAME, $newfilename, S3::ACL_PUBLIC_READ);
But I get this error:
Warning: S3::inputFile(): Unable to open input file: ���� in.....
What I`m doing wrong?
Is imagick not compatible with S3 AWS?
Or is there a better way?
And my next goal is to put different image resizes to S3, e.g 100x100, 300x300.... from same input file, but of course I have to solve before the first goal.
EXTRA:
With this solution from here:
PHP Imagick: Write Image directly to Amazon S3?
I get this Error:
Warning: S3::putObject(): [SignatureDoesNotMatch] The request signature we calculated does not match the signature you provided. Check your key and signing method.
If I do this: $new = urlencode($new); or $new = strtolower($new); ...Works to upload but no readable!
The error came from extra spaces or slashes in there, so far as I have understood
And if its important, here the Url from the image in S3
https->awsCount.xxxx.xxxxx/img.jpg?AWSAccessKeyId=xxxx&Expires=1383787878&Signature=xxxx&x-amz-security-token=AQoDYXdzEGAasAJlJXrt/7FPf84wE9stfgBfEoWaPMDHlubQBlQ6oMY6sNMT4cizkEm9khypHulLB/zJ%2BbqqAErvFBKKs2I9bKDBzrKYKhgRn%2Bta057CZaLougsxHLRGquhd5H26br/Odkq98%2BoDTnfK0LHFa9vYbX6sXDIzCSHcZx4%2B5o0y3cKlxCMsYLqw6wYD1DNjJ%2BHlWWuh%2B6V0FtpbYaErB1XUZfRRZdx3ZPEOvyZxQS7uzP8C3B1nK0wo3uqqSAhn9PPtQt5jrRutYRao2KugxK8TbkZbr/v5NOYSbpc%2BmI2iYYrUjylqgenzf85Avss0CA1GfOzg%2BMs2/TQ7evH7epr09B8Vyd89Gk1XQpVMyrTSvbzDYE8UCcgrUrXgdHTYWdGLVZ%2BBHzft9nHtNhggePD6AXMuIP%2Ba6ZMF

You are trying to put an object from S3 from a file (putObjectFile takes a file name as an argument) but you're giving the image blob as a parameter, instead of a file name.
You should do something like this:
In resizeImg:
return $i-> getimageblob(); //(this is just an assumption)
For uploading to S3, something similar to this:
$s3 = new AmazonS3();
$s3->batch()->create_object(__BUCKET__,$filename, array(
'body' => $object,
'acl' => AmazonS3::ACL_PUBLIC,
'contentType' => $contentType,
'storage' => AmazonS3::STORAGE_REDUCED
));
$file_upload_response = $s3->batch()->send();
Note that this is using the PHP SDK V1 (not sure if you're using V2).

I'll have the answer, I show the whole code for each one:
if (!empty($_FILES["input_file"])) {
if ($_FILES["input_file"]["error"] !== UPLOAD_ERR_OK) {
echo "<p>An error occurred.</p>";
exit;
}
// Move/Copy from temporary file to local file
$success = move_uploaded_file($_FILES["input_file"]["tmp_name"],
'local_temp_file_directory/' . $_FILES["input_file"]["name"]);
if (!$success) {
echo "<p>Unable to save file.</p>";
exit;
}
}
// I make a function to get the local file and save the edited file
function resizeImg($img_from_local_file, $width, $height, $pathToSaveImg) {
$i = new Imagick($img_from_local_file);
$gig = $i->getImageGeometry();
if(($gig['width']/$width) < ($gig['height']/$height)) {
$i->cropImage($gig['width'], floor($height * $gig['width'] / $width), 0, (($gig['height'] - ($height * $gig['width'] / $width)) / 2));
} else {
$i->cropImage(ceil($width * $gig['height'] / $height), $gig['height'], (($gig['width'] - ($width * $gig['height'] / $height)) / 2), 0);
}
$i->ThumbnailImage($width, $height,true);
$i->setImageFormat("jpeg");
$i->setImageCompressionQuality(90);
$i->writeImage($pathToSaveImg);
return $i->getimage();
}
// Call the resizeImg function
resizeImg("local_temp_file_directory/".$_FILES["input_file"]["name"], 40, 40, "local_temp_file_directory/resized_".$_FILES["input_file"]["name"]);
$s3->putObject(
S3::inputFile("local_temp_file_directory/resized_".$_FILES["input_file"]["name"]),
BUCKET_NAME,
"make_a_new_image_name".date("his").".jpg",
S3::ACL_PUBLIC_READ,
array(),
array("Content-Type"=>'image/jpeg'));
// Remove the temporary local file
unlink("local_temp_file_directory/".$_FILES["input_file"]["name"]);
unlink("local_temp_file_directory/resized_".$_FILES["input_file"]["name"]);
Thats it... Enjoy it!

you can doing these :
$outFile = $this->get('kernel')->getRootDir().'/../web/uploads/imageWithImagick.png';
$url = "http//......";
$img = new Imagick();
$dir = "images/profile";
$uploader = $this->get('core_storage.uploader');
$width = 300;
$height = 500;
$compression = 90;
$imageFormat = "jpeg";
$uploader->uploadImagick($url,$img,$outFile,$width,$height,$dir,$imageFormat,$compression);
and the function :
public function uploadImagick($url,$img,$outFile,$width,$height,$dir,$imageFormat,$compression)
{
$handle = fopen($url, 'rb');
$img->readImageFile($handle);
$gig = $img->getImageGeometry();
if(($gig['width']/$width) < ($gig['height']/$height)) {
$img->cropImage($gig['width'], floor($height * $gig['width'] / $width), 0, (($gig['height'] - ($height * $gig['width'] / $width)) / 2));
} else {
$img->cropImage(ceil($width * $gig['height'] / $height), $gig['height'], (($gig['width'] - ($width * $gig['height'] / $height)) / 2), 0);
}
$img->thumbnailImage($width,$height);
$img->setImageFormat($imageFormat);
$img->setImageCompressionQuality($compression);
$img->writeImage($outFile);
// Generate a unique filename based on the date and add file extension of the uploaded file
$filename = sprintf('%s/%s.%s', $dir, uniqid(), $imageFormat);
$adapter = $this->filesystem->getAdapter();
$adapter->write($filename, file_get_contents($outFile));
unlink($outFile);
return $filename;
}

Related

Imagick PHP - Getting DPI for AI file

I want to get the resolution of an AI file but it only returns 72. However, the resolution is supposed to be 300. If I were to change the resolution of the image using imagick, it would come out to be something far less [the dimensions]. How can I get the actual resolution of a file?
In case I can't use imagick for that, is there a library or framework that can give me the precised resolution of a file (regardless what type)?
I have my code as:
try {
$imagick = new Imagick($imagePath);
$data = $imagick->identifyimage();
}
catch(Exception $e) {
echo json_encode('ERROR: ' . $e->getMessage());
}
if($data['units'] == 'PixelsPerCentimeter') {
$imageResolution = $imagick->getImageResolution(); // Temp Image Resolution
//echo 'pixels per cent lol';
if (!empty($imageResolution['y'])) {
$dpi = intval( round($imageResolution['y'] * 2.54, 2) );
}
}
else $dpi = $data['resolution']['x'];
$width = round($data['geometry']['width'] / $dpi, 3);
$height = round($data['geometry']['height'] / $dpi, 3);

Efficient and fast image uploading

I've been playing around with a new website that will allow members to upload some content and images. I've knocked up the code html, php & mysql (with the help of google) and it now all works but not fast.
It could be my code is inefficient or my hosting company is restricting the uploading speed ... or both. I am very new to developing websites!
Using small size images <300kb is not an issue, but as soon as I use 6mb ones its can take up to 5minutes to upload the images even though I am reducing there size before upload. I've tested without database inserts so I know its the images part thats causing the issue.
Before I start looking at implementing DropBox to store the images ... has anyone come across this problem before that could recommend a different approach?
Code html snippet:
<form name="add-form" action="includes/new_post.php" method="post" enctype="multipart/form-data">
<input id='id_question_pic' name="upfile1[]" type="file" tabindex="3" multiple accept='image/*' max-uploads=6 />
Code in php:
//put all the uploaded images into an array
$files=array();
$fdata=$_FILES['upfile1'];
for($i=0;$i<count($fdata['name']);++$i){
$files[]=array(
'name' =>$fdata['name'][$i],
'type' => $fdata['type'][$i],
'tmp_name'=>$fdata['tmp_name'][$i],
'error' => $fdata['error'][$i],
'size' => $fdata['size'][$i]
);
}
//move to the correct directory, with unique file names
$directory = 'C:\Inetpub\vhosts\mydomain\form_uploads\\'; //use local server path (hosting company)
$dbimagepath = 'form_uploads/';
$result = true;
foreach ($files as $file) {
if ($file['error'] == 0) {
$filename = $file['name'];
if (strlen($filename) > 20) {$filename = substr($filename, strlen($filename) - 8);}
$filename = mt_rand() . '_' . $filename;
//ensure the filename is unique//
while (#getimagesize($directory . $filename)){$filename = mt_rand() . $filename;}
$fullpath = $directory . $filename;
if (exif_imagetype($file['tmp_name'])== 2){
$image = imagecreatefromstring(file_get_contents($file['tmp_name']));
//ORIGINAL DIMENTIONS
list( $width , $height ) = getimagesize($file['tmp_name']);
//ORIGINAL SCALE
$xscale=$width/600;
$yscale=$height/600;
//NEW DIMENSIONS WITH SAME SCALE
if ($yscale > $xscale)
{
$new_width = round($width * (1/$yscale));
$new_height = round($height * (1/$yscale));
}
else
{
$new_width = round($width * (1/$xscale));
$new_height = round($height * (1/$xscale));
}
//NEW IMAGE RESOURCE
if(!($imageResized = imagecreatetruecolor($new_width, $new_height)))
{//error handling}
//RESIZE IMAGE
if(! imagecopyresampled($imageResized, $image , 0 , 0 , 0 , 0 , $new_width , $new_height , $width , $height))
{//error handling}
$image = $imageResized;
$exif = exif_read_data($file['tmp_name']);
if (!empty($exif['Orientation']) || !$exif['Orientation']===null){
switch($exif['Orientation'])
{
case 3: // 180 rotate left
$image=imagerotate($image, 180, -1);
break;
case 6: // 90 rotate right
$image=imagerotate($image, -90, -1);
break;
case 8: // 90 rotate left
$image=imagerotate($image, 90, -1);
break;
default:
break;
}
}
if (imagejpeg($image, $fullpath, 80)){
//call function to update the database
}
imagedestroy($image);
}
else
{$result = false;}
}
}
Take a look at 3rd party solutions that are build to solve your particular problem.
Uploadcare for example.
With it you can have fast reliable uploads even without access to your host's filesystem and upload speed is limited only by your visitor's internet connectivity.

Old PHP GD code no longer working

I have a function which resizes images and whilst it works fine on my test server, it doesn#t work on the new live server. The error message i get is
Warning: imagejpeg(): Unable to open ' /home/sites/public_html/images/2013-24-1-240x300.jpg' for writing: No such file or directory in /home/sites/public_html/includes/functions/html_output.php on line 352
line 352 in the code below is the imagejpeg line near to the bottom. If its creating the image on the fly, I dont understand why its trying to open the file.
Images folder is writeable (changed to 777 to check) as the original image is showing fine. GD is enabled on the live server bundled (2.0.34 compatible)
Both versions of PHP and GD are the same now on both servers. Only difference is test server is running WAMP and live is a linux.
function image_resample($src,$width,$height) {
define(JPEGQUALITY, 75);
define(ALLOWSQUASH,0.10);
if ($src=='') {
return $src;
}
$i = #getimagesize( $src ); // 1-gif (ignore), 2-jpeg, 3-png
if (!(($width == SMALL_IMAGE_WIDTH) && ($height == SMALL_IMAGE_HEIGHT)) &&
!(($width == MEDIUM_IMAGE_WIDTH) && ($height == MEDIUM_IMAGE_HEIGHT))&&
!(($width == LARGE_IMAGE_WIDTH) && ($height == LARGE_IMAGE_HEIGHT))) {
return $src; // can amend to work with other images
}
if (!( ($i[2] == 3) || ($i[2] ==2))) {
return $src;
}
$file = preg_replace( '/\.([a-z]{3,4})$/i', "-{$width}x{$height}.\\1", $src ); // name of resampled image
if (is_file( $file ) ) {
return $file;
}
$scr_w = $i[0];
$scr_h = $i[1];
if (($scr_w * $scr_h * $width * $height) == 0) {
return $src;
}
$howsquashed = ($width / $height * $scr_h / $scr_w);
if (((1 / (1 + ALLOWSQUASH)) < $howsquashed) && ($howsquashed < (1 + ALLOWSQUASH))) $simpleway='true';
$scalefactor = min($width/$scr_w, $height/$scr_h);
$scaled_w = (int)($scr_w * $scalefactor);
$scaled_h = (int)($scr_h * $scalefactor);
$offset_w = max(0,round(($width - $scaled_w) / 2,0));
$offset_h = max(0,round(($height - $scaled_h) / 2));
$dst = DIR_FS_CATALOG . '/' . $file;
$dstim = #imagecreatetruecolor ($width, $height);
$background_color = imagecolorallocate ($dstim, 255, 255, 255);
imagefilledrectangle($dstim, 0, 0, $width, $height, $background_color);
if ( $i[2] == 2) {
$srcim = #ImageCreateFromJPEG ($src); // open
}
elseif ( $i[2] == 3) {
$srcim = #ImageCreateFromPNG ($src);
}
if ($simpleway == 'true') {
imagecopyresampled ($dstim, $srcim, 0, 0, 0, 0, $width, $height, $scr_w, $scr_h);
}
else {
$intim = #imagecreatetruecolor ($width, $height);
imagecopyresampled ($intim, $srcim, $offset_w, $offset_h, 0, 0, $scaled_w, $scaled_h, $scr_w, $scr_h);
imagecopy ( $dstim, $intim, $offset_w, $offset_h, $offset_w, $offset_h, $scaled_w, $scaled_h);
imagedestroy ($intim);
}
if ( $i[2] == 2) {
imagejpeg ($dstim , $dst , JPEGQUALITY);
}
elseif ( $i[2] == 3) {
imagepng ($dstim , $dst);
}
imagedestroy ($srcim);
imagedestroy ($dstim);
return $file; // Use the newly resampled image
}
the message is pretty clear
Warning: imagejpeg(): Unable to open ' /home/sites/public_html/images/2013-24-1-240x300.jpg'
for writing: No such file or directory in
/home/sites/public_html/includes/functions/html_output.php on line 352
if the directory exists chmod it so the apache user can write to it.
if the directory doesnt exist create it and then chmod it (644 should be enough)
if the file exists already - it can not over write it, So chmod the file (its likely you used SCP to transfer it and its under the user you SCP'ed as) ls -l to confirm the permissions

RewriteRule Image from php file to another php script

I am trying to use adaptive images and I have no problem using it with normal linked images that end in .jpg, .png, .gif but when I use a filesystem that a php file grabs a unextensioned file from a directory and uses header Content-Disposition: inline to display the image, the htaccess does not properly run it through the php file.
Here is the Rewrite rule that works for normal linked images:
RewriteRule \.(?:jpe?g|gif|png)$ adaptive-images.php [NC,L]
Here is an example of a image link that needs to be run through adaptive-images.php:
http://localhost/projects/file-system/getmedia.php?id=2&slug=35dq
How do I write another rewrite rule that will take care of those images? I am currently using this rule but it just makes broken images (I have tried some other rules but no difference):
RewriteRule ^getmedia.php$ adaptive-images.php [NC,L]
Although my htaccess rule was maybe at fault, the adaptive images php script does not accommodate php fed images natively.
The htaccess rule I used was:
RewriteCond %{QUERY_STRING} !(^|&)noadaptive=(true)(&|$) [NC]
RewriteRule ^getmedia\.php.*$ adaptive-images.php [NC,L]
This allows me to send all the images generated by getmedia.php to be sent into adaptive-images.php and if it has noadaptive=true as a get parameter then it does not utilize the script so I can get full sized images again.
Here is the modified adaptive-images.php
<?php
//sendErrorImage("there is a problem");
/* PROJECT INFO --------------------------------------------------------------------------------------------------------
Version: 1.5.2
Changelog: http://adaptive-images.com/changelog.txt
Homepage: http://adaptive-images.com
GitHub: https://github.com/MattWilcox/Adaptive-Images
Twitter: #responsiveimg
LEGAL:
Adaptive Images by Matt Wilcox is licensed under a Creative Commons Attribution 3.0 Unported License.
/* CONFIG ----------------------------------------------------------------------------------------------------------- */
/* MODIFICATIONS -------------------------------------------------------------------------------------------------------
Mods by: MLM from VisualPulse.net
Description: Added compatibility for php fed images.
Intended for use with a ambiguous file system that serve the files through a php file
NOTE: These are unofficial modifications I made up to get this wonderful script to work with my file system.
*/
$resolutions = array(1382, 992, 768, 480); // the resolution break-points to use (screen widths, in pixels)
$cache_path = "ai-cache"; // where to store the generated re-sized images. Specify from your document root!
$jpg_quality = 100; // the quality of any generated JPGs on a scale of 0 to 100
$sharpen = TRUE; // Shrinking images can blur details, perform a sharpen on re-scaled images?
$watch_cache = TRUE; // check that the adapted image isn't stale (ensures updated source images are re-cached)
$browser_cache = 60 * 60 * 24 * 7; // How long the BROWSER cache should last (seconds, minutes, hours, days. 7days by default)
/* END CONFIG ----------------------------------------------------------------------------------------------------------
------------------------ Don't edit anything after this line unless you know what you're doing -------------------------
--------------------------------------------------------------------------------------------------------------------- */
/* get all of the required data from the HTTP request */
$document_root = $_SERVER['DOCUMENT_ROOT'];
$requested_uri = parse_url(urldecode($_SERVER['REQUEST_URI']), PHP_URL_PATH);
$requested_uri_more_stuff = parse_url(urldecode($_SERVER['REQUEST_URI']));
$requested_file = basename($requested_uri);
//$source_file = $document_root . $requested_uri;
file_put_contents('array.txt', var_export($requested_uri_more_stuff, TRUE));
if(pathinfo($requested_file, PATHINFO_EXTENSION) == 'php')
$source_file = 'http://' . $_SERVER['HTTP_HOST'] . $requested_uri. ((!empty($requested_uri_more_stuff['query']) ? ('?' . $requested_uri_more_stuff['query']) : '') . (((parse_url($_SERVER['REQUEST_URI'], PHP_URL_QUERY) == NULL) ? '?' : '&') . 'noadaptive=true'));
else
$source_file = $document_root . $requested_uri;
$resolution = FALSE;
//sendErrorImage(pathinfo($requested_file, PATHINFO_EXTENSION));
//sendErrorImage($source_file);
/* Mobile detection
NOTE: only used in the event a cookie isn't available. */
function is_mobile()
{
$userAgent = strtolower($_SERVER['HTTP_USER_AGENT']);
return strpos($userAgent, 'mobile');
}
/* Does the UA string indicate this is a mobile? */
if (!is_mobile()) {
$is_mobile = FALSE;
} else {
$is_mobile = TRUE;
}
// does the $cache_path directory exist already?
if (!is_dir("$document_root/$cache_path")) { // no
if (!mkdir("$document_root/$cache_path", 0755, true)) { // so make it
if (!is_dir("$document_root/$cache_path")) { // check again to protect against race conditions
// uh-oh, failed to make that directory
sendErrorImage("Failed to create cache directory at: $document_root/$cache_path");
}
}
}
/* helper function: Send headers and returns an image. */
function sendImage($filename, $browser_cache)
{
$extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
if (in_array($extension, array('png', 'gif', 'jpeg'))) {
header("Content-Type: image/" . $extension);
} else {
header("Content-Type: image/jpeg");
}
header("Cache-Control: private, max-age=" . $browser_cache);
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $browser_cache) . ' GMT');
header('Content-Length: ' . filesize($filename));
readfile($filename);
exit();
}
/* helper function: Create and send an image with an error message. */
function sendErrorImage($message)
{
/* get all of the required data from the HTTP request */
$document_root = $_SERVER['DOCUMENT_ROOT'];
$requested_uri = parse_url(urldecode($_SERVER['REQUEST_URI']), PHP_URL_PATH);
$requested_file = basename($requested_uri);
$source_file = $document_root . $requested_uri;
if (!is_mobile()) {
$is_mobile = "FALSE";
} else {
$is_mobile = "TRUE";
}
$im = ImageCreateTrueColor(800, 300);
$text_color = ImageColorAllocate($im, 233, 14, 91);
$message_color = ImageColorAllocate($im, 91, 112, 233);
ImageString($im, 5, 5, 5, "Adaptive Images encountered a problem:", $text_color);
ImageString($im, 3, 5, 25, $message, $message_color);
ImageString($im, 5, 5, 85, "Potentially useful information:", $text_color);
ImageString($im, 3, 5, 105, "DOCUMENT ROOT IS: $document_root", $text_color);
ImageString($im, 3, 5, 125, "REQUESTED URI WAS: $requested_uri", $text_color);
ImageString($im, 3, 5, 145, "REQUESTED FILE WAS: $requested_file", $text_color);
ImageString($im, 3, 5, 165, "SOURCE FILE IS: $source_file", $text_color);
ImageString($im, 3, 5, 185, "DEVICE IS MOBILE? $is_mobile", $text_color);
//ImageString($im, 3, 5, 205, "Resolution: $resolution", $text_color); // Doesn't work
header("Cache-Control: no-store");
header('Expires: ' . gmdate('D, d M Y H:i:s', time() - 1000) . ' GMT');
header('Content-Type: image/jpeg');
ImageJpeg($im);
ImageDestroy($im);
exit();
}
/* sharpen images function */
function findSharp($intOrig, $intFinal)
{
$intFinal = $intFinal * (750.0 / $intOrig);
$intA = 52;
$intB = -0.27810650887573124;
$intC = .00047337278106508946;
$intRes = $intA + $intB * $intFinal + $intC * $intFinal * $intFinal;
return max(round($intRes), 0);
}
/* refreshes the cached image if it's outdated */
function refreshCache($source_file, $cache_file, $resolution)
{
if (file_exists($cache_file)) {
// not modified
if (filemtime($cache_file) >= filemtime($source_file)) {
return $cache_file;
}
// modified, clear it
unlink($cache_file);
}
return generateImage($source_file, $cache_file, $resolution);
}
/* generates the given cache file for the given source file with the given resolution */
function generateImage($source_file, $cache_file, $resolution)
{
global $sharpen, $jpg_quality;
$extension = strtolower(pathinfo($source_file, PATHINFO_EXTENSION));
// Check the image dimensions
$dimensions = getimagesize($source_file);
$width = $dimensions[0];
$height = $dimensions[1];
//sendErrorImage($width . ' ' . $resolution);
// Do we need to downscale the image?
if ($width <= $resolution) { // no, because the width of the source image is already less than the client width
return $source_file;
}
// We need to resize the source image to the width of the resolution breakpoint we're working with
$ratio = $height / $width;
$new_width = $resolution;
$new_height = ceil($new_width * $ratio);
$dst = ImageCreateTrueColor($new_width, $new_height); // re-sized image
switch ($extension) {
case 'png':
$src = #imagecreatefrompng($source_file); // original image
break;
case 'gif':
$src = #imagecreatefromgif($source_file); // original image
break;
default:
//imagecreatefromstring(file_get_contents($source_file));
$src = #imagecreatefromjpeg($source_file); // original image
ImageInterlace($dst, true); // Enable interlancing (progressive JPG, smaller size file)
break;
}
if ($extension == 'png') {
imagealphablending($dst, false);
imagesavealpha($dst, true);
$transparent = imagecolorallocatealpha($dst, 255, 255, 255, 127);
imagefilledrectangle($dst, 0, 0, $new_width, $new_height, $transparent);
}
ImageCopyResampled($dst, $src, 0, 0, 0, 0, $new_width, $new_height, $width, $height); // do the resize in memory
ImageDestroy($src);
// sharpen the image?
// NOTE: requires PHP compiled with the bundled version of GD (see http://php.net/manual/en/function.imageconvolution.php)
if ($sharpen == TRUE && function_exists('imageconvolution')) {
$intSharpness = findSharp($width, $new_width);
$arrMatrix = array(
array(-1, -2, -1),
array(-2, $intSharpness + 12, -2),
array(-1, -2, -1)
);
imageconvolution($dst, $arrMatrix, $intSharpness, 0);
}
$cache_dir = dirname($cache_file);
//sendErrorImage($cache_dir);
// does the directory exist already?
if (!is_dir($cache_dir)) {
if (!mkdir($cache_dir, 0755, true)) {
// check again if it really doesn't exist to protect against race conditions
if (!is_dir($cache_dir)) {
// uh-oh, failed to make that directory
ImageDestroy($dst);
sendErrorImage("Failed to create cache directory: $cache_dir");
}
}
}
if (!is_writable($cache_dir)) {
sendErrorImage("The cache directory is not writable: $cache_dir");
}
// save the new file in the appropriate path, and send a version to the browser
switch ($extension) {
case 'png':
$gotSaved = ImagePng($dst, $cache_file);
break;
case 'gif':
$gotSaved = ImageGif($dst, $cache_file);
break;
default:
$gotSaved = ImageJpeg($dst, $cache_file, $jpg_quality);
break;
}
ImageDestroy($dst);
if (!$gotSaved && !file_exists($cache_file)) {
sendErrorImage("Failed to create image: $cache_file");
}
return $cache_file;
}
//sendErrorImage($source_file);
// check if the file exists at all
if(pathinfo($requested_file, PATHINFO_EXTENSION) != 'php')
{
if (!file_exists($source_file)) {
//sendErrorImage('404 ' . $source_file);
header("Status: 404 Not Found");
exit();
}
}
else if(pathinfo($requested_file, PATHINFO_EXTENSION) == php)
{
}
/* check that PHP has the GD library available to use for image re-sizing */
if (!extension_loaded('gd')) { // it's not loaded
if (!function_exists('dl') || !dl('gd.so')) { // and we can't load it either
// no GD available, so deliver the image straight up
trigger_error('You must enable the GD extension to make use of Adaptive Images', E_USER_WARNING);
sendImage($source_file, $browser_cache);
}
}
/* Check to see if a valid cookie exists */
if (isset($_COOKIE['resolution'])) {
$cookie_value = $_COOKIE['resolution'];
// does the cookie look valid? [whole number, comma, potential floating number]
if (!preg_match("/^[0-9]+[,]*[0-9\.]+$/", "$cookie_value")) { // no it doesn't look valid
setcookie("resolution", "$cookie_value", time() - 100); // delete the mangled cookie
} else { // the cookie is valid, do stuff with it
$cookie_data = explode(",", $_COOKIE['resolution']);
$client_width = (int)$cookie_data[0]; // the base resolution (CSS pixels)
$total_width = $client_width;
$pixel_density = 1; // set a default, used for non-retina style JS snippet
if (#$cookie_data[1]) { // the device's pixel density factor (physical pixels per CSS pixel)
$pixel_density = $cookie_data[1];
}
rsort($resolutions); // make sure the supplied break-points are in reverse size order
$resolution = $resolutions[0]; // by default use the largest supported break-point
// if pixel density is not 1, then we need to be smart about adapting and fitting into the defined breakpoints
if ($pixel_density != 1) {
$total_width = $client_width * $pixel_density; // required physical pixel width of the image
// the required image width is bigger than any existing value in $resolutions
if ($total_width > $resolutions[0]) {
// firstly, fit the CSS size into a break point ignoring the multiplier
foreach ($resolutions as $break_point) { // filter down
if ($total_width <= $break_point) {
$resolution = $break_point;
}
}
// now apply the multiplier
$resolution = $resolution * $pixel_density;
} // the required image fits into the existing breakpoints in $resolutions
else {
foreach ($resolutions as $break_point) { // filter down
if ($total_width <= $break_point) {
$resolution = $break_point;
}
}
}
} else { // pixel density is 1, just fit it into one of the breakpoints
foreach ($resolutions as $break_point) { // filter down
if ($total_width <= $break_point) {
$resolution = $break_point;
}
}
//sendErrorImage($client_width . " " . $resolution . " " . $pixel_density . " | " . $total_width);
}
}
}
/* No resolution was found (no cookie or invalid cookie) */
if (!$resolution) {
// We send the lowest resolution for mobile-first approach, and highest otherwise
$resolution = $is_mobile ? min($resolutions) : max($resolutions);
}
/* if the requested URL starts with a slash, remove the slash */
if (substr($requested_uri, 0, 1) == "/") {
$requested_uri = substr($requested_uri, 1);
}
/* whew might the cache file be? */
if(pathinfo($requested_file, PATHINFO_EXTENSION) == 'php')
{
$getstring = '';
foreach($_GET as $key => $item)
{
$getstring .= $key . '~' . $item . '^';
}
$fileinfophp = pathinfo($_SERVER['REQUEST_URI']);
//sendErrorImage($getstring);
$cache_file = $document_root . "/$cache_path/$resolution/" . 'php/' . $fileinfophp['filename'] . '%' . $getstring;
}
else
$cache_file = $document_root . "/$cache_path/$resolution/" . $requested_uri;
/* Use the resolution value as a path variable and check to see if an image of the same name exists at that path */
if (file_exists($cache_file)) { // it exists cached at that size
if ($watch_cache) { // if cache watching is enabled, compare cache and source modified dates to ensure the cache isn't stale
$cache_file = refreshCache($source_file, $cache_file, $resolution);
}
sendImage($cache_file, $browser_cache);
}
//sendErrorImage('gen');
/* It exists as a source file, and it doesn't exist cached - lets make one: */
$file = generateImage($source_file, $cache_file, $resolution);
//file_put_contents('image.jpg', $file);
sendImage($file, $browser_cache);

Thumbnail generation time

Idea
I have a function that checks to see if a thumbnail exists in cache folder for a particular image. If it does, it returns the path to that thumbnail. If it does not, it goes ahead and generates the thumbnail for the image, saves it in the cache folder and returns the path to it instead.
Problem
Let's say I have 10 images but only 7 of them have their thumbnails in the cache folder. Therefore, the function goes to generation of thumbnails for the rest 3 images. But while it does that, all I see is a blank, white loading page. The idea is to display the thumbnails that are already generated and then generate the ones that do not exist.
Code
$images = array(
"http://i49.tinypic.com/4t9a9w.jpg",
"http://i.imgur.com/p2S1n.jpg",
"http://i49.tinypic.com/l9tow.jpg",
"http://i45.tinypic.com/10di4q1.jpg",
"http://i.imgur.com/PnefW.jpg",
"http://i.imgur.com/EqakI.jpg",
"http://i46.tinypic.com/102tl09.jpg",
"http://i47.tinypic.com/2rnx6ic.jpg",
"http://i50.tinypic.com/2ykc2gn.jpg",
"http://i50.tinypic.com/2eewr3p.jpg"
);
function get_name($source) {
$name = explode("/", $source);
$name = end($name);
return $name;
}
function get_thumbnail($image) {
$image_name = get_name($image);
if(file_exists("cache/{$image_name}")) {
return "cache/{$image_name}";
} else {
list($width, $height) = getimagesize($image);
$thumb = imagecreatefromjpeg($image);
if($width > $height) {
$y = 0;
$x = ($width - $height) / 2;
$smallest_side = $height;
} else {
$x = 0;
$y = ($height - $width) / 2;
$smallest_side = $width;
}
$thumb_size = 200;
$thumb_image = imagecreatetruecolor($thumb_size, $thumb_size);
imagecopyresampled($thumb_image, $thumb, 0, 0, $x, $y, $thumb_size, $thumb_size, $smallest_side, $smallest_side);
imagejpeg($thumb_image, "cache/{$image_name}");
return "cache/{$image_name}";
}
}
foreach($images as $image) {
echo "<img src='" . get_thumbnail($image) . "' />";
}
To elaborate on #DCoder's comment, what you could do is;
If the thumb exists in the cache, return the URL just as you do now. This will make sure that thumbs that are in the cache will load quickly.
If the thumb does not exist in the cache, return an URL similar to /cache/generatethumb.php?http://i49.tinypic.com/4t9a9w.jpg where the script generatethumb.php generates the thumbnail, saves it in the cache and returns the thumbnail. Next time, it will be in the cache and the URL won't go through the PHP script.

Categories