I have this source code where I got it from net tutsplus. I have configured it and made it work in one PHP file. It does work by transferring the original image, but it does not generate to the thumbnails folder.
<?php
$final_width_of_image = 100;
$path_to_image_directory = "../../img/events/" . urldecode($_GET['name']) . "/";
$path_to_thumbs_directory = "../../img/events/" . urldecode($_GET['name']) . "/thumbnails/";
function createThumbnail($filename)
{
if(preg_match('/[.](jpg)$/', $filename))
{
$im = imagecreatefromjpeg($path_to_image_directory . $filename);
}
elseif(preg_match('/[.](gif)$/', $filename))
{
$im = imagecreatefromgif($path_to_image_directory . $filename);
}
elseif(preg_match('/[.](png)$/', $filename))
{
$im = imagecreatefrompng($path_to_image_directory . $filename);
}
$ox = imagesx($im);
$oy = imagesy($im);
$nx = $final_width_of_image;
$ny = floor($oy * ($final_width_of_image / $ox));
$nm = imagecreatetruecolor($nx, $ny);
imagecopyresized($nm, $im, 0,0,0,0,$nx,$ny,$ox,$oy);
imagejpeg($nm, $path_to_thumbs_directory . $filename);
$tn = '<img src="' . $path_to_thumbs_directory . $filename . '" alt="image" />';
echo $tn;
}
if(isset($_FILES['fupload'])) {
if(preg_match('/[.](jpg)|(gif)|(png)$/', $_FILES['fupload']['name'])) {
$filename = $_FILES['fupload']['name'];
$source = $_FILES['fupload']['tmp_name'];
$target = $path_to_image_directory . $filename;
move_uploaded_file($source, $target);
createThumbnail($filename);
}
}
?>
Basically it is supposed to generate a thumbnail of the uploaded image and store the original image into a different folder.
The paths are correct, it works by getting the folder name in the URL, it does work, but nothing works for the thumbnails folder.
BEFORE you ask this related question, yes, thumbnails generation does work on my server by the PHP GD, I have tested it separately. So this is not the problem. :)
How do I get this to work? :(
Well, first off, use imagecopyresampled(), as it will generate a better thumbnail.
Secondly, you shouldn't use the same variable for filesystem directory and for url directory. You should have $filesystem_path_to_thumbs and $url_path_to_thumbs. So you can set them differently.
Third, you may want to do a size check for both width and height. What happens if someone uploads a tall image? Your thumbnail will be outside the target box (but this may not be a big issue).
Fourth, you should prob do a check to see if the thumbnail file exists in the thumbs directory before generating the thumbnail (for performance reasons)...
Finally, the reason it's actually failing, is $final_width_of_image, $path_to_image_directory and $path_to_thumbs_directory are not defined within the function. Either:
Make them global at the start of the function, so you can access them inside of the function global $final_width_of_image, $path_to_image_directory, $path_to_thumbs_directory;
Make them arguments to the function: function createTumbnail($image, $width, $path_to_images, $path_to_thumbs) {
Hard code them inside of the function (Move their declaration from outside the function to inside the function).
Personally, I'd do #2, but it's up to what your requirements and needs are...
Related
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());
So yesterday I tried to make an upload file function , for when user makes his products, he can also upload a picture too.
But the picture was too big when I was iterating through the items, so I decided to use intervention package to resize the picture and also create a thumbnail picture.
I made the function but its partially working.
if($file = $request->hasFile('image')) {
$file = $request->file('image');
$extension = $file->getClientOriginalName();
$username = Auth::user()->username;
$destinationPath = public_path('/uploads/products/' . $username);
$thumb = Image::make($file->getRealPath())->resize(100, 100, function ($constraint) {
$constraint->aspectRatio(); //maintain image ratio
});
$thumb->save($destinationPath.'/thumb_'.$extension);
$destinationPath = public_path('/uploads/products/' . $username);
$file->move($destinationPath, $extension);
$product['imagePath'] = '/uploads/products/'. $username . '/' . $extension;
$product['thumbnail'] = '/uploads/products/'. $username . '/thumb_' . $extension;
}
I made it so, different user will create a different file in /uploads/products.
Also I upload the original picture and the resized so the I should have like:
picture.jpg and thumb_picture.jpg.
When the custom file is not created (from the name of the user) I get this error:
Can't write image data to path
(C:\xampp\htdocs\shop\public/uploads/products/book/thumb_Jellyfish.jpg)
When I comment 6,7,8 lines, the function works but it uploads only the original picture as it supposed to. If I remove the comment, the thumbnail works too!
So I guess, after the custom folder has been created, the whole function works fine, but before it has a writable problem.
Any ideas? Everything will be appreciated!
For anyone wonder how to fix this or do something similar, I just found the solution:
if($file = $request->hasFile('image')) {
$file = $request->file('image');
$extension = $file->getClientOriginalName();
$username = Auth::user()->username;
$thumb = Image::make($file->getRealPath())->resize(100, 100, function ($constraint) {
$constraint->aspectRatio(); //maintain image ratio
});
$destinationPath = public_path('/uploads/products/' . $username);
$file->move($destinationPath, $extension);
$thumb->save($destinationPath.'/thumb_'.$extension);
$product['imagePath'] = '/uploads/products/'. $username . '/' . $extension;
$product['thumbnail'] = '/uploads/products/'. $username . '/thumb_' . $extension;
}
So this piece of code makes a dynamic folder (I chose the username of the authenticated user) inside /uploads/products/. In that folder it uploads the picture and also creates a resized one, for thumbnail use. Also, when it creates the thumbnail, it holds the ratio of the original picture so it doesn't lose proportions
I am working on an uploader and slowly getting it working, I am uploading 3 images at once, and setting arrays for each one as keys, with an increment of ++1. I am wanting to resize the image before it gets copied to the thumbnail folder.
I have this code.
Everything works with it.
As you see, I started on getting the file info, but after that I am totally stuck on what to do after to resize the image proportionally with a maximum width of xpx and height to match it without looking distorted.
Any help would be really appreciated. Thank You.
EDIT --- I started working on it myself and wondering if this is the right approach to what i am doing.
<?php
if (isset($_POST['addpart'])) {
$image = $_FILES['images']['tmp_name'];
$name = $_POST['username'];
$i = 0;
foreach ($image as $key) {
$fileData = pathinfo(basename($_FILES["images"]["name"][$i]));
$fileName[] = $name . '_' . uniqid() . '.' . $fileData['extension'];
move_uploaded_file($key, "image/" . end($fileName));
copy("image/" . end($fileName), "image_thumbnail/" . end($fileName));
// START -- THE RESIZER THAT IS BEING WORKED ON
$source = "image_thumb/" . end($fileName);
$dest = "image_thumb/" . end($fileName);
$quality = 100;
$scale = 1 / 2;
$imsize = getimagesize($source);
$x = $scale * $imsize[0];
$y = $scale * $imsize[1];
$im = imagecreatefromjpeg($source);
$newim = imagecreatetruecolor($x, $y);
imagecopyresampled($newim, $im, 0, 0, 0, 0, $x, $y, $imsize[0], $imsize[1]);
imagejpeg($newim, $dest, $quality);
// END -- THE RESIZER THAT IS BEING WORKED ON
$i++;
}
echo 'Uploaded<br>';
echo 'Main Image - ' . $fileName[0] . '<br>';
echo 'Extra Image 1 - ' . $fileName[1] . '<br>';
echo 'Extra Image 2 - ' . $fileName[2] . '<br>';
echo '<hr>';
}
?>
thanks
Use GD library.
Create input image object using imagecreatefromstring() for example: imagecreatefromstring(file_get_contents($_FILES['images']['tmp_name'][$i]))
It's the simplest way.
Another option is to detect file type and use functions like imagecreatefromjpeg (), imagecreatefrompng(), etc.
Create output empty image using imagecreate()
Use imagecopyresampled() or imagecopyresized() to resize image and copy+paste it from input image to output image
Save output image using function like imagejpeg()
Clean memory using imagedestroy()
The built-in image manipulation commands of PHP makes your code difficult to understand and to maintain. I suggest you to use a library which wraps it into a more productive way.
If you use Intervention/image, for example, your code will look like this:
<?php
// target file to manipulate
$filename = $_FILES['images']['tmp_name'];
// create image instance
$img = Image::make($filename);
// resize to width, height
$img->resize(320, 240);
// save it!
$img->save('thumbs/'. uniqid() . '.' . pathinfo($filename, PATHINFO_EXTENSION));
Read the full documentation here: http://image.intervention.io/use/uploads
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
I have a question on how to filter image while moving the file. I used uploadify to upload image. What I did is, before he move the image to the directory, the code filter will covert the image to grayscale.
Here is my code
if (!empty($_FILES)) {
$tempFile = $_FILES['Filedata']['tmp_name'];
$targetPath = $_SERVER['DOCUMENT_ROOT'] . $_REQUEST['folder'] . '/';
$targetFile = str_replace('//','/',$targetPath) . $_FILES['Filedata']['name'];
$newImg = imagefilter($tempFile, IMG_FILTER_GRAYSCALE); // This is what I insert
move_uploaded_file($newImg,$targetFile);
echo "1";
}
The code is uploadify.php and I just inserted a filter to make it grayscale. Please help me. Thanks in advance.
Imagefilter works on an image resource, not a file, and also a boolean, not a new image. It's probably worth reading through the documentation, but you'll need to change your code to something along these lines
if (!empty($_FILES)) {
$tempFile = $_FILES['Filedata']['tmp_name'];
$targetPath = $_SERVER['DOCUMENT_ROOT'] . $_REQUEST['folder'] . '/';
$targetFile = str_replace('//','/',$targetPath) . $_FILES['Filedata']['name'];
// Create an image resource - exact method will depend on the image type (PNG, JPEG, etc)
$im = imagecreatefrompng($tempFile);
// Apply your filter
imagefilter($im, IMG_FILTER_GRAYSCALE);
// Save your changes
imagepng($im, $tempFile);
move_uploaded_file($tempFile,$targetFile);
echo "1";
}
To use imagefilter you have to load image first. Use one of GD load functions ( like: imagecreatefrompng).
Then you can use filter on loaded image. By the way check parameters for imagefilter (which requires loaded image, not path to image). Here is some example code (that replaces your imagefilter()):
// Check extension of the file, here is example if the file is png, but you have to check for extension and use specified function
$img = imagecreatefrompng($tempFile);
if( imagefilter($img, IMG_FILTER_GRAYSCALE) )
{
// success
}
else
{
// failture
}
// Save file as png to $targetFile
imagepng($img, $targetFile);
// Destroy useless resource
imagedestroy($img);