Checking image file type - php

I'm attempting to add a function to my site where users can set their profile picture as an image from an external url, instead of saving it to their pc, then uploading it to my server.
This is what I've come up with so far:
$filename = $inputs['image_url'];
if(getimagesize($filename)){
// Get new dimensions
list($width, $height) = getimagesize($filename);
$new_width = 100;
$new_height = 100;
// Resample
$image_p = imagecreatetruecolor($new_width, $new_height);
//a check needs to be done here $image = imagecreatefromjpeg($filename);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
$filename = "profile_pictures/". md5( uniqid(rand(),true) ).".jpg";
imagejpeg($image_p,$filename,100);
}else{
echo 'This is not an image';
}
The code can download .jpg images fine, but I want to support other filetypes too.
I need to somehow check the file type of the image so I can save other images with different filetypes...
if($extension=="jpg" || $extension=="jpeg"){
$image = imagecreatefromjpeg($filename);
}else if($extension=="png"){
image = imagecreatefrompng($filename);
}else{
$image = imagecreatefromgif($filename);
}
Does anyone know of a function that would allow me to do this?
Thanks in advance for any replies.

Most straight forward and for GD compatiblity checking you can just create it from string:
$image = imagecreatefromstring(file_get_contents($filename));
If this fails to load, you know that you can not process that image.
But see as well getimagesize, it inspects the filetype as well, not only width and height:
list($width, $height, $type) = getimagesize($filename);
The third element, $type, then is any of these IMAGETYPE_XXX constants:
Value Constant
1 IMAGETYPE_GIF
2 IMAGETYPE_JPEG
3 IMAGETYPE_PNG
4 IMAGETYPE_SWF
5 IMAGETYPE_PSD
6 IMAGETYPE_BMP
7 IMAGETYPE_TIFF_II (intel byte order)
8 IMAGETYPE_TIFF_MM (motorola byte order)
9 IMAGETYPE_JPC
10 IMAGETYPE_JP2
11 IMAGETYPE_JPX
12 IMAGETYPE_JB2
13 IMAGETYPE_SWC
14 IMAGETYPE_IFF
15 IMAGETYPE_WBMP
16 IMAGETYPE_XBM
17 IMAGETYPE_ICO
From exif_imagetype. If you combine both, you could first check if the type is okay to load for you and you then check if you can load it.

Splfileinfo::getextension.php might be just what you need.
Edit : I misread, you only want to check the extension of a string. There isn't built-in function for that in PHP, you can simply use a regexp :
$ext = substr(strrchr($fileName,'.'),1);

You can try of of this
$fileExtention = pathinfo ( $filename, PATHINFO_EXTENSION );
Or
$fileExtention = image_type_to_extension(exif_imagetype($filename));
Finally i would advice you use something like http://phpthumb.sourceforge.net/ is has more than what you need to manipulate images

Related

Black result image problem on BMP image resize using PHP

I have a PHP script to re size image file as below;
$file = "test.bmp";
$ext = pathinfo($file, PATHINFO_EXTENSION);
$info = pathinfo($file);
$file_name = basename($file,'.'.$info['extension']);
$thumbname = "thumb/".$file_name.".".$ext;
$maxh = 200;
$maxw = 200;
$quality = 100;
list($width,$height)=getimagesize($file);
$src = imagecreatefromwbmp($file);
$tmp = imagecreatetruecolor($maxw,$maxh);
imagecopyresampled($tmp,$src,0,0,0,0,200,200,$width,$height);
imagejpeg($tmp,$thumbname,$quality);
imagedestroy($tmp);
The script is suppose to resize a Windows bitmap image to 200x200 thumbnail. But instead, I am getting a black 200x200 image. I am using PHP with Apache in Windows PC. How can I fix this?
.bmp and wbmp are VERY, VERY different file types.
Note the content-type headers:
Content-Type: image/x-xbitmap
Content-Type: image/vnd.wap.wbmp
Calling imagecreatefromwbmp($file) where $file is a .bmp will fail every time.
See this thread for info on how to load a .bmp file. It's not pretty.
As pointed out in PHP imagecopyresampled() docs:
Note:
There is a problem due to palette image limitations (255+1 colors). Resampling or filtering an image commonly needs more colors than 255, a kind of approximation is used to calculate the new resampled pixel and its color. With a palette image we try to allocate a new color, if that failed, we choose the closest (in theory) computed color. This is not always the closest visual color. That may produce a weird result, like blank (or visually blank) images. To skip this problem, please use a truecolor image as a destination image, such as one created by imagecreatetruecolor().
To see if it's the case you can use imageistruecolor() and copy the contents to a new truecolor image before "copyresampling" it:
if( !imageistruecolor($src) ){
$newim = imagecreatetruecolor( $width, $height );
imagecopy( $newim, $src, 0, 0, 0, 0, $width, $height );
imagedestroy($src);
$src = $newim;
}
There is a new opensource project on Github that allows reading and saving of BMP files (and other file formats) in PHP.
The project is called PHP Image Magician.
<?php
//Create New 'Thumbnail' Image
$newImageWidth = 200;
$newImageHeight = 200;
$newImage = imagecreatetruecolor($newImageWidth, $newImageHeight);
$newImageFile = 'output.jpg';
$newImageQuality = 100;
//Load old Image(bmp, jpg, gif, png, etc)
$oldImageFile = "test.jpg";
//Specific function
$oldImage = imagecreatefromjpeg($oldImageFile);
//Non-Specific function
//$oldImageContent = file_get_contents($oldImageFile);
//$oldImage = imagecreatefromstring($oldImageContent);
//Get old Image's details
$oldImageWidth = imagesx($oldImage);
$oldImageHeight = imagesy($oldImage);
//Copy to new Image
imagecopyresampled($newImage, $oldImage, 0, 0, 0, 0, $newImageWidth, $newImageHeight, $oldImageWidth, $oldImageHeight);
//Output to file
imagejpeg($newImage, $newImageFile, $newImageQuality);

PHP: crop with PNG and trans

Im having issue when a user uploads and try's to crop a PNG or transparent image( with .gif)
I am getting:
Warning: imagecreatefromjpeg(): gd-jpeg: JPEG library reports unrecoverable error: in statusUpFunctions.php on line 100
Warning: imagecreatefromjpeg(): 'images/status/photo/1-6.jpg' is not a valid JPEG file in statusUpFunctions.php on line 100
Warning: imagecopyresampled() expects parameter 2 to be resource, boolean given in statusUpFunctions.php on line 114
This may be because of my php crop function:
case 'crop':
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
ini_set('memory_limit', '256M');
$jpeg_quality = 90;
$src = "images/status/photo/".$_POST['fname'];
$img_r = imagecreatefromjpeg($src);
if($_POST['fixed'] == 0) {
$targ_w = $_POST['w'];
$targ_h = $_POST['h'];
}
else {
$targ_h = $_POST['sizeh'];
$targ_w = $_POST['sizew'];
}
$dst_r = ImageCreateTrueColor( $targ_w, $targ_h );
imagecopyresampled($dst_r,$img_r,0,0,$_POST['x'],$_POST['y'],
$targ_w,$targ_h,$_POST['w'],$_POST['h']);
$path_thumbs = "images/status/photo";
$filename = $newfilename;
$thumb_path = $path_thumbs . '/' . $filename;
imagejpeg($dst_r,$thumb_path,$jpeg_quality);
}
break;
}
It creates from jpg, cant i make so it creates from gif and png and bmp and so..? and then convert it somehow..
How should this be solved?
The function imagecreatefromjpeg() creates a generic PHP image object from a jpeg image. You can then do whatever you want with the object.
imagecreatefromjpeg() will ONLY create a generic image object FROM a JPEG. If you want to create a generic image object FROM a PNG or GIF, you need to use their respective functions: imagecreatefrompng() and imagecreatefromgif(). One quick way to detect an image's type is by reading its file extension.
Once you have that generic image object, then you can do what you want with it (including using imagecopyresampled()), and then create a jpeg image from it using imagejpeg().
EDIT:
You can use pathinfo() to detect the file's extension:
$filename = pathinfo($_POST['fname']); // Returns an array of file details
$extension = $filename['extension'];
If you are getting the filename from a $_POST value, you need to make sure that you are copying the temporary image file to that filename. I don't see any $_FILES values used in your code (maybe you're doing it in another script?). If not, here's a good tutorial on handling file uploads. It also covers file extensions.
Try This... It will work..
<?php
$image = imagecreatefrompng('photo.png');
$thumb_width = 280;
$thumb_height = 200;
$width = imagesx($image);
$height = imagesy($image);
$original_aspect = $width / $height;
$thumb_aspect = $thumb_width / $thumb_height;
if ( $original_aspect >= $thumb_aspect ){
// If image is wider than thumbnail (in aspect ratio sense)
$new_height = $thumb_height;
$new_width = $width / ($height / $thumb_height);
}else{
// If the thumbnail is wider than the image
$new_width = $thumb_width;
$new_height = $height / ($width / $thumb_width);
}
$crop = imagecreatetruecolor($thumb_width,$thumb_height);
imagealphablending($crop, false);
$white = imagecolorallocatealpha($crop, 0, 0, 0, 127); //FOR WHITE BACKGROUND
imagefilledrectangle($crop,0,0,$thumb_width,$thumb_height,$white);
imagesavealpha($crop, true);
$userImage = imagecopyresampled($crop, $image,
0 - ($new_width - $thumb_width) / 2, // Center the image horizontally
0 - ($new_height - $thumb_height) / 2, // Center the image vertically
0, 0, $new_width, $new_height,
$width, $height);
header('Content-type: image/png');
imagepng($crop);
?>
It fails to load the image, causing imagecreatefromjpeg() to return false. Make sure that you're trying to open an valid image.
For gif and png files you need to get the image identifier using imagecreatefromgif and imagecreatefrompng
<?php
$image = imagecreatefrompng('myPhoto.png');
$crop = imagecreatetruecolor(50,50);
$userImage = imagecopyresampled($crop, $image, 0, 0, 0, 0, 50, 50, 8, 8);
header('Content-type: image/png');
imagepng($crop);
?>
This will return cropped image.

php says php made png is invalid

So I have a function that turns a jpeg into a png image resizes it then saves it. Then a bit later i come back to it and use the image in a rotate function. I keep getting errors though. It says uploads/image.png isnt a valid PNG file. The weird thing is that it only does then on php edited png files. If i delete image.png and download a png from the internet name is image.png is works fine as long as i dont run it through the first resize script.
function load($filename) {
$image_info = getimagesize($filename);
$this->image_type = $image_info[2];
if( $this->image_type == IMAGETYPE_JPEG ) {
$imagecreated = imagecreatefromjpeg($filename);
$this->image = $imagecreated;
$extention = pathinfo($filename, PATHINFO_EXTENSION);
$basename = basename($filename, ".".$extention);
$newname = "uploads/".$basename;
imagepng($imagecreated, $newname.".png", 0);
// ....???
function resize($width,$height) {
$new_image = imagecreatetruecolor($width, $height);
imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height,
$this->getWidth(), $this->getHeight());
$this->image = $new_image;
}
Then i save the file with just a simple
imagepng(etc etc);
I go to the uploads folder and it looks fine. its resized and everything. I also noticed photoshop wont open the edited png either.
Also the line of code that produces the error is here..
$image = imagecreatefrompng('uploads/image.png');
Possible fix is to add a NULL for your filters parameter (the last parameter in imagepng)
ie.
imagepng($image,$file_location,0,NULL);
I can't say this should be needed, but I read a similar case where someone noted they had to do this, may be dependant on the version of libpng or gd lib.

imagejpeg() doesnt give the output properly in php

I want to upload an image from disk, resize it, and then upload it to Amazon S3.
However, I cant get the proper image output from imagejpeg().
heres my code:
$sourceUrl = $_FILES['path']['tmp_name'];
$thumbWidth = '100';
$thumbid = uniqid();
$img = imagecreatefromjpeg($sourceUrl);
$width = imagesx( $img );
$height = imagesy( $img );
// calculate thumbnail size
$new_width = $thumbWidth;
$new_height = floor( $height * ( $thumbWidth / $width ) );
// create a new temporary image
$tmp_img = imagecreatetruecolor( $new_width, $new_height );
// copy and resize old image into new image
imagecopyresampled($tmp_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
// output the image
imagejpeg($tmp_img);
// upload thumbnail to s3
$s3->putObjectFile($tmp_img, "mybucket", $thumbid, S3::ACL_PUBLIC_READ);
Firebug gives me this error :
illegal character
[Break on this error] (�����JFIF���������>CREATOR: g...(using IJG JPEG v62), default quality\n
If I modify imagejpeg this way,
imagejpeg($tmp_img, 'abc.jpg');
then I get the same error. :(
Can i get some help here please ?
If you check the documentation of imagejpeg you can see it outputs the image, it means the way you call it it gets sent to the browser. You can get it to save to a file the second way you call it - by passing a filename in the second parameter.
Also, $tmp_img is an image resource, not a ready-to-use image file.
I don't know how your upload function works, but: if you need the file contents to upload, do it like this:
ob_start();
imagejpeg($tmp_image);
$image_contents = ob_get_clean();
$s3->putObjectFile($image_contents, "mybucket", $thumbid, S3::ACL_PUBLIC_READ);
if you need a filename to upload:
$filename = tempnam(sys_get_temp_dir(), "foo");
imagejpeg($tmp_image, $filename);
$s3->putObjectFile($filename, "mybucket", $thumbid, S3::ACL_PUBLIC_READ);
You have to define the header:
header('Content-type: image/jpeg');
1) $tmp_img is a resource not a file. You probably need to save the image to disc and use that for putObjectFile
2) You probably need to tell S3 that the file you're uploading is of type image/jpeg
Well guys thank you very much again, I screwed around a bit more and combining that with your responses I got this working as follows :)
$thumbid .= ".jpg";
$img = imagecreatefromgif($sourceUrl);
$width = imagesx( $img );
$height = imagesy( $img );
// calculate thumbnail size
$new_width = $thumbWidth;
$new_height = floor( $height * ( $thumbWidth / $width ) );
// create a new temporary image
$tmp_img = imagecreatetruecolor( $new_width, $new_height );
// copy and resize old image into new image
imagecopyresampled($tmp_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
$path = '/var/www/1.4/wwwroot/cdn/'.$thumbid;
// output the image
if(imagegif($tmp_img, $path)){
$thumblink = "";
// upload thumbnail to s3
if($s3->putObjectFile($path, "mybucket", $thumbid, S3::ACL_PUBLIC_READ)){
$thumblink = "http://dtzhqabcdscm.cloudfront.net/".$thumbid;
imagedestroy($tmp_img);
}
return $thumblink;
}

Use PHP to convert PNG to JPG with compression?

I have a bunch of high quality PNG files. I want to use PHP to convert them to JPG because of it's smaller file sizes while maintaining quality. I want to display the JPG files on the web.
Does PHP have functions/libraries to do this? Is the quality/compression any good?
Do this to convert safely a PNG to JPG with the transparency in white.
$image = imagecreatefrompng($filePath);
$bg = imagecreatetruecolor(imagesx($image), imagesy($image));
imagefill($bg, 0, 0, imagecolorallocate($bg, 255, 255, 255));
imagealphablending($bg, TRUE);
imagecopy($bg, $image, 0, 0, 0, 0, imagesx($image), imagesy($image));
imagedestroy($image);
$quality = 50; // 0 = worst / smaller file, 100 = better / bigger file
imagejpeg($bg, $filePath . ".jpg", $quality);
imagedestroy($bg);
Be careful of what you want to convert. JPG doesn't support alpha-transparency while PNG does. You will lose that information.
To convert, you may use the following function:
// Quality is a number between 0 (best compression) and 100 (best quality)
function png2jpg($originalFile, $outputFile, $quality) {
$image = imagecreatefrompng($originalFile);
imagejpeg($image, $outputFile, $quality);
imagedestroy($image);
}
This function uses the imagecreatefrompng() and the imagejpeg() functions from the GD library.
This is a small example that will convert 'image.png' to 'image.jpg' at 70% image quality:
<?php
$image = imagecreatefrompng('image.png');
imagejpeg($image, 'image.jpg', 70);
imagedestroy($image);
?>
Hope that helps
<?php
function createThumbnail($imageDirectory, $imageName, $thumbDirectory, $thumbWidth) {
$explode = explode(".", $imageName);
$filetype = $explode[1];
if ($filetype == 'jpg') {
$srcImg = imagecreatefromjpeg("$imageDirectory/$imageName");
} else
if ($filetype == 'jpeg') {
$srcImg = imagecreatefromjpeg("$imageDirectory/$imageName");
} else
if ($filetype == 'png') {
$srcImg = imagecreatefrompng("$imageDirectory/$imageName");
} else
if ($filetype == 'gif') {
$srcImg = imagecreatefromgif("$imageDirectory/$imageName");
}
$origWidth = imagesx($srcImg);
$origHeight = imagesy($srcImg);
$ratio = $origWidth / $thumbWidth;
$thumbHeight = $origHeight / $ratio;
$thumbImg = imagecreatetruecolor($thumbWidth, $thumbHeight);
imagecopyresized($thumbImg, $srcImg, 0, 0, 0, 0, $thumbWidth, $thumbHeight, $origWidth, $origHeight);
if ($filetype == 'jpg') {
imagejpeg($thumbImg, "$thumbDirectory/$imageName");
} else
if ($filetype == 'jpeg') {
imagejpeg($thumbImg, "$thumbDirectory/$imageName");
} else
if ($filetype == 'png') {
imagepng($thumbImg, "$thumbDirectory/$imageName");
} else
if ($filetype == 'gif') {
imagegif($thumbImg, "$thumbDirectory/$imageName");
}
}
?>
This is a very good thumbnail script =)
Here's an example:
$path = The path to the folder where the original picture is.
$name = The filename of the file you want to make a thumbnail of.
$thumbpath = The path to the directory where you want the thumbnail to be saved into.
$maxwidth = the maximum width of the thumbnail in PX eg. 100 (wich will be 100px).
createThumbnail($path, $name, $thumbpath, $maxwidth);
You might want to look into Image Magick, usually considered the de facto standard library for image processing. Does require an extra php module to be installed though, not sure if any/which are available in a default installation.
HTH.
PHP has some image processing functions along with the imagecreatefrompng and imagejpeg function. The first will create an internal representation of a PNG image file while the second is used to save that representation as JPEG image file.
See this list of php image libraries. Basically it's GD or Imagemagick.
I know it's not an exact answer to the OP, but as answers have already be given...
Do you really need to do this in PHP ?
What I mean is : if you need to convert a lot of images, doing it in PHP might not be the best way : you'll be confronted to memory_limit, max_execution_time, ...
I would also say GD might not get you the best quality/size ratio ; but not sure about that (if you do a comparison between GD and other solutions, I am very interested by the results ;-) )
Another approach, not using PHP, would be to use Image Magick via the command line (and not as a PHP extension like other people suggested)
You'd have to write a shell-script that goes through all .png files, and gives them to either
convert to create a new .jpg file for each .png file
or mogrify to directly work on the original file and override it.
As a sidenote : if you are doing this directly on your production server, you could put some sleep time between bunches of conversions, to let it cool down a bit sometimes ^^
I've use the shell script + convert/mogrify a few times (having them run for something like 10 hours one time), and they do the job really well :-)

Categories