Check image dimensions (height and width) before uploading image using PHP - php

How can I check for height and width before uploading image, using PHP.
Must I upload the image first and use "getimagesize()"? Or can I check this before uploading it using PHP?
<?php
foreach ($_FILES["files"]["error"] as $key => $error) {
if(
$error == UPLOAD_ERR_OK
&& $_FILES["files"]["size"][$key] < 500000
&& $_FILES["files"]["type"][$key] == "image/gif"
|| $_FILES["files"]["type"][$key] == "image/png"
|| $_FILES["files"]["type"][$key] == "image/jpeg"
|| $_FILES["files"]["type"][$key] == "image/pjpeg"
){
$filename = $_FILES["files"]["name"][$key];
if(HOW TO CHECK WIDTH AND HEIGHT)
{
echo '<p>image dimenssions must be less than 1000px width and 1000px height';
}
}
?>

We can do this with temp file easily.
$image_info = getimagesize($_FILES["file_field_name"]["tmp_name"]);
$image_width = $image_info[0];
$image_height = $image_info[1];

This is how I solved it.
$test = getimagesize('../bilder/' . $filnamn);
$width = $test[0];
$height = $test[1];
if ($width > 1000 || $height > 1000)
{
echo '<p>iamge is to big';
unlink('../bilder/'.$filnamn);
}

This work for me
$file = $_FILES["files"]['tmp_name'];
list($width, $height) = getimagesize($file);
if($width > "180" || $height > "70") {
echo "Error : image size must be 180 x 70 pixels.";
exit;
}

If the file is in the $_FILES array (because it's been selected in a Multipart form), it has already been uploaded to the server (usually to /tmp or similar file path) so you can just go ahead and use the getimagesize() function in php to get the dimensions (including all details as array).

To get the width and height of the image use getimagesize(path_name), this function returns the array which contains the height, width, image_type constant and other image related info. By the following code you can achive that.
Note -
Need to pass temporary location of the image, and use the following piece of code before you use move_upload_file(), else it will move the file to destination path and you wont get the desired result for the image
$imageInformation = getimagesize($_FILES['celebrity_pic']['tmp_name']);
print_r($imageInformation);
$imageWidth = $imageInformation[0]; //Contains the Width of the Image
$imageHeight = $imageInformation[1]; //Contains the Height of the Image
if($imageWidth >= your_value && $imageHeight >= your_value)
{
//Your Code
}

You need something that is executed on the client before the actual upload happens.
With (server-side) php you can check the dimension only after the file has been uploaded or with upload hooks maybe while the image is uploaded (from the image file header data).
So your options are flash, maybe html5 with its FileAPI (haven't tested that, maybe that's not doable), java-applet, silverlight, ...

array getimagesize ( string $filename [, array &$imageinfo ] )
The getimagesize() function will determine the size of any given image file and return the dimensions along with the file type and a height/width text string to be used inside a normal HTML IMG tag and the correspondant HTTP content type.
For more update visit site:
http://www.php.net/manual/en/function.getimagesize.php

Very important - if you are using Dreamweaver to code and you try to get the image size using the $_FILES[anyFormName][tmp_name] it will display an error in live view.. It took me a while to figure this out.

Related

Calculate image file size before saving to Disk in PHP

I am kind of experimenting with the PHP Image saving.
I want to compare the image's actual file sizes before upload and after resize/compress processing, but want to know the file size that will going to be if I save it to the disk.
So that if the file size is less, then the newly processed file will replace old one, else no change will be made.
This is the code I am using to save jpeg image.
imagejpeg($this->newImage, $savePath, $imageQuality);
I tried getting the actual file size and size after
print_r(filesize($actual_file_size));
print_r($this->newImage);
where $actual_file_size gives the data by reading from tmp object file, however $this->newImage is giving blank (no value).
I am using ResizeImage class from github
Is there any way I can get the file size before saving to disk? So that I can keep the minimal size version.
This is how you do it:
$original_file = 'original.jpg';
$resized_file = 'resized.jpg';
$max_file_size = '10000';
$original_image = imagecreatefromjpeg($original_file);
$image_quality = 100;
do {
$temp_stream = fopen('php://temp', 'w+');
$saved = imagejpeg($original_image, $temp_stream, $image_quality--);
rewind($temp_stream);
$fstat = fstat($temp_stream);
fclose($temp_stream);
$file_size = $fstat['size'];
}
while (($file_size > $max_file_size) && ($image_quality >= 0));
if (-1 == $image_quality) {
echo "Unable to get the file that small. Best I could do was $file_size bytes at image quality 0.\n";
}
else {
echo "Successfully resized $original_file to $file_size bytes using image quality $image_quality. Resized file saved as $resized_file.\n";
imagejpeg($new_image, $resized_file, $image_quality + 1);
}
This requires no file to be written until you've successfully found the ideal compression ratio.
This loop starts with an $image_quality of 100, then counts downward trying each new value on a temporary in-memory buffer. If gets down to trying 0 and the file would still be too big, it returns an error message. Otherwise, if it gets to a value that works, it reports that and saves the new file using that image quality setting.
If you're feeling adventurous, you could implement a binary search algorithm to find the ideal compression ratio more quickly, but this quick-fix gives the same result, albeit possibly a tad slower.
There is no way to calculate the size before saving it to the disk. I advice you create some kind of temporary folder to save the image, then check the size and if it is what you want move it to the folder you see fit, if you dont want to save it, delete it from the temporary folder.
Not really true.
There is a way..
The following piece of code works with JPEG and PNG :-)
///######## GET THE TOTAL PIXELS
$total_pixels = $image_width * $image_height;
$size_at_max = (3 * $total_pixels) * 0.001; /// **** IN KB
Brian's answer was a bit slow with large numbers of pictures... so I used a loop which modified by half the distance each time (how some digital volt meters work)...
So quality changes in steps 50, 25, 12.5 ... etc and can go up or down as needed...
$max_file_size = 100000; //100k max saved file size
$delta = 10000; //10k distance off max when OK to stop optimizing...
$n = 1;
$quality = 100;
$size = image_size($image, $quality);
if ($size > $max_file_size) {
while ((($size > $max_file_size + $delta) or ($size < $max_file_size - $delta))) {
if ($size > $max_file_size) $quality = $quality - (100 / (2 ** $n));
elseif( $size < $max_file_size) $quality = $quality + (100 / (2 ** $n));
else break;
$size = image_size($image, $quality);
$n++;
}
}
function image_size ($image, $quality) {
ob_start();
imagewebp($image, NULL, $quality);
$size = ob_get_length();
ob_end_clean();
return $size;
}

resize width and compress images on upload php mysql

I have a client that sends me text messages from his iPhone with images for me to upload into his gallery. I'm trying to create a admin system so I can simply take the images from the texts, go to the admin page on my iPhone and upload the images straight to the gallery.
This would save me tons of time in my day to day work schedule.
Using the provided code. How can I add the following functions:
I would like to compress the file size down to a smaller size if possible, similar to the save to web jpg function in Photoshop. (Most images I get are around 1-3 MB. I would like to get them down to around 150-500kb max)
I would like to automatically change the width to 760px, but keep the aspect ratio so the images are not squished. He sends me landscape and portrait images.
Beings they are iPhone images. They have an extension .JPG (all caps) I would like this to change to .jpg (all lower case.) This is not a deal breaker I would just like to know how to do this for future use.
Either one of these functions would be very helpful, but all 3 would be ideal for my situation.
Here is the code I'm working with?
THIS IS THE FINAL CORRECT CODE FOR UPLOADING AND RESIZING IMAGES PROVIDED By #tman
Make sure you have imagick installed in your php.ini file. Check with your hosting provider to install it.
<?php
include($_SERVER['DOCUMENT_ROOT'] . "/connections/dbconnect.php");
for($i=0;$i<count($_FILES["image"]["name"]);$i++){
if($_FILES["image"]["name"][$i] != ''){ // don't insert if file name empty
$dataType = mysql_real_escape_string($_POST["dataType"][$i]);
$title = mysql_real_escape_string($_POST["title"][$i]);
$fileData = pathinfo($_FILES["image"]["name"][$i]);
$fileName = uniqid() . '.' . $fileData['extension'];
$target_path = $_SERVER['DOCUMENT_ROOT'] . "/images/gallery/" . $fileName;
if (move_uploaded_file($_FILES["image"]["tmp_name"][$i], $target_path)){ // The file is in the images/gallery folder.
// Insert record into database by executing the following query:
$sql="INSERT INTO images (data_type, title, file_name) "."VALUES('$dataType','$title','$fileName')";
$retval = mysql_query($sql);
///NEW
$size = getimagesize($target_path);
$width=$size[0];
$height=$size[1];
$newwidth = 760;
$newheight = $height*($newwidth/$width);
$pic = new Imagick($target_path);//specify name
$pic->resizeImage($newwidth,$newhight,Imagick::FILTER_LANCZOS,1);
unlink($target_path);
$pic->writeImage($target_path);
$pic->destroy();
///NEW
echo "The image {$_FILES['image']['name'][$i]} was successfully uploaded and added to the gallery<br />
<a href='index.php'>Add another image</a><br />";
}
else
{
echo "There was an error uploading the file {$_FILES['image']['name'][$i]}, please try again!<br />";
}
}
} // close your foreach
?>
uploader.php Original code. Allows me to upload 4 images at once. WORKS!!!
<?php
include($_SERVER['DOCUMENT_ROOT'] . "/connections/dbconnect.php");
for($i=0;$i<count($_FILES["image"]["name"]);$i++){
if($_FILES["image"]["name"][$i] != ''){ // don't insert if file name empty
$dataType = mysql_real_escape_string($_POST["dataType"][$i]);
$title = mysql_real_escape_string($_POST["title"][$i]);
$fileData = pathinfo($_FILES["image"]["name"][$i]);
$fileName = uniqid() . '.' . $fileData['extension'];
$target_path = $_SERVER['DOCUMENT_ROOT'] . "/images/gallery/" . $fileName;
if (move_uploaded_file($_FILES["image"]["tmp_name"][$i], $target_path)){ // The file is in the images/gallery folder.
// Insert record into database by executing the following query:
$sql="INSERT INTO images (data_type, title, file_name) "."VALUES('$dataType','$title','$fileName')";
$retval = mysql_query($sql);
echo "The image {$_FILES['image']['name'][$i]} was successfully uploaded and added to the gallery<br />
<a href='index.php'>Add another image</a><br />";
}
else
{
echo "There was an error uploading the file {$_FILES['image']['name'][$i]}, please try again!<br />";
}
}
} // close your foreach
?>
FYI, This will allow you to give a unique names to your images, resize the width, but keep the correct aspect ratio and upload multiple file at the same time.
Awesome Stuff!
Like this:
$filelocation='http://help.com/images/help.jpg';
$newfilelocation='http://help.com/images/help1.jpg';
$size = getimagesize($filelocation);
$width=$size[0];//might need to be ['1'] im tired .. :)
$height=$size[1];
// Plz note im not sure of units pixles? & i could have the width and height confused
//just had some knee surgery so im kinda loopy :)
$newwidth = 760;
$newheight = $height*($newwidth/$width)
$pic = new Imagick( $filelocation);//specify name
$pic->resizeImage($newwidth,$newhight,Imagick::FILTER_LANCZOS,1);
//again might have width and heing confused
$pic->writeImage($newfilelocation);//output name
$pic->destroy();
unlink($filelocation);//deletes image
Here is something kind of similar, lets check the size and compress if the image seems that it is too big. I didn't resize it which just requires that you get the dimensions and resize based on desire.
All this is doing is if the file is greater than 250KB compress it to 85% ..
$bytes = filesize($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName);
//$maxSizeInBytes = 26400; //is 250KB? No? compress it.
if ($bytes > 26400) {
$img = new Imagick($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName);
$img->setImageCompression(imagick::COMPRESSION_JPEG);
$img->stripImage();
$img->setImageCompressionQuality(85);
$img->writeImage($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName);
}
OR:
// resize with imagejpeg ($image, $destination, $quality); if greater than byte size KB
// Assume only supported file formats on website are jpg,jpeg,png, and gif. (any others will not be compressed)
$bytes = filesize($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName);
//$maxSizeInBytes = 26400; //is gtr than 250KB? No? compress it.
if ($bytes > 26400) {
$info = getimagesize($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName);
$quality = 85; //(1-100), 85-92 produces 75% quality
if ($info['mime'] == 'image/jpeg') {
$image = imagecreatefromjpeg($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName);
imagejpeg($image,$inventory_path.DIRECTORY_SEPARATOR.$this->uploadName,$quality);
} elseif ($info['mime'] == 'image/gif') {
$image = imagecreatefromgif($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName);
imagejpeg($image,$inventory_path.DIRECTORY_SEPARATOR.$this->uploadName,$quality);
} elseif ($info['mime'] == 'image/png') {
$image = imagecreatefrompng($inventory_path.DIRECTORY_SEPARATOR.$this->uploadName
imagejpeg($image,$inventory_path.DIRECTORY_SEPARATOR.$this->uploadName,$quality);
}
}

PHP uploading seems to default to 72 dpi, I need 300 dpi

I have a page while is used only for print, and some of the images on there are uploaded through a script I have. It seems to always reduce the image to 72 dpi, reguardless of what I set imagejpeg() and imagepng() to for quality.
I've used my own personal script and this one on git hub
https://github.com/maxim/smart_resize_image
I was hoping for a little guidance on preserving the dpi at the original 300dpi.
Here is my own personal script
if (!empty($_FILES['image']['name'])) //checking if file upload box contains a value
{
$saveDirectory = 'pics/'; //name of folder to upload to
$tempName = $_FILES['image']['tmp_name']; //getting the temp name on server
$fileName1 = $_FILES['image']['name']; //getting file name on users computer
$count = 1;
do{
$location = $saveDirectory . $_GET['section'] . $count . $fileName1;
$count++;
}while(is_file($location));
if (move_uploaded_file($tempName, $location)) //Moves the temp file on server
{ //to directory with real name
$image = $location;
// Get new sizes
list($width, $height, $type) = getimagesize($image); //gets information about new server image
$framewidth = 932;
$frameheight = 354;
$realwidth = $width; //setting original width and height
$realheight = $height;
// Load
$file1new = imagecreatetruecolor($framewidth, $frameheight); //creates all black image with target w/h
if($type == 2){
$source = imagecreatefromjpeg($image);
imagecopyresampled($file1new, $source , 0, 0, 0, 0, $framewidth, $frameheight, $realwidth, $realheight);
}
elseif($type == 3){
$source = imagecreatefrompng($image);
imagecopyresampled($file1new, $source , 0, 0, 0, 0, $framewidth, $frameheight, $realwidth, $realheight);
}
else{
echo "Wrong file type";
}
if($type == 2){
//creates jpeg image from file1new for file1 (also retains quality)
imagejpeg($file1new, $image,100);
//frees space
imagedestroy($file1new);
}
elseif($type == 3){
//creates png image from file1new for file1 (also retains quality)
imagepng($file1new, $image,10);
//frees space
imagedestroy($file1new);
}
else{
echo "Wrong file type";
}
}
else
{
echo '<h1> There was an error while uploading the file.</h1>';
}
}
}
Edit: Even if dpi isn't the answer, as I see jpgs in specific don't retain that information. I need some way of keeping these images very clear and crisp.
If you generate image and open with a browser, the browser will reduce it to 72dpi before rendering.
If you open with gimp/phptoshop/whatever image editor , it should preserve the same dpi quality.
Though on a screen, there is no difference since your screen is 72 dpi.
Not tested on new browsers, but it was like this in netscape and first firefox versions, I assume it has not changed since.
The function posted by lorezyra (at) lorezyra (dot) com here: http://www.php.net/manual/es/function.imagejpeg.php#85712 might do the trick.

PHP check IF non-empty, non-zero

I get the width and height of image with getimagesize function, like below:
list($width,$height) = getimagesize($source_pic);
How can I use IF condition to check that the getimagesize function executed without error and $width and $height got non-empty, non-zero values?
if ($size = getimagesize($source_pic)) {
list($width,$height) = $size;
if($height > 0 && $width > 0) {
// do stuff
}
}
if ($width === NULL) {
//handle error
}
If there's an error getimagesize returns FALSE, not an an array, so the list assignment will result in the variables being NULL.
This should be enough:
list($width, $height) = getimagesize($source_pic);
if( $width>0 && $height>0 ){
// Valid image with known size
}
If it isn't a valid image, both $width and $height will be NULL. If it's a valid image but PHP could not determine its dimensions, they'll be 0.
A note from the manual:
Some formats may contain no image or
may contain multiple images. In these
cases, getimagesize() might not be
able to properly determine the image
size. getimagesize() will return zero
for width and height in these cases.
$size = getimagesize('image.jpg');
list($height,$width) = getimagesize('image.jpg');
if($height>0 && $width>0){
//it comes into if block if and only if both are not null
}

jQuery resize image before saving

I am new to jQuery but im loving it! ive have a problem i cant get round as of yet.
I am using http://www.zurb.com/playground/ajax_upload
which i have got working using the following upload.php
<?
$time= time();
$uploaddir = 'users/'; //<-- Changed this to my directory for storing images
$uploadfile = $uploaddir.$time.basename($_FILES['userfile']['name']); //<-- IMPORTANT
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
echo $uploaddir.$time.$_FILES['userfile']['name']; // IMPORTANT
#print_r($_FILES);
} else {
// WARNING! DO NOT USE "FALSE" STRING AS A RESPONSE!
// Otherwise onSubmit event will not be fired
echo "error";
}
?>
i have added the time variable to ensure each image is unique. The problem i have is i want to resize and optimise the image on the fly and i am not sure how to do this.
The resize is the most important featuer i require - for example i would like a max width of 300px for the image that is saved even if it was originally 1000px wide. I need to resize proportionaly ( is that a word? :) )
Any help will be great.
Regards
M
To resize images you need libs like GD
The standard function to do this is GD's imagecopyresampled.
In the example is shown one way to resize and keeping the proportion:
//> MAx
$width = 200;
$height = 200;
// 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;
}
There is two main image manipulation things in PHP, GD or Imagemagick. Both will be able to do what you need. You will need to configure them on your PHP webserver.

Categories