resize multiple images while uploading - php

Hi im trying to resize multiple image while uploading i have the function that resize but its only work for one image so please can anyone shom me how to loop this for multiple file upload
if( $_FILES['image']['size']< $max_file_size ){
// get file extension
$ext = strtolower(pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION));
// $ext = pathinfo($_FILES['files']['name'][$f], PATHINFO_EXTENSION);
if (in_array($ext, $valid_exts)) {
/* resize image */
foreach ($sizes as $w => $h) {
$files[] = resize($w, $h);
}
} else {
$msg = 'Unsupported file';
}
} else{
$msg = 'Please upload image smaller than 200KB';
}

This is untested, but might give you an idea.
The way this works is by looping through all of the $_FILES of the variable $iname which is 'image'. I set this since it's used multiple times, so if you ever change it, its easier.
I create a new variable called $image which will be the variables for that specific image. I do this by looping through all of the variables of $_FILES[$iname]. I set the $image variable to the $key and the new value, which will be an array. We reference the correct array using the $i variable.
Next I simply use your existing code. Since the resize() function only calls for width and height, I am unsure what happens here. Another parameter should be passed to reference the image you want to resize, which will be $image.
From the visible code I typed, not knowing what resize() is, this code is insecure. You should really check more than just the file extension since it can easily be changed. I usually use exif to check the image header. I also never store the data users upload unless I re-encode it using a GDI function in PHP.
Hopefully this will get you started.
$i = 0;
$iname = 'image';
for($i = 0; $i < count($_FILES[$iname]['size']); $i++) {
// Create new Image Array
$image = array();
foreach($_FILES[$iname] as $key => $val) {
$image[$key] = $val[$i];
}
if( $image['size'] < $max_file_size ) {
$ext = strtolower(pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION));
if (in_array($ext, $valid_exts)) {
foreach ($sizes as $w => $h) {
// How is resize getting the $_FILES?
// Should pass a variable of $image and use it instead
$files[] = resize($w, $h);
}
} else {
$msg = 'Unsupported file';
}
} else{
$msg = 'Please upload image smaller than 200KB';
}
}

Related

how to prevent imagecreatefrom from creating a static gif - PHP

I have a script that sends an image it is saved as a .gif as declared in the movie.php file that will be listed below.
However, as I understand it, it creates an image from the gif making it useless for display because it simply becomes a static image .gif.
Anyway
I wanted to know how I can upload this file and ignore this function (imagecreatefromgif) I tried to change it in several ways and when I remove it I get an error, someone could help me work around this so that the gif will be sent and not be converted to a gif file static. basically I wanted that the way I sent the gif it would only be renamed with function imageGenerateName () but that it would keep all its size and property.
Every help is welcome.
Thanks in advance
.
Movie.php code:
<?php
class Movie {
public function imageGenerateName() {
return bin2hex(random_bytes(60)) . ".gif";
}
}
movie-process.php code
<?php
// Upload img
if(isset($_FILES["image"]) && !empty($_FILES["image"]["tmp_name"])) {
$image = $_FILES["image"];
$imageTypes = ["image/gif"];
$jpgArray = ["image/gif"];
// Check img type
if(in_array($image["type"], $imageTypes)) {
// Check img type
if(in_array($image["type"], $jpgArray)) {
$imageFile = imagecreatefromgif($image["tmp_name"]);
} else {
$imageFile = imagecreatefromgif($image["tmp_name"]);
}
// image name
$imageName = $movie->imageGenerateName();
imagegif($imageFile, "./img/movies/" . $imageName, 100);
$movie->image = $imageName;
}
}
// Upload img
if(isset($_FILES["image"]) && !empty($_FILES["image"]["tmp_name"])) {
$image = $_FILES["image"];
$imageTypes = ["image/gif"];
$jpgArray = ["image/gif"];
// Check img type
if(in_array($image["type"], $imageTypes)) {
// check type is gif
if(in_array($image["type"], $jpgArray)) {
$imageFile = imagecreatefromgif($image["tmp_name"]);
}
// generete img name
$movie = new Movie();
$imageName = $movie->imageGenerateName();
imagegif($imageFile, "./img/movies/" . $imageName, 100);
$movieData->image = $imageName;
}
}
Unfortunately, the imagecreatefromgif function will only read the first image of the gif as the PHP manual says.
I tried before to solve this, but there is no turnaround other than uploading the image without touching it. PHP uses the GD library and this library doesn't have the proper functionality to deal with gif images other than just saving the image with the *.gif extension.
So, this is my suggested solution:
// generete img name
$movie = new Movie();
$imageName = $movie->imageGenerateName();
move_uploaded_file($_FILES["image"]["tmp_name"],"./img/movies/" . $imageName);
$movieData->image = $imageName;
I think since you say you just want to save it as it is, with the same size and its all properties, you can use below code
<?php
$allowed = array('gif');
$filename = $_FILES["image"]['name'];
$ext = pathinfo($filename, PATHINFO_EXTENSION);
if (in_array($ext, $allowed)) {
// generete img name
$movie = new Movie();
$imageName = $movie->imageGenerateName();
$uploadResult = move_uploaded_file($_FILES['image']['tmp_name'], dirname( dirname( __FILE__ ) ).'/img/movies/'. $imageName );
if($uploadResult === true ){
$movie->image = $imageName;
}else{
throw new \Exception('Unable to copy file to the given path');
}
}
Or if you have access to the Imagick lib php extension refer to below link on how to install this php-extension
https://www.php.net/manual/en/imagick.setup.php
then using the functions in that library you can do
<?php
$allowed = array('gif');
$filename = $_FILES["image"]['name'];
$ext = pathinfo($filename, PATHINFO_EXTENSION);
if (in_array($ext, $allowed)) {
$image = new Imagick();
$image->readImage($_FILES["image"]["tmp_name"]);
$image = $image->coalesceImages();
foreach ($image as $frame) {
$frame->cropImage($crop_w, $crop_h, $crop_x, $crop_y);
$frame->thumbnailImage($size_w, $size_h);
$frame->setImagePage($size_w, $size_h, 0, 0);
}
$image = $image->deconstructImages();
$image->writeImages(dirname( dirname( __FILE__ ) ).'/img/movies/'. $imageName, true);
}
?>

Issue when uploading image to tmp folder, resize and then upload to S3 bucket

I've spend all day figuring out how to store an image in tmp, change its size and then upload it to my S3 bucket. The S3 bucket works fine and i am able to upload images when i don't resize. The resize function is the createThumbnail function and works fine when not combined with S3 probably because it's a wrong format or something. The second file "init.php" contains all the functions. The images are uploaded to the temp folder but when i run the script it doesn't get uploaded after it's resized. I don't get any error logs on localhost and when i upload the code to my AWS instance it just returns a internal server error but the error log in my instance is oddly empty... I need some fresh eyes on this issue.
banner_image.php
<?php
include "init.php";
if (#session($_SESSION["buddy"])){
$valid_file_formats = array("jpg","png","jpeg");
if(isset($_POST) and $_SERVER['REQUEST_METHOD'] == "POST" && !empty($_FILES['banner_image']['tmp_name']) && !empty($_FILES['banner_image']['name'])){
$folder = usernameFromEmail($_SESSION["user"]); // session based on users email
$buddy = $_SESSION["user"];
$name = $_FILES['banner_image']['name'];
$size = $_FILES['banner_image']['size'];
$path = $folder."/cover/"; // path to image folder
$temp = explode(".", $name);
$newfilenameKey = round(microtime(true)); // generating random file name
$newfilename = $newfilenameKey . "." . "png"; // always using png
if(strlen($newfilename) && strlen($name)) {
$ext = explode(".", $name);
$ext = end($ext);
if(in_array($ext,$valid_file_formats)) { // valid file format array check
if($size<=(10485760)) { // size check in bits
$tmp = $_FILES['banner_image']['tmp_name'];
$file_name = $path.$newfilename; // full path including file name
if(putS3IMG($bucket, $file_name, $tmp)){ // upload untouched image to S3 bucket
list($width, $height) = getimagesize($tmp);
$type = 2;
$w = 300;
$h = 300 * ($height / $width);
// getting new dimensions for the new image
if(createThumbnail(1,$tmp,$w,$h,$path,$file_name) == 1){ // function for smaller image
return json_encode(array("succ" => 1));
}
}
}
}
}
}
}
?>
here is my init.php file included in the banner_image.php file which contains my functions.
<?php
// connection to S3Client .... $client
function createThumbnail($type,$image_name,$new_width,$new_height,$uploadDir,$moveToDir){
global $bucket;
//$type: defines the name of the new file
//image_name: tmp name
//uploadDir: path
//moveToDir: files new path incl. file name
$mime = getimagesize($image_name);
if($mime['mime']=='image/png') {
$src_img = imagecreatefrompng($image_name);
} else if($mime['mime']=='image/jpg' || $mime['mime']=='image/jpeg' || $mime['mime']=='image/pjpeg') {
$src_img = imagecreatefromjpeg($image_name);
}
$old_x = imageSX($src_img);
$old_y = imageSY($src_img);
$thumb_w = $new_width;
$thumb_h = $new_height;
$dst_img = ImageCreateTrueColor($thumb_w,$thumb_h);
$background = imagecolorallocate($dst_img, 0, 0, 0);
imagecolortransparent($dst_img, $background);
imagealphablending($dst_img, false);
imagesavealpha($dst_img, true);
imagecopyresampled($dst_img,$src_img,0,0,0,0,$thumb_w,$thumb_h,$old_x,$old_y);
$image_name_new = explode(".", $moveToDir);
if ($type == 1){
$new_image_name = $image_name_new[0] . "_thumb." . $image_name_new[1];
} else if ($type == 2){
$new_image_name = $image_name_new[0] . "_image." . $image_name_new[1];
}
$tmpPath = tempnam(sys_get_temp_dir(), $new_image_name); // getting temporary directory
if($mime['mime']=='image/png') {
imagepng($dst_img,$tmpPath,8);
} else if($mime['mime']=='image/jpg' || $mime['mime']=='image/jpeg' || $mime['mime']=='image/pjpeg') {
imagejpeg($dst_img,$tmpPath,80);
}
imagedestroy($dst_img);
imagedestroy($src_img);
if(putS3IMG($bucket, $image_name, $tmpPath)){ // this part does not work
return 1;
} else {
return 2;
}
}
function putS3IMG($bucket, $file_name, $tmp){ // function uploading to my bucket
//file_name is with directories
//tmp is $_FILES tmp_name
global $client;
$result = $client->putObject([
'Bucket' => $bucket,
'Key' => $file_name,
'SourceFile' => $tmp
]);
if ($result){
return true;
}
return false;
}
SOLUTION:okay, so eventually i ended up using AWS lambda which solved the issue but it isn't a free solution. So, if any of you come up with a solution that allow you to resize without using third party tools feel free to comment it in order to make life easier for the next programmers viewing this question.

Compress and RESCALE uploaded image

I have a function that uploads files up to 8MB but now I also want to compress or at least rescale larger images, so my output image won't be any bigger than 100-200 KB and 1000x1000px resolution. How can I implement compress and rescale (proportional) in my function?
function uploadFile($file, $file_restrictions = '', $user_id, $sub_folder = '') {
global $path_app;
$new_file_name = generateRandomString(20);
if($sub_folder != '') {
if(!file_exists('media/'.$user_id.'/'.$sub_folder.'/')) {
mkdir('media/'.$user_id.'/'.$sub_folder, 0777);
}
$sub_folder = $sub_folder.'/';
}
else {
$sub_folder = '';
}
$uploadDir = 'media/'.$user_id.'/'.$sub_folder;
$uploadDirO = 'media/'.$user_id.'/'.$sub_folder;
$finalDir = $path_app.'/media/'.$user_id.'/'.$sub_folder;
$fileExt = explode(".", basename($file['name']));
$uploadExt = $fileExt[count($fileExt) - 1];
$uploadName = $new_file_name.'_cache.'.$uploadExt;
$uploadDir = $uploadDir.$uploadName;
$restriction_ok = true;
if(!empty($file_restrictions)) {
if(strpos($file_restrictions, $uploadExt) === false) {
$restriction_ok = false;
}
}
if($restriction_ok == false) {
return '';
}
else {
if(move_uploaded_file($file['tmp_name'], $uploadDir)) {
$image_info = getimagesize($uploadDir);
$image_width = $image_info[0];
$image_height = $image_info[1];
if($file['size'] > 8000000) {
unlink($uploadDir);
return '';
}
else {
$finalUploadName = $new_file_name.'.'.$uploadExt;
rename($uploadDirO.$uploadName, $uploadDirO.$finalUploadName);
return $finalDir.$finalUploadName;
}
}
else {
return '';
}
}
}
For the rescaling I use a function like this:
function dimensions($width,$height,$maxWidth,$maxHeight)
// given maximum dimensions this tries to fill that as best as possible
{
// get new sizes
if ($width > $maxWidth) {
$height = Round($maxWidth*$height/$width);
$width = $maxWidth;
}
if ($height > $maxHeight) {
$width = Round($maxHeight*$width/$height);
$height = $maxHeight;
}
// return array with new size
return array('width' => $width,'height' => $height);
}
The compression is done by a PHP function:
// set limits
$maxWidth = 1000;
$maxHeight = 1000;
// read source
$source = imagecreatefromjpeg($originalImageFile);
// get the possible dimensions of destination and extract
$dims = dimensions(imagesx($source),imagesy($source),$maxWidth,$maxHeight);
// prepare destination
$dest = imagecreatetruecolor($dims['width'],$dims['height']);
// copy in high-quality
imagecopyresampled($dest,$source,0,0,0,0,
$width,$height,imagesx($source),imagesy($source));
// save file
imagejpeg($dest,$destinationImageFile,85);
// clear both copies from memory
imagedestroy($source);
imagedestroy($dest);
You will have to supply $originalImageFile and $destinationImageFile. This stuff comes from a class I use, so I edited it quite a lot, but the basic functionality is there. I left out any error checking, so you still need to add that. Note that the 85 in imagejpeg() denotes the amount of compression.
you can use a simple one line solution through imagemagic library the command will like this
$image="path to image";
$res="option to resize"; i.e 25% small , 50% small or anything else
exec("convert ".$image." -resize ".$res." ".$image);
with this you can rotate resize and many other image customization
Take a look on imagecopyresampled(), There is also a example that how to implement it, For compression take a look on imagejpeg() the third parameter helps to set quality of the image, 100 means (best quality, biggest file) and if you skip the last option then default quality is 75 which is good and compress it.

Check current image being displayed on page

I currently have this code:
$img_dir = 'tsimgs/';
$images = array();
$files = scandir($img_dir);
foreach($files as $f) {
$extension = end(explode('.',$f));
if($extension == 'jpg') {
$images[] = $f;
}
elseif($extension == 'png') {
$images[] = $f;
}
}
$random = array_rand($images);
$chosen = $images[$random];
if(end(explode('.',$chosen)) == 'jpg') {
$image = imagecreatefromjpeg($img_dir.$chosen);
}
elseif(end(explode('.',$chosen)) == 'png') {
$image = imagecreatefrompng($img_dir.$chosen);
}
// WRITE OUT THE IMAGE //
header('Content-type: image/jpeg');
imagejpeg($image, NULL, 100);
imagedestroy($image);
Basically this displays a random image on webpage visit. How would I make a script to check which image is currently being displayed to the user. Is that even possible?
This might not be a perfect solution, but if you are already using sessions you could set a session variable when selecting the image to show to the user, and then fetch it when you want to know which image is being displayed.
You have to remember though, that if the user has multiple windows open there is no guarantee that this works.

PHP: Making thumbnail, why do i get these errors?

When i made this function:
function makeThumbnail($type, $name, $size, $tmp_name, $thumbSize) {
//make sure this directory is writable!
$path_thumbs = "uploaded_files/";
//the new width of the resized image, in pixels.
$img_thumb_width = $thumbSize; //
$extlimit = "yes"; //Limit allowed extensions? (no for all extensions allowed)
//List of allowed extensions if extlimit = yes
$limitedext = array(".gif",".jpg",".png",".jpeg",".bmp");
//the image -> variables
$file_type = $type;
$file_name = $name;
$file_size = $size;
$file_tmp = $tmp_name;
//check if you have selected a file.
echo $file_tmp."<br>";
echo $file_name."<br>";
echo $file_type."<br>";
echo $file_size."<br>";
if(!is_uploaded_file($file_tmp)){
echo "Error: Please select a file to upload!. <br>--back";
exit(); //exit the script and don't process the rest of it!
}
//check the file's extension
$ext = strrchr($file_name,'.');
$ext = strtolower($ext);
//uh-oh! the file extension is not allowed!
if (($extlimit == "yes") && (!in_array($ext,$limitedext))) {
echo "Wrong file extension. <br>--back";
exit();
}
//so, whats the file's extension?
$getExt = explode ('.', $file_name);
$file_ext = $getExt[count($getExt)-1];
//create a random file name
$rand_name = md5(time());
$rand_name= rand(0,999999999);
//the new width variable
$ThumbWidth = $img_thumb_width;
/////////////////////////////////
// CREATE THE THUMBNAIL //
////////////////////////////////
//keep image type
if($file_size){
if($file_type == "image/pjpeg" || $file_type == "image/jpeg"){
$new_img = imagecreatefromjpeg($file_tmp);
}elseif($file_type == "image/x-png" || $file_type == "image/png"){
$new_img = imagecreatefrompng($file_tmp);
}elseif($file_type == "image/gif"){
$new_img = imagecreatefromgif($file_tmp);
}
//list the width and height and keep the height ratio.
list($width, $height) = getimagesize($file_tmp);
//calculate the image ratio
$imgratio=$width/$height;
if ($imgratio>1){
$newwidth = $ThumbWidth;
$newheight = $ThumbWidth/$imgratio;
}else{
$newheight = $ThumbWidth;
$newwidth = $ThumbWidth*$imgratio;
}
//function for resize image.
if (function_exists(imagecreatetruecolor)){
$resized_img = imagecreatetruecolor($newwidth,$newheight);
}else{
die("Error: Please make sure you have GD library ver 2+");
}
//the resizing is going on here!
imagecopyresampled($resized_img, $new_img, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
//finally, save the image
ImageJpeg ($resized_img,"$path_thumbs/$rand_name.$file_ext", 100);
ImageDestroy ($resized_img);
ImageDestroy ($new_img);
}
//ok copy the finished file to the thumbnail directory
// move_uploaded_file ($file_tmp, "$path_big/$rand_name.$file_ext");
/*
Don't want to copy it to a separate directory?
Want to just display the image to the user?
Follow the following steps:
2. Uncomment this code:
/*
/* UNCOMMENT THIS IF YOU WANT */
echo "OK THUMB " . $thumbSize;
exit();
//*/
//and you should be set!
//success message, redirect to main page.
$msg = urlencode("$title was uploaded! Upload More?");
}
Then it stopped working, but outside a function, it works good.
As you can see i added "echo $file...." because i wanted to see if they have value, and they do have the right values.
I just get the error Error: Please select a file to upload.
This function is running after an normal upload image script(full size).
When i call the function i do:
makeThumbnail($_FILES[$fieldname]['type'], $_FILES[$fieldname]['name'], $_FILES[$fieldname]['size'], $_FILES[$fieldname]['tmp_name'], 100);
At my other file where its not in a function, theres no difference only that the variables is:
$file_type = $_FILES['file']['type'];
$file_name = $_FILES['file']['name'];
$file_size = $_FILES['file']['size'];
$file_tmp = $_FILES['file']['tmp_name'];
But it should work, I cant find anything wrong, but it doesnt and i keep getting that error. If i remove the is_uploaded_file function, i get a bunch of another errors.
Make sure you are not using move_uploaded_file() before calling the function.
I use timthumb to process the image into a thumbnail when it outputs it to screen, instead of when it's uploaded.
It means you only have one file and not one master size and one thumb size. TimThumb reduces the size of the file on serverside so it appears nice and smooth on the browserside. Have a look at it: TimThumb Link

Categories