Renaming the uploaded file using ImageMagick - php

In my current project I am using the plupload plugin with PHP and ImageMagick and its working fine - now my next task is too rename uploaded files in lowercase.
To rename these files I first store the uploaded image in a temporary folder with a ".temp" extension, than I move the file to a main folder and there I attempt to do a rename. The first time the function is executed, if there are no matching image then it will store it perfectly, but the second time through it doesn't work as well. The function should check for the existing file name and should store repeats with an incrementing index, i.e. as image_1.jpg, image_2.jpg, etc, but istead of doing that it just overwrites the image i.e. image.jpg.
Here is a snippet of my code:
$filename = $this->input->post('filename');
$root = $_SERVER["DOCUMENT_ROOT"]."/uploads/";
$source_image = $root.'temp/'.$filename;
$image_name = explode(".",$filename);
rename($source_image, $source_image. '.temp');
copy($source_image.'.temp', $root.$filename.'.temp');
unlink($source_image.'.temp');
$exp_temp_img_slash = explode(".",$filename);
$rename_img_a = strtolower($exp_temp_img_slash[0]);
$rename_img_b = $exp_temp_img_slash[1];
if (file_exists($root.$rename_img_a .".".$rename_img_b)) {
$count=1;
while (file_exists($root. $rename_img_a ."_".$count. ".".$rename_img_b)) {
$count++;
$rename_img = strtolower($rename_img_a . '_' . $count . ".".$rename_img_b);
}
$renamed_image = $_SERVER["DOCUMENT_ROOT"]."/uploads/".$rename_img;
rename($root.$filename.".temp",$renamed_image);
} else {
$rename_img = strtolower($rename_img_a .".".$rename_img_b);
$renamed_image = $_SERVER["DOCUMENT_ROOT"]."/uploads/".$rename_img;
rename($root.$filename.".temp",$renamed_image);
}
Any help will be appreciated, thanks.

shell_exec($imagemagick_folder."convert ".$from . $fileName." -resize ".$width."x".$height." -quality 95 ".$to.$fileName);
$imagemagick_folder is the folder where imagemagick is installed (ex. C:\imagemagick)
$from and $to are the the start and the destination folder
$width and $height are optional if you want to resize the image

Related

How to get Interventation/Image after Resize in Laravel

I used Interventation image to resize a big size uploaded image. But I don't want to save it into the local directory of Laravel. This is my sample source code.
public function Uploader(Request $request) {
$upload_file = $request->file_upload;
$new_img = Image::make($upload_file)->resize(800, 544);
$new_img->save(\public_path($fileName));
$upload_file_new = "../public/" . $fileName;
}
I want to get the new path of the resized image (by not by saving it). I used
$path = $new_img->basePath();
But it returns the basePath of the $upload_file. How can I get the new path so I can use it on fopen($upload_file_new, 'r'). Please help. Thank you.
you can do like this
$image_new_name = time() . str_random(10) . str_replace(' ','',$upload_file->getClientOriginalName());

Upload images with random name and also delete older image from the directory

I am trying to upload an image with a random name, also when I update the image, I want the previous image to be deleted.
Code below:
$banner=$_FILES ['banner']['name'];
$upload="../image/banner/";
$target_file = $upload.basename($_FILES["banner"]["name"]);
$imagefiletype= pathinfo($target_file,PATHINFO_EXTENSION);
move_uploaded_file($_FILES["banner"]["tmp_name"], $target_file );
Any help will be appreciated.
When update your new images at that time first store old image name in variable. after update true then delete old image in your directory using "unlink" function.
$old_image = "xyz" // store old image name
after update query success
unlink('../image/banner/'.$old_image); // delete old image in your directory
You can do it like this.
$path = 'image/folder/'; $unique_name=time().uniqid(rand());
$File_with_location = $path . $unique_name . '.' . strtolower(pathinfo($_FILES['img']['name'], PATHINFO_EXTENSION));
$filename = $_FILES["img"]["tmp_name"];
move_uploaded_file($filename, $File_with_location);
for deleting old image you can use this
$path = './root/home/folder/file.jpg';
if (unlink($path)) {
echo 'success';
} else {
echo 'fail';
}

Trying to resize uploaded files as they are saved to server

I am using Glide to deliver image content from one of my sites. This is working well and I have now built a file upload so that admins can upload images to the site for subsequent download.
Some of the images that admins will upload will be much larger than I need (or want the overhead of storing on the server), so I want to downsize them, preferably during the upload routine or failing that, just after they have been saved to their new location (storage/app/images)
So, I've been hacking around with intervention for instance without much success because of my poor understanding of the file names and paths available from getClientOriginalName/Extension etc.
Could anyone show me a pattern for this which would work well. Ideally I'd love to include something like I've seen on others' examples like...
$img = Image::make('foo.jpg')->resize(300, 200);
... in the correct place in my code
foreach($files as $file) {
$fileExtension = $file->getClientOriginalExtension();
$fileMimeType = $file->getMimeType();
if(in_array($fileExtension, $allowableExtensions)) {
if(in_array($fileMimeType, $allowableMimes)) {
array_push($dbFileList, $file->getClientOriginalName());
$newImage = '/images/' . $propertyCode . '/' . $file->getClientOriginalName();
Storage::put('/images/' . $propertyCode . '/' . $file->getClientOriginalName(), file_get_contents($file));
}else{
$errorMessage = 'At least one file was not an image, check your results...';
}
}else{
$errorMessage = 'At least one file was not an image, check your results...';
}
}
Update 1:
Storage::put('/images/' . $propertyCode . '/' . $file->getClientOriginalName(), file_get_contents($file));
$img = Image::make($file);
Storage::put('/images/new/' . $file->getClientOriginalName(), $img);
This updated code outputs the files to the /new directory and all looks fine, but the output files have 'zero bytes'. What am I missing?
Update 2: Final code
The final answer (after using the proper code provided by contributors) was that:
I had to move my app from virtual box on to the dev machine (iMac) to prevent extra confusion with paths
The path for the images must exist prior to making the ->save()
The path variable must be set in advance of the ->save()
I don't need the Storage::put at all, so the larger file never ends up on the server.
Then this final code started to work.
$path = storage_path('app/smallpics/')."/".$file->getClientOriginalName();
$img = Image::make($file)->resize(300,200)->save($path);
Much thanks to all of you. You make my Laravel learning curve a bit less terrifiying!!
You can use Intervention to manipulate your image (resize etc.) as
$new_image = Image::make($file)->resize(300,200)->save('/path/to/save');
The image upload and resize work flow is like:
Upload the image from tmp to your directory.
Make a copy of that image by setting the height, width, quality and save it in the same or some other directory.
Delete the original image.
So as per your code flow:
Storage::put('/images/' . $propertyCode . '/' . $file->getClientOriginalName(), file_get_contents($file));
after this code, put the image compress code and after that delete the original image.
you can use Intervention or just use imagemagick convert command line command for resize or convert.
Pay attention to comments :
public function saveUploadPic(Request $request)
{
$pic = $request->file('<NAME_OF_FILE_INPUT_IN_HTML_FORM>');
#check for upload correctly
if(!$pic->isValid())
{
throw new Exception("IMAGE NOT UPLOADED CORRECTLY");
}
#check for mime type and extention
$ext = $pic->getClientOriginalExtension();
$mime = $pic->getMimeType();
if(!in_array($mime, $allowedMimeTypeArray) || !in_array($ext, $allowedExtArray))
{
throw new Exception("This Image Not Support");
}
#check for size
$size = $pic->getClientSize() / 1024 / 1024;
if($size > $allowedSize)
{
throw new Exception("Size Of Image Is More Than Support Size");
}
########################YOU HAVE TWO OPTION HERE###################
#1- save image in a temporary location with random hash for name if u need orginal image for other process
#below code save image in <LARAVEL_APP_PATH>/storage/app/tmp/pics/
$hash = md5(date("YmdHis").rand(1,10000));
$pic->storeAs('tmp/pics', $hash.'.'.$ext);
#Then resize or convert it
$img = Image::make(storage_path('app/tmp/pics/'.$hash.'.'.$ext))->resize(300, 200);
#save new image whatever u want
$img->save('<PATH_TO_SAVE_IMAGE>');
#after u finish with orginal image delete it
Storage::delete(storage_path('app/tmp/pics/'.$hash.'.'.$ext);
#2- Or just use below for resize and save image witout need to save in temporary location
$img = Image::make($pic->getRealPath())->resize(300,200);
$img->save('<PATH_TO_SAVE_IMAGE>');
}
if you want to use convert see this link.

Create a unique name for the uploaded image

I have a certain code for image upload .I found this on the internet and there was no explanation of the code either.What i can understand from the code is that php upload a certain file makes it a temporary file and then moves the temporary file to the original location
Code Looks something like this
$filename = $_FILES["img"]["tmp_name"];
list($width, $height) = getimagesize( $filename );
move_uploaded_file($filename, $imagePath . $_FILES["img"]["name"]);
What happens now is that when i try to provide an unique name to the image when it is being moved using the move_uploaded_file then a file does come up inside the folder but it says an invalid file and with the extension type of file.
My code for trying to achieve the same but with an unique name/id for the uploaded image.
$uniquesavename=time().uniqid(rand());
$filename = $_FILES["img"]["tmp_name"];
list($width, $height) = getimagesize( $filename );
move_uploaded_file($filename, $imagePath . $uniquesavename);
How to achieve the same as before and could you please explain me the previous code as well?
Sample code:
// Get file path from post data by using $_FILES
$filename = $_FILES["img"]["tmp_name"];
// Make sure that it's a valid image which can get width and height
list($width, $height) = getimagesize( $filename );
// Call php function move_uploaded_file to move uploaded file
move_uploaded_file($filename, $imagePath . $_FILES["img"]["name"]);
Please try this one:
// Make sure this imagePath is end with slash
$imagePath = '/root/path/to/image/folder/';
$uniquesavename=time().uniqid(rand());
$destFile = $imagePath . $uniquesavename . '.jpg';
$filename = $_FILES["img"]["tmp_name"];
list($width, $height) = getimagesize( $filename );
move_uploaded_file($filename, $destFile);
Edit 1:
To get image type in two ways:
Get the file type from upload file name.
Use php function as below
CODE
// Get details of image
list($width, $height, $typeCode) = getimagesize($filename);
$imageType = ($typeCode == 1 ? "gif" : ($typeCode == 2 ? "jpeg" : ($typeCode == 3 ? "png" : FALSE)));
$name = $_FILES['file']['name'];
$tmp_name = $_FILES['file']['tmp_name'];
$location = "uploads/";
$new_name = $location.time()."-".rand(1000, 9999)."-".$name;
if (move_uploaded_file($tmp_name, $new_name)){
echo "uploaded";
}
else{
sleep(rand(1,5));
$new_name = $location.time()."-".rand(1000, 9999)."-".$name;
if (move_uploaded_file($tmp_name, $new_name)){
echo "uploaded";
}
else{
echo"failed, better luck next time";
}
}
here, location is folder inside directory, i mainly create folder "uploads"
time() adds timestamp , which is always unique, until two person upload at same time, which is rare.
moreover, adding 4 digit random number to it , making combination rarest
after that adding actual file name , to making combination unique.
why i use it :
u can extract timestamp later if u need to know when image was uploaded.
u can extract actual filename too.
Lets, say our so unique combination somehow fails,
then, php instance will wait for 1 to 5 second whatever random number is generated. and rename with latest timestamp and regenerated random number.
It's the best u can think of without being resource hog.
you can use
$strtotime = strtotime("now");
$filename = $strtotime.'_'.$_FILES['file']['name'];

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);
}
}

Categories