Not able to get image file extension - php

I'm using Uploadify to upload an image to the server.
The image is uploaded, and placed in the temp folder of the web server.
Now I need to work with the file beore moving it to it's real location, and I have the following code:
// Get the filepath and filename from server temp dir
$sourceFile = $_FILES[ 'Filedata' ][ 'tmp_name' ]; // e.g. c:\server\path\tmp\php159.tmp
// Solution 1 for getting file extension
$fileExt1 = pathinfo($sourceFile, PATHINFO_EXTENSION); // <-- This only returns .tmp
// Solution 2 with getimagesize
list(,,$extension) = getimagesize($sourceFile);
$fileExt2 = $extension; // this only returns the number 2.
// Solution 3 with getimagesize
$img = getimagesize($sourceFile);
$fileExt3 = $img[2]; // this only returns the number 2.
I'm not using regex to read filename, because a user may name the file anything, so I have to read file data.
Any sugegstions anyone?

Well, first off $sourceFile should be $_FILES['Filedata']['name'] instead of $_FILES['Filedata']['tmp_name'] but only for your first solution.
Now regarding your solutions/problems:
pathinfo($sourceFile, PATHINFO_EXTENSION); // should work now
getimagesize() returns a constant indicating the image type in the second index
same as point 2
Keep in mind that exif_imagetype() returns exactly the same information as the second index of getimagesize(), if you have access to this function it should perform way better.
Now for the image constants, the most common three are:
IMAGETYPE_GIF = 1
IMAGETYPE_JPEG = 2
IMAGETYPE_PNG = 3
Checking is as simple as doing something like this:
switch (exif_imagetype($_FILES['Filedata']['tmp_name']))
{
case IMAGETYPE_GIF:
echo 'is a GIF';
break;
case IMAGETYPE_JPEG:
echo 'is a JPEG';
break;
case IMAGETYPE_PNG:
echo 'is a PNG';
break;
case default:
echo 'is something else;
break;
}
One more thing, it's better to use getimagesize() / exif_imagetype() than to rely on the file extension, since the extension can be easily changed.

Your solutions #2 and #3 both work already. From the getimagesize() manual page:
Returns an array with 7 elements.
...
Index 2 is one of the IMAGETYPE_XXX constants indicating the type of the image.
So for a .gif then this should be the integer 2. To get the file extension use image_type_to_extension() since you already are using the gd library. eg.
$img = getimagesize($sourceFile);
$fileExt = image_type_to_extension($img[2])

exif_imagetype() can determine a number of graphics formats, is fast and doesn't even use GD.
Edit: I see you are already using getimagesize() and have trouble translating the constants. The exif_imagetype() page linked above has a translation of all returned image types that should be valid for getimagesize() as well.

Related

Image resize with php image magician

I'm using PHP IMAGE MAGICIAN for resizing the images of my website.
When I try to resize the image with a changed extension (e.g. changing image.jpg to image.gif), the function returns an error because the image is invalid in this situation. I want to avoid this error.
I tried a lot of methods to check is the image valid but without success.
The error which appear is:
"file
/Users/.../uploads/1541963916_4dd672e5f3a3060ced41f3f7975453c9.gif is
missing or invalid"
Every image I upload to my website I am renaming to a new filename with its extension.
This is the part of code which I am using.
$workWithImage = new imageLib(UPLOADS_DIR . $original);
$workWithImage->resizeImage($width, $height, $type);
$workWithImage->saveImage(UPLOADS_DIR . $thumbnail, $imageQuality);
I searched for this problem but I could not find a solution.
Unfortunately looking at source this library seems to not handle this situation at all. You can create bug report at library home page. What you can do is compare mime type of file with it's extension and either do you own error handling or rename file name to have correct extension. Mime type detection code used by this library is
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimeType = finfo_file($finfo, $file);
finfo_close($finfo);
switch($mimeType) {
case 'image/jpeg':
case 'image/gif':
case 'image/png':
case 'image/bmp':
case 'image/x-windows-bmp':
$isImage = true;
break;
default:
$isImage = false;
}
Your File Path is not valid.
You have a path error like : "/Users/.../uploads/1541963916_4dd672e5f3a3060ced41f3f7975453c9.gif"
After /Users/ you have stille three dots "..." that is not passible .. dots for a folder backwards. And one dot . for root direcotory.
Your Errocode, says: "file /Users/.../uploads/1541963916_4dd672e5f3a3060ced41f3f7975453c9.gif is missing or invalid"
Ist Invalid PATH, that means he cant find your file in your system.

Understanding if a file is an image or a video from its content

I can not find a way to understand if a file is really a video or an image.
For example: I have a .jpg image renamed .mp4, if I open it via computer or browser I can not see anything because it is not really a video.
What I'm looking for is a way to understand if a video / image beyond the required extension is also really a video or an image, depending on the request.
In theory I would like a similar result:
$ImageOrVideo = pathinfo($_FILES["file"]["tmp_name"],PATHINFO_EXTENSION);
switch($ImageOrVideo){
case 'jpg': //check if a real image
case 'mp4': // check if a real video
default: exit('stop');
}
I had thought of some solutions, for example in the past I had used for the images getimagesize (), but now the php documentation says:
Caution This function expects filename to be a valid image file. If a
non-image file is supplied, it may be incorrectly detected as an image
and the function will return successfully, but the array may contain
nonsensical values.
Do not use getimagesize() to check that a given file is a valid image.
Use a purpose-built solution such as the Fileinfo extension instead.
$ImageOrVideo = $_FILES["file"]["tmp_name"];
switch(mime_content_type($ImageOrVideo)){
case 'image/jpeg':
// ........
break;
case 'video/mp4':
// ........
break;
default:
exit('stop');
}

PHP imagecreate() PNG from any commonly used file-format?

I currently have an image upload input that only accepts PNG, JPG/JPEG, GIF images.
If the file is valid, it then proceeds to create a thumbnail from the image using
imagecreatefrompng()
imagecopy()
imagejpg()
This works fine, but ONLY for png images, obviously.
What is the most logical and efficient way to use "imagecreatefrompng()" except using the proper file format that was submitted? All I can think of is if/else using multiple "imagecreatefrom__()" but that doesn't seem right.
Also, how can my outputted format always be PNG no matter what was submitted instead of the current imagejpg() I have now.
You will have to use a switch and determine the image type like so:
$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;
}
-EDIT- Didn't see the second part of your question, you just need to save it using imagepng to save it to a PNG, no need to do anything else.
Using imagecreatefromstring( file_get_contents( $filename)) would be the lazy option here.
And if you always want a png output, then just exchanging imagejpg for imagepng would do.

Validating image uploads with PHP

I have an image upload program setup that I made with PHP to allow the public to submit their images. I am having trouble finding a method to make sure the file is actually an image. I'm checking the file type, and also using getimagesize(), amongst other checks but if I rename a text file to become a JPG file my validation allows the file. How can I ensure this is actually an image? I don't want my boss to execute any infected files.
you can use Imagick's identifyImage() command.
if it gives you back image data its an image if it hands back an error or no image data then its not an image. there is a command line version of this tool you can use to: http://www.imagemagick.org/script/identify.php if you do not have php compiled with imagemagick
Check allowed extensions
.gif .jpg .jpeg .png should be allowed
How about to use Exif module's exit-imagetype() function?
http://www.php.net/manual/en/function.exif-imagetype.php
<?php
if (exif_imagetype('image.gif') != IMAGETYPE_GIF) {
echo 'The picture is not a gif';
}
?>
Reproduce the uploaded image using gd. If the image isn't reproduced, it's not an image!
If this function returns false, then it's not a valid image. I haven't worked with any more than jpg, png and gif, so there might be some more image types out there that can fit into this function (bmp?)...
function checkFileType($filetype,$tmp_name)
{
$return_val = false;
switch($filetype){
case 'image/jpg':
case 'image/jpeg':
case 'image/pjpeg':
$return_val = #imagecreatefromjpeg($tmp_name);
break;
case 'image/gif':
$return_val = #imagecreatefromgif($tmp_name);
break;
case 'image/png':
case 'image/x-png':
$return_val = #imagecreatefrompng($tmp_name);
break;
}
return $return_val;
}

ImageCreateFromString and getimagesize in PHP

Currently if a user POST/uploads a photo to my PHP script I start out with some code like this
getimagesize($_FILES['picture1']['tmp_name']);
I then do a LOT more stuff to it but I am trying to also be able to get a photo from a URL and process it with my other existing code if I can. SO I am wanting to know, I f I use something like this
$image = ImageCreateFromString(file_get_contents($url));
Would I be able to then run getimagesize() on my $image variable?
UPDATE
I just tried this...
$url = 'http://a0.twimg.com/a/1262802780/images/twitter_logo_header.png';
$image = imagecreatefromstring(file_get_contents($url));
$imageinfo = getimagesize($image);
print_r($imageinfo);
But it didnt work, gave this.
Warning: getimagesize(Resource id #4) [function.getimagesize]: failed to open stream: No such file or directory in
Any idea how I can do this or something similar to get the result I am after?
I suggest you follow this approach:
// if you need the image type
$type = exif_imagetype($url);
// if you need the image mime type
$type = image_type_to_mime_type(exif_imagetype($url));
// if you need the image extension associated with the mime type
$type = image_type_to_extension(exif_imagetype($url));
// if you don't care about the image type ignore all the above code
$image = ImageCreateFromString(file_get_contents($url));
echo ImageSX($image); // width
echo ImageSY($image); // height
Using exif_imagetype() is a lot faster than getimagesize(), the same goes for ImageSX() / ImageSY(), plus they don't return arrays and can also return the correct image dimension after the image has been resized or cropped for instance.
Also, using getimagesize() on URLs isn't good because it'll consume much more bandwidth than the alternative exif_imagetype(), from the PHP Manual:
When a correct signature is found, the
appropriate constant value will be
returned otherwise the return value is
FALSE. The return value is the same
value that getimagesize() returns in
index 2 but exif_imagetype() is much
faster.
That's because exif_imagetype() will only read the first few bytes of data.
If you've already got an image resource, you'd get the size using the imagesx and imagesy functions.
getimagesize can be used with HTTP.
Filename - It can reference a local file or (configuration permitting) a remote file using one of the supported streams.
Thus
$info = getimagesize($url);
$image = ImageCreateFromString(file_get_contents($url));
should be fine.
Not sure if this will help, but I ran into a similar issue and it turned out the firewall controlled by my host was blocking outgoing http connection from my server.
They changed the firewall settings. My code then worked.
BTW: I thought this might have been an issue when I tried file_get_contents() on a number of urls, none of which worked!

Categories