Memory exhaustion with small files - php

Never come across this before...
I'm uploading 2 files, one that is 371kb and another than is 291kb.
public function useImage($image, $photoid){
$source = $image['tmp_name'];
$target = "projectimages/";
//prepare the largest image
$targetname = $photoid."large.jpg";
$file = $target . $targetname;
copy($source, $file);
list($width, $height) = getimagesize($file);
$modwidth = 800;
$diff = $width / $modwidth;
$modheight = $height / $diff;
$tn = imagecreatetruecolor($modwidth, $modheight);
$image = imagecreatefromjpeg($file);
imagecopyresampled($tn, $image, 0, 0, 0, 0, $modwidth, $modheight, $width, $height);
imagejpeg($tn, $file, 100);
//prepare the smaller image
$targetname = $photoid."small.jpg";
$file = $target.$targetname;
move_uploaded_file($source, $file);
list($width, $height) = getimagesize($file);
$modwidth = 400;
$diff = $width / $modwidth;
$modheight = $height / $diff;
$tn = imagecreatetruecolor($modwidth, $modheight);
$image = imagecreatefromjpeg($file);
imagecopyresampled($tn, $image, 0, 0, 0, 0, $modwidth, $modheight, $width, $height);
imagejpeg($tn, $file, 100);
}
I use this function to resize them to make them smaller, the function is ran for each image.
When reaching the smaller image section of the function, the photo isn't being resized and instead an error is popping up saying:
Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 10368 bytes) in /Applications/MAMP/htdocs/bs/classes/image.php on line 202
Which is on this line:
$image = imagecreatefromjpeg($file);
How are these small images exhausting all the memory?
Thanks.

don't forget that those tiny .jpg images when uncompressed by the line you highlighted will become much larger in-memory bitmaps
eg: width in px * height in px * colour depth bits...

Related

PHP image resize with GD use to many CPU time

I have a script on PHP GD with simple functions how to resize on real-time images on my site, but this process "eat" all my CPU time ... I use VPS with 4 cores and it's not enough.
From image tag i call PHP file (<img src="image.php?file=XXX&width=XXX&height=XXX" alt="" />) with image name, new width and new height ... after that in PHP I make this operations:
ob_start();
ini_set('max_execution_time', 0);
set_time_limit(0);
error_reporting(E_ALL^E_NOTICE^E_DEPRECATED);
date_default_timezone_set('Europe/Sofia');
header('Content-type: image/jpeg');
$url = $_GET['file'];
if(!empty($url) && file_exists($url) && is_file($url) && is_readable($url)){
$width = $_GET['width'];
$height = $_GET['height'];
list($width_orig, $height_orig) = getimagesize($url);
if(empty($width)) $width = $width_orig/($height_orig/$height);
if(empty($height)) $height = $height_orig/($width_orig/$width);
$ratio_orig = $width_orig/$height_orig;
if($width/$height > $ratio_orig) {
$width = $height*$ratio_orig;
} else {
$height = $width/$ratio_orig;
}
$image_p = imagecreatetruecolor($width, $height);
$image = imagecreatefromjpeg($url);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
imagejpeg($image_p, null, 100);
imagedestroy($image_p);
imagedestroy($image);
}
ob_end_flush();
I don't understand why "eat" to match CPU time ... my original image size it's 1920x2880 px.
How to reduce my CPU usage? Any ideas?

Resize image while uploading to amazon s3

I need to resize image to 150 x 150 px and then upload it to Amazon S3
Following is the code:
$image = $_FILES["userImage"]["name"];
$fileTempName = $_FILES['userImage']['tmp_name'];
$new_width = 150;
$new_height = 150;
$image_p = imagecreatetruecolor($new_width, $new_height);
$image = imagecreatefromstring(file_get_contents($fileTempName));
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, imagesx($image), imagesy($image));
$newFielName = tempnam(sys_get_temp_dir(), "tempfilename");
imagepng($image_p, $newFielName, 9);
$s3 = new S3(awsAccessKey, awsSecretKey);
//move the file
if ($s3->putObjectFile($fileTempName, "urimages", $newFielName, S3::ACL_PUBLIC_READ)) {
$image_link = 'https://s3-us-west-2.amazonaws.com/urimages/' . $newFielName . '';
$this->Product->saveField('image', $image_link);
}
Following is the link which i receive upon uploading : https://s3-us-west-2.amazonaws.com/urimages/C:/Users/LS/AppData/Local/Temp/9102.tmp
Could be you please help me debug the code
i think issue in path. Please create folder on s3 and make a valid
path according to that folder
https://s3-us-west-2.amazonaws.com/urimages/C:/Users/LS/AppData/Local/Temp/9102.tmp
Example :- Resampling an image proportionally
<?php
// The file
$filename = 'test.jpg';
// Set a maximum height and width
$width = 200;
$height = 200;
// Content type
header('Content-Type: image/jpeg');
// Get new dimensions
list($width_orig, $height_orig) = getimagesize($filename);
$ratio_orig = $width_orig/$height_orig;
if ($width/$height > $ratio_orig) {
$width = $height*$ratio_orig;
} else {
$height = $width/$ratio_orig;
}
// Resample
$image_p = imagecreatetruecolor($width, $height);
$image = imagecreatefromjpeg($filename);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
// Output
imagejpeg($image_p, null, 100);
?>

PHP GD cropping PNG doesn't work

I'm creating a function to crop images using PHP GD.
The function works perfectly for JPEG images but when I try to use the same function for PNG I just get a blank page and the following errors when I inspect the page in chrome:
I realize this is a javascript error, but this is probably something chrome does? This is what happens when i visit the IMAGE URL. If i replicate this with the JPEG code it works perfectly.
Edit: in Firefox it says "The image [URL] cannot be displayed because it contains errors. The below js error is just a chrome error and isn't very relevant.
Uncaught TypeError: Cannot read property 'getAttribute' of null
data_loader.js:2 Uncaught TypeError: Cannot read property
'hasAttribute' of null global-shortcut.js:9
The working JPEG code is as follows:
$fileName = $_POST['file'];
$jpeg_quality = 100;
$ratio = $_POST['r'];
$src = '/var/www/admin/public_html/images/'.$fileName;
$image = imagecreatefromjpeg($src);
$target = '/var/www/admin/public_html/images/crop/'.$fileName;
$thumb_width = $_POST['w'] / $ratio;
$thumb_height = $_POST['h'] / $ratio;
$width = imagesx($image);
$height = imagesy($image);
$thumb = imagecreatetruecolor( $thumb_width, $thumb_height );
// Resize and crop
imagecopyresampled($thumb,
$image,
0,
0,
$_POST['x'] / $ratio, $_POST['y'] / $ratio,
$width, $height,
$width, $height);
imagejpeg($thumb, $target, $jpeg_quality);
The Broken PNG code is as follows:
$fileName = $_POST['file'];
$jpeg_quality = 100;
$ratio = $_POST['r'];
$src = '/var/www/admin/public_html/images/'.$fileName;
$image = imagecreatefrompng($src);
$target = '/var/www/admin/public_html/images/crop/'.$fileName;
$thumb_width = $_POST['w'] / $ratio;
$thumb_height = $_POST['h'] / $ratio;
$width = imagesx($image);
$height = imagesy($image);
$thumb = imagecreatetruecolor( $thumb_width, $thumb_height );
// Resize and crop
imagecopyresampled($thumb,
$image,
0,
0,
$_POST['x'] / $ratio, $_POST['y'] / $ratio,
$width, $height,
$width, $height);
imagepng($thumb, $target, $jpeg_quality);
I answered my own question.
imagepng() function takes quality argument from 0 to 9
imagejpeg() function takes quality argument from 0 to 100

Copying image file

I'm uploading an image file, copying it, resizing it, then moving the original file and resizing it!
I've written the following function, I know there's a lot of room to tidy the code up etc.
public function useImage($image, $photoid){
$source = $image['tmp_name'];
$target = "projectimages/";
//prepare the largest image
copy($source, $target);
$targetname = $photoid."large.jpg";
$file = $target.$targetname;
list($width, $height) = getimagesize($file);
$modwidth = 800;
$diff = $width / $modwidth;
$modheight = $height / $diff;
$tn = imagecreatetruecolor($modwidth, $modheight);
$image = imagecreatefromjpeg($file);
imagecopyresampled($tn, $image, 0, 0, 0, 0, $modwidth, $modheight, $width, $height);
imagejpeg($tn, $file, 100);
//prepare the smaller image
move_uploaded_file($source, $target);
$targetname = $photoid."small.jpg";
$file = $target.$targetname;
list($width, $height) = getimagesize($file);
$modwidth = 400;
$diff = $width / $modwidth;
$modheight = $height / $diff;
$tn = imagecreatetruecolor($modwidth, $modheight);
$image = imagecreatefromjpeg($file);
imagecopyresampled($tn, $image, 0, 0, 0, 0, $modwidth, $modheight, $width, $height);
imagejpeg($tn, $file, 100);
}
I'm getting plenty of errors but the crucial one that the others are built upon is the first one when I try and copy or move the uploaded file...
Warning: copy(projectimages/) [function.copy]: failed to open stream: Is a directory in /Applications/MAMP/htdocs/bs/classes/image.php on line 171
I've used var_dump on image and it appears the image is in place.
Any ideas?
The destination of the copy() call is a directory. Try to change your code like this:
$source = $image['tmp_name'];
$target = "projectimages/";
//prepare the largest image
$targetname = $photoid."large.jpg";
$file = $target.$targetname;
copy($source, $file);
// The rest of your code goes here.

Creat temporay thumb image in PHP

Hey, i am looking for a method to creat temporay thumb file in PHP. Is there any way not to store the image on the server or delete them right after. What I am looking for is a solution like this: http://www.dig2go.com/index.php?shopbilde=772&type=1&size=120
Could some one explain to me how the php code behind this works? For the moment are am using a php code I found on the net for creation of thumb nails:
function createThumb($pathToImage, $pathToThumb, $thumbWidth, $thumbHeight, $saveNameAndPath)
{
if(!file_exists($pathToImage))
return false;
else
{
//Load image and size
$img = imagecreatefromjpeg($pathToImage);
$width = imagesx($img);
$height = imagesy($img);
//Calculate the size of thumb
$new_width = $thumbWidth;
$new_height = $thumbHeight; //floor($height * ($thumbWidth / $width));
//Make the new thumb
$tmp_img = imagecreatetruecolor($new_width, $new_height);
//Copy the old image and calculate the size
imagecopyresized($tmp_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
//Save the thumb to jpg
imagejpeg($tmp_img, $saveNameAndPath);
return true;
}
}
function createThumb($pathToImage, $pathToThumb, $thumbWidth, $thumbHeight, $saveNameAndPath)
{
if(!file_exists($pathToImage))
return false;
else
{
//Load image and size
$img = imagecreatefromjpeg($pathToImage);
$width = imagesx($img);
$height = imagesy($img);
//Calculate the size of thumb
$new_width = $thumbWidth;
$new_height = $thumbHeight; //floor($height * ($thumbWidth / $width));
//Make the new thumb
$tmp_img = imagecreatetruecolor($new_width, $new_height);
//Copy the old image and calculate the size
imagecopyresized($tmp_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
// sets the header and creates the temporary thumbnail
// ideal for ajax requests / <img> elements
header("Content-type: image/jpeg");
imagejpeg($img);
return true;
}
}
You can use ini_set("memory_limit","12M"); to set memory limit in your script. You can extend it from 12 megabytes to maximum memory you have.
Generally 64M is good.

Categories