I'm trying to load an image from an external site over which I have no control.
Most of the time it works fine (hundreds of images tested so far).
It's now giving me this error for one particular image:
imagecreatefromstring(): gd-jpeg, libjpeg: recoverable error: Corrupt JPEG data: premature end of data segment
from this line:
$im = #imagecreatefromstring( $imageString );
The advice I'd read so far suggests adding:
ini_set("gd.jpeg_ignore_warning", true);
but that's had no effect and I'm still getting the error. I'm doing the ini_set just before the call. Is that relevant?
I'm really stuck on how to ignore this error and carry on.
The problem was due to my error handling. I'd set up an error handler so my call to
$im = #imagecreatefromstring( $imageString );
wasn't suppressing errors.
By modifying my error handler with:
if (error_reporting() === 0)
{
// This copes with # being used to suppress errors
// continue script execution, skipping standard PHP error handler
return false;
}
I can now correctly suppress selected errors.
I found the info here: http://anvilstudios.co.za/blog/php/how-to-ignore-errors-in-a-custom-php-error-handler/
this can be solve with:
ini_set ('gd.jpeg_ignore_warning', 1);
If you are just showing the image, then I suggest simply reading the contents and display the image as follows:
$img = "http://path/to/image";
$contents = file_get_contents($img);
header("Content-Type: image/jpeg");
print($contents);
If you are wanting to copy the image to your server, you have a few options, two of which are the copy() function or the method used above and then fwrite():
Option 1 - The copy() function, available from PHP 4
$file1 = "http://path/to/file";
$dest = "/path/to/yourserver/lcoation";
$docopy = copy($file1, $dest);
Option 2 - Using file_get_contents() and fwrite()
$img = "http://path/to/image";
$contents = file_get_contents($img);
$newfile = "path/to/file.ext";
$fhandler = fopen($newfile, 'w+'); //create if not exists, truncate to 0 length
$write = fwrite($fhandler, $contents); //write image data
$close = fclose($fhandler); //close stream
chmod(0755, $newfile); //make publically readable if you want
I hope you find some use in the above
Considering that you want to make a thumbnail and save it, you could implement a handy resize function like the following:
<?php
function resize($sourcefile, $endfile, $thumbwidth, $thumbheight, $quality){
$ext1 = explode(".",trim($sourcefile));
$ext = strtolower(trim(array_slice($sext1,-1)));
switch($ext):
case 'jpg' or 'jpeg':
$img = imagecreatefromjpeg($sourcefile);
break;
case 'gif':
$img = imagecreatefromgif($sourcefile);
break;
case 'png':
$img = imagecreatefrompng($sourcefile);
break;
endswitch;
$width = imagesx( $img );
$height = imagesy( $img );
if ($width > $height) {
$newwidth = $thumbwidth;
$divisor = $width / $thumbwidth;
$newheight = floor( $height / $divisor);
}
else {
$newheight = $thumbheight;
$divisor = $height / $thumbheight;
$newwidth = floor( $width / $divisor );
}
// Create a new temporary image.
$tmpimg = imagecreatetruecolor( $newwidth, $newheight );
// Copy and resize old image into new image.
imagecopyresampled( $tmpimg, $img, 0, 0, 0, 0, $newwidth, $newheight, $width, $height );
// Save thumbnail into a file.
switch($ext):
case 'jpg' or 'jpeg':
$makeimg = imagejpeg($tmpimg, $endfile, $quality);
break;
case 'gif':
$makeimg = imagegif($tmpimg, $endfile, $quality);
break;
case 'png':
$makeimg = imagepng($tmpimg, $endfile, $quality);
break;
endswitch;
// release the memory
imagedestroy($tmpimg);
imagedestroy($img);
if($makeimg){
chmod($endfile,0755);
return true;
}else{
return false;
}
}
?>
Then, after you've copied the file to your server using one of my methods in my answer above this, you could simply apply the function as follows:
$doresize = resize($sourcefile, $endfile, $thumbwidth, $thumbheight, $quality);
echo ($doresize == true ? "IT WORKED" : "IT FAILED");
This function serves me pretty well. I apply it to 1000's of images a day and it works like a charm.
Related
I want to get the image and resize it then save, but when i use the url to get the image and get the info of the image, error pop up.
$content = file_get_contents('http://localhost//uploadImage/tipsImages/9a861a512bed4530456620c159e80220e9eaba7f.png');
if (($img_info = getimagesize($content)) === FALSE)
die("Image not found or not an image");
$width = $img_info[0];
$height = $img_info[1];
if($width > 740){
switch ($img_info[2]) {
case IMAGETYPE_GIF : $src = imagecreatefromgif($img); break;
case IMAGETYPE_JPEG : $src = imagecreatefromjpeg($img); break;
case IMAGETYPE_PNG : $src = imagecreatefrompng($img); break;
default : die("Unknown filetype");
}
$img_info = pathinfo($link);
$new_name = 'small_'.$img_info['filename'];
$new_width = 740;
$ratio = $new_width/$width;
$new_height = $height*$ratio;
$tmp = imagecreatetruecolor(740, $new_height);
imagecopyresampled($tmp, $src, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
$dst = realpath(dirname(__FILE__).'/../../');
imagejpeg($tmp, $dst.$new_name.".jpg");
}
The error come out is
failed to open stream: No such file or directory
In the line
if (($img_info = getimagesize($content)) === FALSE)
The link is definitly right as it shows the image when i copy it to browser
I found that what cause the error is that getimagesize is suppose to use the link instead of content
I want to use watermark image with php. This is my reference page
function imagecreatefromfile($image_path)
{
list($width, $height, $image_type) = getimagesize($image_path);
switch ($image_type)
{
case IMAGETYPE_GIF: return imagecreatefromgif($image_path); break;
case IMAGETYPE_JPEG: return imagecreatefromjpeg($image_path); break;
case IMAGETYPE_PNG: return imagecreatefrompng($image_path); break;
default: return ''; break;
}
}
$image = imagecreatefromfile($_GET['image']);
if (!$image) die('Unable to open image');
$watermark = imagecreatefromfile('uploads/files/water.png');
if (!$image) die('Unable to open watermark');
$watermark_pos_x = imagesx($image) - imagesx($watermark) - 8;
$watermark_pos_y = imagesy($image) - imagesy($watermark) - 10;
imagecopy($image, $watermark, $watermark_pos_x, $watermark_pos_y, 0, 0,
imagesx($watermark), imagesy($watermark));
header('Content-Type: image/jpg');
imagejpeg($image, '', 100);
imagedestroy($image);
imagedestroy($watermark);`
but my page seems empty ,
This is my test page
http://www.alanyaticaretrehberi.com/watermark.php?image=uploads/firmaresim/750/address-cikcilli-3jpg.jpeg
this worked in other servers but not worked in my server.
This is my phpinfo page..
http://www.alanyaticaretrehberi.com/php.php
I guess some setting missed in my php settings but i dont know what it is. May be it is about gd library or something else, can you give some advices for this issue.
How do you download, resize and store an image from a remote server using php?
This is the code I am using
$temp_image = file_get_contents($url);
$image = imagecreatefromstring($temp_image);
$thumb = imageToCanvas($image,100,75,true);
imagejpeg($thumb,$base_image_path . $thumb_path,90)
function imageToCanvas($_image, $_canvasWidth, $_canvasHeight, $forceScale=false,$x=false,$y=false)
{
$newImage = imagecreatetruecolor($_canvasWidth, $_canvasHeight);
$imageinfo = getimagesize($_image);
$sourceWidth = $imageinfo[0];
$sourceHeight = $imageinfo[1];
$sourceImage = openImage($_image);
imagecopyresampled($newImage, $sourceImage, 0, 0, 0, 0, $_canvasWidth, $_canvasHeight, $sourceWidth, $sourceHeight);
return $newImage;
}
function openImage($file)
{
// *** Get extension
$extension = strtolower(strrchr($file, '.'));
switch($extension) {
case '.jpg': case '.jpeg':
$img = #imagecreatefromjpeg($file);
break;
case '.gif':
$img = #imagecreatefromgif($file);
break;
case '.png':
$img = #imagecreatefrompng($file);
break;
default:
$img = false;
break;
}
return $img;
}
Doesn't work and I don't know why.
$sourceWidth & $sourceHeight doesn't have a value so I presume $image is in the wrong format
Thanks!
There is no function in php called openImage so that would be a problem if you don't define it yourself.
If you do have it defined, what does it look like and are you receiving any errors?
Edit: Based on your comments the problem would seem to be that you treat the input parameter of your openImage function as a file path. However, when you call it you are feeding it an image resource, the result of imagecreatefromstring.
If you are on a linux server and ghostscript is installed - here is an easier way
shell_exec("convert in.jpg -resize 100x75 out.jpg")
Hi I based this function from the one I've found on web and tried modifying it up for my PHP page for uploading of their icons but I want to limit the user from uploading an image which should only size 100x100px. Well I just call it using this:
uploadImage($id,$_FILES['upload']['name'],$_FILES['upload']['tmp_name']);
This is the function I made:
function uploadImage($new_name,$imagename,$tmp_name){
if($tmp_name!=null||$tmp_name!=""){
list($width, $height, $type, $attr) = getimagesize($tmp_name);
if($width==100&&$height==100){
$image1 = $imagename;
$extension = substr($image1, strrpos($image1, '.') + 1);
$image = "$new_name.$extension";
$folder = "Images/";
if($image) {
$filename = $folder.$image;
$copied = copy($tmp_name, $filename);
}
else echo "image not uploaded.";
}
else
echo "upload only 100x100px image!";
}
}
Now the problem is that even if I uploaded an image which exceeds the 100 x 100px dimensions it still proceeds without returning any errors and now I'm lost with it.
You probably need to re-factor your code a bit; have a function that checks whether the uploaded image is valid, and then one actually does the upload. Alternatively, you could create a class.
<?php
class ImageUpload
{
public $tmpImage;
public $maxWidth = 100;
public $maxHeight = 100;
public $errors = [];
public function __construct($image)
{
$this->tmpImage = $image;
}
public function upload()
{
// Check image is valid; if not throw exception
// Check image is within desired dimensions
list($width, $height) = getimagesize($this->tmpImage);
if ($width > $this->maxWidth || $height > $this->maxHeight) {
throw new Exception(sprintf('Your image exceeded the maximum dimensions (%d×%d)', $this->maxWidth, $this->maxHeight));
}
// Create filename
// Do the upload logic, i.e. move_uploaded_file()
}
}
You can then use this class as follows:
<?php
$imageUpload = new ImageUpload($_FILES['upload']['tmp_name']);
try {
$imageUpload->upload();
} catch (Exception $e) {
echo 'An error occurred: ' . $e->getMessage();
}
This was written off the cuff, so they may be errors. But hopefully it demonstrates a better way to handle file uploads, and errors that may occur during upload.
well, you can also resize the image after upload.
function createFixSizeImage( $pathToImages, $pathToFixSizeImages, $Width )
{
// open the directory
$dir = opendir( $pathToImages );
// loop through it, looking for any/all JPG files:
while (false !== ($fname = readdir( $dir ))) {
$image_info = getimagesize( "path/to/images/".$fname );
$image_width = $image_info[0];
$image_height = $image_info[1];
$image_type = $image_info[2];
switch ( $image_type )
{
case IMAGETYPE_JPEG:
// parse path for the extension
$info = pathinfo($pathToImages . $fname);
// continue only if this is a JPEG image
if ( strtolower($info['extension']) == 'jpeg' )
{
// load image and get image size
$img = imagecreatefromjpeg( "{$pathToImages}{$fname}" );
$width = imagesx( $img );
$height = imagesy( $img );
// give the size,u want
$new_width = 100;
$new_height = 100;
// create a new temporary image
$tmp_img = imagecreatetruecolor( $new_width, $new_height );
// copy and resize old image into new image
imagecopyresized( $tmp_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height );
// save Fix Size Images into a file
imagejpeg( $tmp_img, "{$pathToFixSizeImages}{$fname}" );
}
break;
case IMAGETYPE_PNG:
// parse path for the extension
$info = pathinfo($pathToImages . $fname);
// continue only if this is a JPEG image
if ( strtolower($info['extension']) == 'png' )
{
// load image and get image size
$img = imagecreatefrompng( "{$pathToImages}{$fname}" );
$width = imagesx( $img );
$height = imagesy( $img );
$new_width = 100;
$new_height = 100;
// create a new temporary image
$tmp_img = imagecreatetruecolor( $new_width, $new_height );
// copy and resize old image into new image
imagecopyresized( $tmp_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height );
// save Fix Size Images into a file
imagejpeg( $tmp_img, "{$pathToFixSizeImages}{$fname}" );
}
break;
case IMAGETYPE_BMP:
echo "bmp";
break;
default:
break;
}
}
}
// close the directory
closedir( $dir );
}
createFixSizeImage("path","path/to/images/to/be/saved",100);
Extending more or less unknown code and then debugging it, is like you wrote some code weeks ago and you don't understand it any longer.
In your case you are extending some existing code (you have not posted the original code, but your wrote that you did it that way) by adding the feature of checking the image size.
So that you do not need to edit much of the (unknown but) working code, create the new feature as a function of it's own:
/**
* #param string $file
* #param int $with
* #param int $height
* #return bool|null true/false if image has that exact size, null on error.
*/
function image_has_size($file, $width, $height)
{
$result = getimagesize($file);
if ($count($result) < 2) {
return null;
}
list($file_width, $file_height) = $result;
return ($file_width == (int) $width)
&& ($file_height == (int) $height);
}
You now have the new functionality in a single function you can much more easily integrate into the original (hopefully otherwise working) code.
Usage:
$imageHasCorrectSize = image_has_size($tmp_name, 100, 100);
So whenever you change code, do it like a surgeon, keeping the cuts as small as possible.
Im developing a website where users can upload multiple images to the server/website, in my upload script I have put an image size limit of 10MB. This is because I thought a lot of modern cameras take large images.
The upload script takes each image, one at a time, and resizes in to 3 different versions, 900x600, 600x450 and a smaller thumbnail image, and also puts a watermark image over the top of the 2 larger images.
I set my php.ini memory_limit to 96MB which I presumed would be easily enough.
After a bit of testing, I was uploading a jpg image which is 6.38MB in size and the resolution is 6143 x 3855 px in size. I received the error message "Fatal error: Allowed memory size of 100663296 bytes exhausted (tried to allocate 24572 bytes)"
Do you think it is reasonable to need this much memory to upload and process an image of this size? or do you think it is more likely a problem with the coding in my script?
96 MB memory limit seems a lot to me. What are other peoples experience dealing with large image uploads? Should I set the memory limit to 128MB or higher? or should I look at rewriting my upload script?
My Code is added below :
//If a new image has been added, resize and upload to filesystem
if ($_FILES['new_image']['name'] !=''){
$allowed_types=array(
'image/gif' => '.gif',
'image/jpeg' => '.jpg',
'image/png' => '.png',
'image/x-png' => '.png',
'image/pjpeg' => '.jpg'
);
$img = $_FILES['new_image'];
// Check the file to be uploaded is the correct file type and is under 9MB
if ((array_key_exists($img['type'], $allowed_types)) && ($img['size'] < 9000000)) {
// File to be uploaded is Valid
// File to be uploaded is Valid
$imagename = stripslashes($_FILES['new_image']['name']);
// make the random file name
$randName = md5(rand() * time());
$ext = pathinfo($imagename, PATHINFO_EXTENSION);
$imagename = $randName . "." . $ext;
$source = $_FILES['new_image']['tmp_name'];
// Check if Directory Exists, if not create it
if(!file_exists("images/breeds/".$trimmed['profile_id']))
{
mkdir("images/breeds/".$trimmed['profile_id']) or die("Could not create images folder for article ".$trimmed['profile_id']);
}
// Check if thumbnail Directory Exists
if(!file_exists("images/breeds/".$trimmed['profile_id']."/thumbs"))
{
mkdir("images/breeds/".$trimmed['profile_id']."/thumbs") or die("Could not create thumbnail folder for article ".$trimmed['profile_id']);
}
// Check if thumbnail Directory Exists
if(!file_exists("images/breeds/".$trimmed['profile_id']."/large"))
{
mkdir("images/breeds/".$trimmed['profile_id']."/large") or die("Could not create thumbnail folder for article ".$trimmed['profile_id']);
}
$LargeImage = "images/breeds/".$trimmed['profile_id']."/large/".$imagename;
$NormalImage = "images/breeds/".$trimmed['profile_id']."/".$imagename;
$SmallImage = "images/breeds/".$trimmed['profile_id']."/thumbs/".$imagename;
//uploaded temp file
$file = $_FILES['new_image']['tmp_name'];
//Get Image size info
list($width, $height, $image_type) = getimagesize($file);
//SourceImage
switch ($image_type)
{
case 1: $image = imagecreatefromgif($file); break;
case 2: $image = imagecreatefromjpeg($file); break;
case 3: $image = imagecreatefrompng($file); break;
default: trigger_error('Unsupported filetype!', E_USER_WARNING); break;
}
// Constraints for Large Image
$max_width = 900;
$max_height = 600;
$ratioh = $max_height/$height;
$ratiow = $max_width/$width;
$ratio = min($ratioh, $ratiow);
if (($height < $max_height) && ($width < $max_width)) {
//keep same dimensions
$modwidth = $width;
$modheight = $height;
} else {
// New dimensions
$modwidth = intval($ratio*$width);
$modheight = intval($ratio*$height);
}
$tmpLarge = imagecreatetruecolor( $modwidth, $modheight );
imagecopyresampled($tmpLarge, $image, 0, 0, 0, 0, $modwidth, $modheight, $width, $height) ;
// Add Watermark to large image at top right
$wm = "images/p4h-wm-200.png";
$wmImage = imagecreatefrompng($wm);
$wmW = imagesx($wmImage);
$wmH = imagesy($wmImage);
$photoW = imagesx($tmpLarge);
$photoH = imagesy($tmpLarge);
$dest_x = $photoW - $wmW - 10;
$dest_y = 10;
// imagecopymerge($tn, $wmImage, $dest_x, $dest_y, 0, 0, $wmW, $wmH, 100);
imagecopy($tmpLarge, $wmImage, $dest_x, $dest_y, 0, 0, $wmW, $wmH);
switch ($image_type)
{
case 1: imagegif($tmpLarge,$LargeImage); break;
case 2: imagejpeg($tmpLarge,$LargeImage, 80); break;
case 3: imagepng($tmpLarge,$LargeImage, 0); break;
default: trigger_error('Failed resize image!', E_USER_WARNING); break;
}
// Destroy tmp images to free memory
imagedestroy($tmpLarge);
imagedestroy($wmImage);
// Constraints for Normal Image
$max_width = 550;
$max_height = 413;
$ratioh = $max_height/$height;
$ratiow = $max_width/$width;
$ratio = min($ratioh, $ratiow);
if (($height < $max_height) && ($width < $max_width)) {
//keep same dimensions
$modwidth = $width;
$modheight = $height;
} else {
// New dimensions
$modwidth = intval($ratio*$width);
$modheight = intval($ratio*$height);
}
$tmpNormal = imagecreatetruecolor( $modwidth, $modheight );
imagecopyresampled($tmpNormal, $image, 0, 0, 0, 0, $modwidth, $modheight, $width, $height) ;
// Add Watermark to large image at top right
$wm = "images/p4h-wm-150.png";
$wmImage = imagecreatefrompng($wm);
$wmW = imagesx($wmImage);
$wmH = imagesy($wmImage);
$photoW = imagesx($tmpNormal);
$photoH = imagesy($tmpNormal);
$dest_x = $photoW - $wmW - 10;
$dest_y = 10;
// imagecopymerge($tn, $wmImage, $dest_x, $dest_y, 0, 0, $wmW, $wmH, 100);
imagecopy($tmpNormal, $wmImage, $dest_x, $dest_y, 0, 0, $wmW, $wmH);
switch ($image_type)
{
case 1: imagegif($tmpNormal,$NormalImage); break;
case 2: imagejpeg($tmpNormal,$NormalImage, 90); break;
case 3: imagepng($tmpNormal,$NormalImage, 0); break;
default: trigger_error('Failed resize image!', E_USER_WARNING); break;
}
// Destroy tmp images to free memory
imagedestroy($tmpNormal);
imagedestroy($wmImage);
// Now that the full size image has been saved, resize the thumbnail one to a fixed size for homepage display
// Constraints
$thumb_width = 150;
$thumb_height = 112.5;
// Calculate stuff and resize image accordingly
$src_ratio = $width/$height;
$dst_ratio = $thumb_width/$thumb_height;
if($src_ratio < $dst_ratio) // trim top and bottom
{
$ratio = $width/$thumb_width;
$crop_height = $thumb_height*$ratio;
$src_y = round(($height-$crop_height)/2);
$crop_width = $width;
$src_x = 0;
}
else // trim left and right
{
$ratio = $height/$thumb_height;
$crop_width = $thumb_width*$ratio;
$src_x = round(($width-$crop_width)/2);
$crop_height = $height;
$src_y = 0;
}
$tmpSmall = imagecreatetruecolor( $thumb_width, $thumb_height );
imagecopyresampled($tmpSmall, $image, 0, 0, $src_x, $src_y, $thumb_width, $thumb_height, $crop_width, $crop_height);
switch ($image_type)
{
case 1: imagegif($tmpSmall,$SmallImage); break;
case 2: imagejpeg($tmpSmall,$SmallImage, 90); break;
case 3: imagepng($tmpSmall,$SmallImage, 0); break;
default: trigger_error('Failed resize image!', E_USER_WARNING); break;
}
// Destroy images to free memory
imagedestroy($image);
imagedestroy($tmpSmall);
jpg is 6.38MB , but to transform image, the internal representation used is the raw uncompressed one.
your image is 23.6 Mega Pixel
the uncompressed representation of it could be 32bit (4Bytes) per pixel, ie : 4*23.6MBytes = 94 MBytes.
So, i would say, do you need to have such big images to process ?
if yes, put memory_limit higher
if no , limit the uploadable image size to something more reasonable to process within your memory settings.
You probably need to give more hints to PHP on when the memory can be released. A simple $some_variable = null; is usually enough.
Once you're finished with an image (the main image and each of its thumbnails), set the referencing variable to null to help free up memory.
Otherwise, try printing out or logging the results of memory_get_usage() (http://www.php.net/manual/en/function.memory-get-usage.php) at the top of your script and in various places throughout your script to track down where memory is getting bogged down.
A 6143x3855 image will require AT LEAST 71,043,795 bytes of memory just for the raw pixel data (3 bytes per pixel). Then you create a series of other images to hold resized versions of the original, etc...
No wonder you're running out of memory.