I'm using amazon s3 to store my images. For now I've got 3 different folders - temporary one to not accepted pictures, one for accepted and one for watermarked one.
When photo is being accepted it is copied to accepted and watermarked folders and deleted form temporary one.
The problem is with watermarked folder because I need to add watermark. During work in progress I've mocked method that is adding watermark like this:
protected function addWatermark($product)
{
$filterName = 'watermark';
$this->imagineFilterManager->getFilter($filterName)
->apply($this->imagine->open($product->getFilePath()))
->save($path, array('format' => "png"));
}
and it was pretty fine. But the problem is - mock was working on uploaded file, and FilePath was temporary file path to image.
Now I need to retrieve image from amazon s3, pass it to imagineFilterManager and save back at amazon s3 location. The problem is with retrieving photo.
I tried like this:
read method:
public function read($path)
{
return $this->fileSystem->read($path);
}
protected function addWatermark($product)
{
var_dump('addWatermark');
$filterName = 'watermark';
$path = $this->getShopPicturePath($product);
$file = $this->staticContentAdapter->read($path);
$file = imagecreatefromstring($file);
$this->imagineFilterManager->getFilter($filterName)
->apply($this->imagine->open($file))
->save($path, array('format' => "png"));
var_dump('filtered');exit;
}
but after this $this-imagine-open() returns
File Resource id #141 doesn't exist
The strange thing form me is that it is was possible for me to save image file on s3 using only path:
->save($path, array('format' => "png"));
but it is not possible to open file using only path:
->apply($this->imagine->open($file->getFilePath()))
It throws exceptions
File watermarked/asd_asd.png doesn't exist.
Related
Currently I want to upload the images that the client chooses to the Amazon S3 service and in fact it seems that it already does so because it uploads a file and tells me that it weighs 92kb the same as the file I am choosing but when I want to open it with the path that is It gives me the following error:
The image <image path> cannot be displayed because it contains errors.
Code Laravel
public function SaveImage($request){
if ($request->hasFile('inputFile')) {
$image = $request->file('inputFile');
$fecha= date("m-d-y");
$name = $fecha."_".$request->txtNombre.'.'.$image->getClientOriginalExtension();
$destinationPath = public_path('UploadProfile');
$image->move($destinationPath, $name);
$filePath=$destinationPath."\\".$name;
$initPath="Perfil\\".$name;
Storage::disk('s3')->put($initPath, $filePath);
return $urlImage= Storage::cloud()->url($initPath);
}
}
the strangest thing is that it does not mark me errors, everything runs correctly but if it shows me that the files were uploaded in the panels of the buckets, besides if I upload directly through the buckets and open the path if it opens right way.
The image path would be as follows:
https://katanasystem.s3-us-west-1.amazonaws.com/Profile/01-05-20_david.jpg
I am trying to write a script to upload bulk product from excel sheet which contain product name, price and images. Images are the dropbox image share link. How can I download those image from the dropbox url, save them on my server, then upload the image url to my database?
Excel sheet reading:Maatwebsite/Laravel-Excel
Generic upload code:
public function productUpload(Request $request){
if($request->hasFile('products')){
$path= $request->file('products')->getRealPath();
$data = Excel::load($path)->get();
if($data->count()){
foreach ($data as $key => $value) {
//download the image create thumbain and store to /images/product/thumbnail folder and get the link,
$thumbnail = //here will be the path for the thumbnail
//Original image
$original = ;
$data['original']= $original;
$data['thumbnail']=$thumbnail;
$data['name']=$value->name;
$data['price']= $value->price;
Product::create($data);
}
return redirect()->back()->with('success','Product has been uploaded');
}
}
}
The image url that is in the excel sheet is like this one https://www.dropbox.com/s/x2tbsy49sraywvv/Ruby12.jpg?dl=0 This file has been removed at this point.
You can dowload the image directly by adding dl=1 to the dropbox link Source
And you can dowload the image to the server with the file_get_contents php command. Source and store it in the server with the Storage Facade
$url = "yoururl"; //check if has the dl=0 and change it to 1 or add dl=1
$contents = file_get_contents($url);
$name = 'image.png';//the name of the image to store on disk.
\Storage::disk('yourdisk')->put($name, $contents);
Also you will get the full path to the image like this.
$thumbnail = storage_path('yourdir/'.$name)
Tested it with a file that i have on my dropbox and worked without a problem.
You still need to handle some things like errors and delays while dowloading the images.
I have a function that takes submitted form data which is an image, then validates it and it deletes an old image if one already exists. It currently does that and stores the image on in the storage folder.
I am now trying to save the URL of the image to the database. I have seen examples where they do not save the path to the database but would it be best to do so?
Here is my function
public function postAvatarUpload(Request $request)
{
$this->validate($request, [
'image' => 'required|image|max:3000|mimes:jpeg,jpg,bmp,png',
]);
$user = Auth::user();
$usersname = $user->username;
$file = $request->file('image');
$filename = $usersname . '.jpg';
if (Storage::disk('local')->has($filename)) {
Storage::delete($filename);
}
Storage::disk('local')->put($filename, File::get($file));
$avatarPath = Storage::url($filename);
Auth::user()->update([
'image' => $avatarPath,
]);
return redirect()->route('profile.index',
['username' => Auth::user()->username]);
}
I mostly store images people upload to a subfolder in the public folder from Laravel. The image can then be requested with only your webserver doing the work and not having to serve it via PHP.
For images like an avatar I create a folder structure based on the model name and id of the model. Like: laravel_folder/public/images/user/13/avatar.jpg.
Because the path and url are based on the modelname and id, you can easily generate a direct url and path to it. Downside is that the url and path to avatars of other users is predictable, so don't use it for sensitive images.
I see you accept an image in multiple formats (jpg,png,bmp).
When you save the image, you save it as an jpg image. You should use an image manipulation library like Intervention, or get the extension of the file with pathinfo($file, PATHINFO_EXTENSION), otherwise the file won't be readable because the image extension and the image contents don't match.
Also think about the image size. Users can upload an image in poster size, while you only need a small image. Use an image manipulation library to create a smaller version image of the original image.
If you save the original image in the format you get from the user, then just check all extensions if they exist. One way to do it would be:
$extensions = [ 'jpg', 'jpeg', 'png', 'bmp' ];
$user = Auth::user();
$imagePath = "{public_path()}/images/{class_basename($user)}/{$user->id}/";
$imageName = "avatar";
// go through all extensions and remove image if it exists
foreach($extensions as $ext)
{
$imageFullPath = "{$imagePath}/{$imageName}.{$ext}";
if( file_exists($imageFullPath) )
{
#unlink($imageFullPath);
break;
}
}
The less you store in your filepath, the better because you aren't locked down to any folderstructure.
For now you might store all your uploads in /public/uploads but when your app gets bigger you might want to put everything in /public/uploads/form_xyz_images. When you put your whole image path in the database you'll have to adjust all values in the database.
A better way would be to only save the filename and append the path somewhere else. For example you could use accessors and mutators to get the path: https://laravel.com/docs/master/eloquent-mutators#accessors-and-mutators
Well, I've uploaded an app to Heroku, and I've discovered that I can't upload files to it. Then I started to use Dropbox as storage option, and I've done a few tests, of send and retrieve link, and all worked fine.
Now, the problem is to use the uploadFile() method on DropboxAdapter. He accepts an resource as the file, and I did'nt work well. I've done a few tests, and still no way. Here is what I am doing, if anyone could me point a solution, or a direction to this problem, please. :)
Here is my actual code for the update user (Update the user image, and get the link to the file).
$input = $_FILES['picture'];
$inputName = $input['name'];
$image = imagecreatefromstring(file_get_contents($_FILES['picture']['tmp_name']));
Storage::disk('dropbox')->putStream('/avatars/' . $inputName, $image);
// $data = Storage::disk('dropbox')->getLink('/avatars/' . $inputName);
return dd($image);
In some tests, using fopen() into a file on the disk, and doing the same process, I've noticed this:
This is when I've used fopen() on a file stored on the public folder
http://i.imgur.com/07ZiZD5.png
And this, when i've die(var_dump()) the $image that I've tried to create. (Which is a suggestion from this two links: PHP temporary file upload not valid Image resource, Dropbox uploading within script.
http://i.imgur.com/pSv6l1k.png
Any Idea?
Try a simple fopen on the uploaded file:
$image = fopen($_FILES['picture']['tmp_name'], 'r');
https://www.php.net/manual/en/function.fopen.php
You don't need an image stream but just a filestream, which fopen provides.
How can I upload image files to Dropbox with the Jimscode PHP Dropbox component for CodeIgniter? It uses the add() method for uploading files. It successfully uploads all other files types (e.g. pdf) to Dropbox. But when I upload image files, it uploads empty files to Dropbox. That is of 0 bytes and unable to preview that image in Dropbox. My code:
public function add($dbpath, $filepath, array $params = array(), $root=self::DEFAULT_ROOT)
{
$dbpath = str_replace(' ', '%20', $dbpath);
$filename = rawurlencode($filepath);
$parstr = empty($params) ? '' : '&'.http_build_query($params);
$uri = "/files_put/{$root}/{$dbpath}?file={$filename}{$parstr}";
//$uri = reduce_double_slashes("/files/{$root}/{$dbpath}?file={$filename}{$parstr}");
$specialhost = 'api-content.dropbox.com';
return $this->_post_request($uri, array('file'=>'#'.$filepath), $specialhost);
}
Is there an API method I can use directly with curl and PHP?
I'm not sure what version you are using but the reduce_double_slashes line isn't commented out normally. That wouldn't cause some file types to upload and not others though. Is the failure with a single image or does it fail to upload with every image.
You can also set the DEBUG const in the library to true and have it write debug information out to your error log. That might help you figure out where the issue is happening.