My application is having images sent to it from mobile devices with the content-type "application/octet-stream".
I need to process these images using the GD library, which means I need to be able to create an image object from the data.
Typically, I have been using imagecreatefromjpeg, imagecreatefrompng, imagecreatefromgif, etc, to handle files uploaded from web forms, but these don't seem to work when coming to me as application/octet-stream.
Any ideas on how I can achieve my goal?
EDIT
Here is the code I use to create the image identifier...my handler works perfectly throughout my site, the only difference I can tell between my site and the data from the iOS is the content-type
public function open_image($path) {
# JPEG:
$im = #imagecreatefromjpeg($path);
if ($im !== false) { $this->image = $im; return $im; }
# GIF:
$im = #imagecreatefromgif($path);
if ($im !== false) { $this->image = $im; return $im; }
# PNG:
$im = #imagecreatefrompng($path);
if ($im !== false) { $this->image = $im; return $im; }
$this->error_messages[] = "Please make sure the image is a jpeg, a png, or a gif.";
return false;
}
Easy :)
$image = imagecreatefromstring( $data );
Specifically:
$data = file_get_contents($_FILES['myphoto']['tmp_name']);
$image = imagecreatefromstring( $data );
I found this in the codeigniter forum a way to change the mime and it works, I suppose you can use for other frameworks as well, this is the link and this the code:
//if mime type is application/octet-stream (psp gives jpegs that type) try to find a more specific mime type
$mimetype = strtolower(preg_replace("/^(.+?);.*$/", "\\1", $_FILES['form_field'] ['type'])); //reg exp copied from CIs Upload.php
if($mimetype == 'application/octet-stream'){
$finfo = finfo_open(FILEINFO_MIME, '/usr/share/file/magic');
if($finfo){
$_FILES['form_field']['type'] = finfo_file($finfo, $_FILES['form_field']['tmp_name']);
finfo_close($finfo);
}
else echo "finfo_open() returned false");
}
Fileinfo extension needs to be installed on the server.
It worked for me.
you can use this function too. it not require any other dependency. and work perfectly for other types also.
function _getmime($file){
if($info = #getimagesize($file)) {
return image_type_to_mime_type($info[2]);
} else {
return mime_content_type($file);
}
}
Related
I'm trying to get mime type of the profile picture they're in format user_id.jpg or gif or png, I experimented with this code but it's not working.
function detectFileMimeType($filename='')
{
$filename = escapeshellcmd($filename);
$command = "file -b --mime-type -m /usr/share/misc/magic {$filename}";
$mimeType = shell_exec($command);
return trim($mimeType);
}
function get_avatar($image, $user_id, $account)
{
$imgurl ="http://mypage/files/pictures/picture-" . ($user_id, $mimeType) . ".jpg";
if (!is_imgurl_good($imgurl)) {
$imgurl = "http://mypage/sites/all/themes/simple_custom/user.png";
}
return $imgurl;
}
You should be able to get the MIME type of a file fairly easily with built in functions provided by PHP -
function detectFileMimeType($filename='')
$finfo = finfo_open(FILEINFO_MIME_TYPE); // return mime type
$fileglob = glob($filename);
echo finfo_file($finfo, $fileglob);
finfo_close($finfo);
}
http://php.net/manual/en/function.finfo-file.php
http://php.net/manual/en/function.glob.php
As well as finfo which works fine, a slightly easier method is to get PHP getimagesize function return, as this will return the MIME type as extracted from the file:
$file = "blah/blahblah/bubbles.jpg";
$fileTypeData = getimagesize($file);
$fileTypeData['mime'] = The Mime type of the image file.
Here is the file upload code. It works in such a way that it accepts all the image extensions. But it needs to validate the file type (video, word doc etc). I need it to only upload images. For an example what happens now is that when I select a word document and submit my form, it shows a bunch of errors, inserts the record but not the file. What should happen is that, if the file is anything other than an image, it should not let the user insert the record. Should get an error message saying to check the file type when the form is submitted. Please assist me in achieving this.
if( isset($_FILES['img']) )
{
//resizing the image
$image = new SimpleImage();
$image->load($_FILES['img']['tmp_name']);
$image->resizeToHeight(180);
$info = pathinfo($_FILES['img']['name']);
$file = 'uploads/' . basename($_FILES['img']['name'],'.'.$info['extension']) . '.png';
if ($image->save($file))
{
if($fp = fopen($file , 'rb'))
{
$data = fread($fp, filesize($file));
//encoding the the image only to text so can be stored in DB
$data = base64_encode($data);
fclose($fp);
}
}
else
{
$error = '<p id="failed">Invalid Image</p>';
}
You need to check MIME type on the image, something like that:
if (isset($_FILES['img'])) {
$file = $_FILES['img'];
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $file['tmp_name']);
finfo_close($finfo);
if (strpos($mime, 'image') === false) {
die('The submitted file is not an image!');
}
// Uploading code..
}
If mime string has 'image' in it, then it's image. Hope that will help.
In older PHP versions you can use mime_content_type. However if you have PHP > 5.3 you should use the finfo_* functions
You should also check is_uploaded_file() rather than isset()
if( is_uploaded_file( $_FILES['img']['tmp_name'] ) ) {
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$type = finfo_file( $_FILES['img']['tmp_name'] );
if( $type == 'image/gif' ) { // for example
// do stuff
}
}
How can I check if a file is an mp3 file or image file, other than check each possible extension?
Native ways to get the mimetype:
For PHP < 5.3 use mime_content_type()
For PHP >= 5.3 use finfo_fopen()
Alternatives to get the MimeType are exif_imagetype and getimagesize, but these rely on having the appropriate libs installed. In addition, they will likely just return image mimetypes, instead of the whole list given in magic.mime.
If you don't want to bother about what is available on your system, just wrap all four functions into a proxy method that delegates the function call to whatever is available, e.g.
function getMimeType($filename)
{
$mimetype = false;
if(function_exists('finfo_fopen')) {
// open with FileInfo
} elseif(function_exists('getimagesize')) {
// open with GD
} elseif(function_exists('exif_imagetype')) {
// open with EXIF
} elseif(function_exists('mime_content_type')) {
$mimetype = mime_content_type($filename);
}
return $mimetype;
}
You can identify image files using getimagesize.
To find out more about MP3 and other audio/video files, I have been recommended php-mp4info getID3().
To find the mime type of a file I use the following wrapper function:
function Mime($path)
{
$result = false;
if (is_file($path) === true)
{
if (function_exists('finfo_open') === true)
{
$finfo = finfo_open(FILEINFO_MIME_TYPE);
if (is_resource($finfo) === true)
{
$result = finfo_file($finfo, $path);
}
finfo_close($finfo);
}
else if (function_exists('mime_content_type') === true)
{
$result = preg_replace('~^(.+);.*$~', '$1', mime_content_type($path));
}
else if (function_exists('exif_imagetype') === true)
{
$result = image_type_to_mime_type(exif_imagetype($path));
}
}
return $result;
}
try mime_content_type()
<?php
echo mime_content_type('php.gif') . "\n";
echo mime_content_type('test.php');
?>
Output:
image/gif
text/plain
Or better use finfo_file() the other way is deprecated.
getimageinfo is best to find images .
Check if return type is false .
You can use FileInfo module which is built into PHP since 5.3. If you are using a PHP version less than PHP 5.3, you can install it as a PECL extension:
After installation the finfo_file function will return file information.
PECL extension: http://pecl.php.net/package/fileinfo
PHP Documentation: http://www.php.net/manual/en/book.fileinfo.php
You could use finfo like this:
$mime = finfo_open(FILEINFO_MIME, $path_to_mime_magic_file);
if ($mime ===FALSE) {
throw new Exception ('Finfo could not be run');
}
$filetype = finfo_file($mime, $filename);
finfo_close($mime);
or if you have problems with finfo not being installed, or the mime magic file just not working (it works correctly on 3 out of our 4 servers - all identical OS and PHP installs) - then try using Linux's native file (don't forget to sanitise the filename though: in this example, I know the filename can be trusted as it's a PHP temporary filename in my test code):
ob_start();
system('file -i -b '.$filename);
$output = ob_get_clean();
$output = explode("; ", $output);
if (is_array($output)) {
$filetype = trim($output[0]);
}
Then just pass the mime file type to a switch statement like:
switch (strtolower($filetype)) {
case 'image/gif':
return '.gif';
break;
case 'image/png':
return '.png';
break;
case 'image/jpeg':
return '.jpg';
break;
case 'audio/mpeg':
return '.mp3';
break;
}
return null;
This function checks if the file is an image based on extension and mime and returns true if it's a browser compatible image...
function checkImage($image) {
//checks if the file is a browser compatible image
$mimes = array('image/gif','image/jpeg','image/pjpeg','image/png');
//get mime type
$mime = getimagesize($image);
$mime = $mime['mime'];
$extensions = array('jpg','png','gif','jpeg');
$extension = strtolower( pathinfo( $image, PATHINFO_EXTENSION ) );
if ( in_array( $extension , $extensions ) AND in_array( $mime, $mimes ) ) return TRUE;
else return FALSE;
}
For Images, I use:
function is_image($path)
{
$a = getimagesize($path);
$image_type = $a[2];
if(in_array($image_type , array(IMAGETYPE_GIF , IMAGETYPE_JPEG ,IMAGETYPE_PNG , IMAGETYPE_BMP)))
{
return true;
}
return false;
}
The best way is to use finfo_file function.
Example:
<?php
if (isset($_FILES['yourfilename']['tmp_name'])) {
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $_FILES['yourfilename']['tmp_name']);
if ($mime == 'image/jpg') {
echo "It's an jpg image!";
}
finfo_close($finfo);
}
?>
This function get a file path and with use finfo_open and mime_content_type if supported, return image or video or audio string.
/**
* get file type
* #return image, video, audio
*/
public static function getFileType($file)
{
if (function_exists('finfo_open')) {
if ($info = finfo_open(defined('FILEINFO_MIME_TYPE') ? FILEINFO_MIME_TYPE : FILEINFO_MIME)) {
$mimeType = finfo_file($info, $file);
}
} elseif (function_exists('mime_content_type')) {
$mimeType = mime_content_type($file);
}
if (strstr($mimeType, 'image/')) {
return 'image';
} else if (strstr($mimeType, 'video/')) {
return 'video';
} else if (strstr($mimeType, 'audio/')) {
return 'audio';
} else {
return null;
}
}
I used this code to check for the type of images,
$f_type=$_FILES['fupload']['type'];
if ($f_type== "image/gif" OR $f_type== "image/png" OR $f_type== "image/jpeg" OR $f_type== "image/JPEG" OR $f_type== "image/PNG" OR $f_type== "image/GIF")
{
$error=False;
}
else
{
$error=True;
}
but some users complain they get an error while uploading any type of images, while some others don't get any errors!
I was wondering if this fixes the problem:
if (mime_content_type($_FILES['fupload']['type']) == "image/gif"){...
Any comments?
Never use $_FILES..['type']. The information contained in it is not verified at all, it's a user-defined value. Test the type yourself. For images, exif_imagetype is usually a good choice:
$allowedTypes = array(IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_GIF);
$detectedType = exif_imagetype($_FILES['fupload']['tmp_name']);
$error = !in_array($detectedType, $allowedTypes);
Alternatively, the finfo functions are great, if your server supports them.
In addition to #deceze, you may also finfo() to check the MIME-type of non-image-files:
$finfo = new finfo();
$fileMimeType = $finfo->file($path . $filename, FILEINFO_MIME_TYPE);
Sure you could check if it's an image with exif, but a better way I think is to do with finfo like this:
$allowed_types = array ( 'application/pdf', 'image/jpeg', 'image/png' );
$fileInfo = finfo_open(FILEINFO_MIME_TYPE);
$detected_type = finfo_file( $fileInfo, $_FILES['datei']['tmp_name'] );
if ( !in_array($detected_type, $allowed_types) ) {
die ( 'Please upload a pdf or an image ' );
}
finfo_close( $fileInfo );
The best way in my opinion is first to use getimagesize() followed by imagecreatefromstring().
$size = getimagesize($filename);
if ($size === false) {
throw new Exception("{$filename}: Invalid image.");
}
if ($size[0] > 2500 || $size[1] > 2500) {
throw new Exception("{$filename}: Image too large.");
}
if (!$img = #imagecreatefromstring(file_get_contents($filename))) {
throw new Exception("{$filename}: Invalid image content.");
}
Checking by getimagesize() prevents some DoS attacks, because we don't have to try to imagecreatefromstring() from every file provided by the user, either non-image file or file too big. Unfortunately, according to PHP docs cannot be relied on for checking image type content.
The imagecreatefromstring() finally tries to open the file as an image - if is succeeds - we have an image.
This is a simple, one line script that I use often.
$image = "/var/www/Core/temp/image.jpg";
$isImage = explode("/", mime_content_type())[0] == "image";
Basically I am using mime_content_type() to get something like "image/jpg" and then exploding it by "/" and checking against the first element of the array to see if it says "image".
I hope it works!
In PHP 5.5 I use this function for getting file type and check if image:
function getFileType( $file ) {
return image_type_to_mime_type( exif_imagetype( $file ) );
}
// Get file type
$file_type = getFileType( 'path/to/images/test.png' );
echo $file_type;
// Prints image/png
// 1. All images have mime type starting with "image"
// 2. No other non-image mime types contain string "image" in it
Then you could do:
if ( strpos( $filetype, 'image' ) !== false ) {
// This is an image
}
Complete list of mime types: http://www.sitepoint.com/web-foundations/mime-types-complete-list/
That last line is close. You can use:
if (mime_content_type($_FILES['fupload']['tmp_name']) == "image/gif"){...
In the case I'm currently working on, my $_FILES..['type'] reports itself as "text/csv", while both mime_content_type() and finfo() (suggested by others) report "text/plain.". As #deceze points out, $_FILES..['type'] is only useful to know what type a client thinks a file is.
you can try this
$file_extension = explode('.',$file['name']);
$file_extension = strtolower(end($file_extension));
$accepted_formate = array('jpeg','jpg','png');
if(in_array($file_extension,$accepted_formate)) {
echo "This is jpeg/jpg/png file";
} else {
echo $file_extension.' This is file not allowed !!';
}
WARNING: the following answer does not actually check the file type. It only checks the name. It is not suitable for actual security purposes.
EDIT: Don't Use this method as it serves no security check. I am leaving this answer here so that no one makes the same mistake like me by trying this.
I tried the following and it worked for me:
$allowed = array('gif','png' ,'jpg', 'pdf');
$filename = $_FILES['input_tag_name']['name'];
$ext = pathinfo($filename, PATHINFO_EXTENSION);
if(!in_array($ext,$allowed) ) {
echo 'error';
}
Source link
how to check whether file is image or video type in php version 5.2.9
$mime = mime_content_type($file);
if(strstr($mime, "video/")){
// this code for video
}else if(strstr($mime, "image/")){
// this code for image
}
Should work for most file extentions.
See my answer to
How can I check if a file is a mp3 or image file?
Example Code
function getMimeType($filename)
{
$mimetype = false;
if(function_exists('finfo_fopen')) {
// open with FileInfo
} elseif(function_exists('getimagesize')) {
// open with GD
} elseif(function_exists('exif_imagetype')) {
// open with EXIF
} elseif(function_exists('mime_content_type')) {
$mimetype = mime_content_type($filename);
}
return $mimetype;
}
I use the following code which IMO is more universal than in the first and the most upvoted answer:
$mimeType = mime_content_type($filename);
$fileType = explode('/', $mimeType)[0];
I hope it was helpful for anyone.
You can check the MIME type using the finfo_file function
Example from the help page
<?php
$finfo = finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension
foreach (glob("*") as $filename) {
echo finfo_file($finfo, $filename) . "\n";
}
finfo_close($finfo);
?>
EDIT: after better checking your question, this won't work, finfo functions require PHP 5.3.0
if(isset($_FILES['my_file'])) {
$mime = $_FILES['my_file']['type'];
if(strstr($mime, "video/")){
$filetype = "video";
}else if(strstr($mime, "image/")){
$filetype = "image";
}else if(strstr($mime, "audio/")){
$filetype = "audio";
}
Rather old question, but for others looking at this in the future, I would handle this like so:
function getType($file): string
{
$mime_type = mime_content_type($file);
return strtok($mime_type, '/');
}
This method utilises strtok to return the portion of the $mime_type string before the first /.
For example, let's say $file has a $mime_type of video/mp4, the getType method will return video.
I use this code and it works very well.
$mimeType = $request->images->getMimeType();
$fileType = explode('/', $mimeType)[0];
if it was an image, this code will give you the image word in the $fileType and if it was a video this code will give you the video word in the $fileType, then you can check on it by the if conditions.
good luck