I want to upload a resized image to Amazon S3 bucket, using Yii framework, but to do it directly -- without uploading original (not resized) image to any folder, anywhere within Yii, website or server structure.
I have used ThumbsGen extension to create thumbnail of an image. The code works, if I upload file on my own server. But, if I upload the image to S3, then it will not create a thumbnail.
My code is look like this:
<?php
Yii::app()->setComponents(array('ThumbsGen' => array(
'class' => 'ext.ThumbsGen.ThumbsGen',
'thumbWidth' => Yii::t('constants', 'SECRETCODE_WIDTH'),
'thumbHeight' => Yii::t('constants', 'SECRETCODE_HEIGHT'),
'baseSourceDir' => Yii::app()->request->s3baseUrl.'/uploads/secretcode/original/',
'baseDestDir' => Yii::app()->request->s3baseUrl. '/uploads/secretcode/thumbs/',
'postFixThumbName' => null,
'nameImages' => array('*'),
'recreate' => false,
)));
class SecretCodeController extends MyController {
public function actionCreate() {
$model = new SecretCode;
$model->scenario = 'create';
if (isset($_POST['SecretCode'])) {
$model->attributes = $_POST['SecretCode'];
$temp = $model->promo_image = CUploadedFile::getInstance($model, 'promo_image');
if ($model->validate()) {
$rnd = rand(1, 1000);
$ext = $model->promo_image->extensionName;
$filename = 'secret_' . Yii::app()->user->app_id . '_' . time() . '_' . $rnd . '.' . $ext; $success = Yii::app()->s3->upload( $temp->tempName , 'uploads/secretcode/original/'.$filename);
if(!$success)
{
$model->addError('promo_image', Yii::t('constants', 'IMAGE_FAILURE'));
} else {
$model->promo_image = $filename; $model->promo_image = $filename;
$fullImgSource = #Yii::app()->s3->getObject(Yii::app()->params->s3bucket_name,"uploads/secretcode/original/".$filename);
list($width, $height, $type, $attr) = getimagesize($fullImgSource->headers['size']);
$dimensions = array();
$dimensions = CommonFunctions :: SetImageDimensions($width, $height,Yii::t('constants', 'SECRETCODE_WIDTH'), Yii::t('constants', 'SECRETCODE_HEIGHT'));
Yii::app()->ThumbsGen->thumbWidth = $dimensions['width'];
Yii::app()->ThumbsGen->thumbHeight = $dimensions['height'];
Yii::app()->ThumbsGen->createThumbnails();
}
if ($model->save()) {
Yii::app()->user->setFlash('success', Yii::t('constants', 'Secret Code')." ". Yii::t('constants', 'ADD_SUCCESS'));
$this->redirect(array('create'));
}
}
}
}
$this->render('create', array(
'model' => $model,
));
}
}
As a result, I'm getting a PHP warning:
getimagesize(42368) [<a href='function.getimagesize'>function.getimagesize</a>]: failed to open stream: No such file or directory
What am I doing wrong?
getimagesize — Get the size of an image
array getimagesize ( string $filename [, array &$imageinfo ] )
Your code:
list($width, $height, $type, $attr) = getimagesize($fullImgSource->headers['size']);
$fullImgSource->headers['size'] - I doubt that it stores the file path to image;
try this:
list($width, $height, $type, $attr) = $fullImgSource->headers['size'];
or
list($width, $height, $type, $attr) = getimagesize(/*path to image*/);
Can also read Transferring Files To and From Amazon S3
Related
I'm working with Laravel 9 and Image Intervention 2.7 and I wanted to resize uploaded images.
Here is the upload method:
public static function upload($file,$cat,$queid)
{
...
if (in_array($file->getClientOriginalExtension(), self::resizeable())) {
$file->storeAs(self::route(), $fileName);
$custom = self::resize($file, $fileName);
}
$file->storeAs(self::route(), $fileName);
...
}
So I call the static function reszie which goes here:
public static function resize($file, $fileName)
{
$path = self::route();
foreach (self::size() as $key => $value) {
$resizePath = self::route() . "{$value[0]}x{$value[1]}_" . $fileName;
Image::make($file->getRealPath())
->resize($value[0], $value[1], function ($constraint) {
$constraint->aspectRatio();
})
->save($resizePath);
$urlResizeImage[] = ["upf_path" => $resizePath, "upf_dimension" => "{$value[0]}x{$value[1]}"];
}
self::$urlResizeImage = $urlResizeImage;
}
As you can see I pass the $resizePath as $path to save method of Image Intervention Facade:
public function save($path = null, $quality = null, $format = null)
{
$path = is_null($path) ? $this->basePath() : $path;
if (is_null($path)) {
throw new NotWritableException(
"Can't write to undefined path."
);
}
if ($format === null) {
$format = pathinfo($path, PATHINFO_EXTENSION);
}
$data = $this->encode($format, $quality);
$saved = #file_put_contents($path, $data);
if ($saved === false) {
throw new NotWritableException(
"Can't write image data to path ({$path})"
);
}
// set new file info
$this->setFileInfoFromPath($path);
return $this;
}
But now the problem is with file_put_contents which does not generate the resized images.
And also no errors returned and just the original image will be saved!
So what's going wrong here? How can I properly resize the original image and save it to the directory?
I would really appreciate any idea or suggestion from you guys about this...
I tried to resize my image before uploading but is not working but I am able to upload the image, Here is my Controller:
public function store(Request $request)
{
$validatedData = $request->validate([
'image' => 'required|image|mimes:jpg,png,jpeg,gif,svg|max:20480',
]);
$imageFile = $request->file('image');
$name = $imageFile->getClientOriginalName();
$path = $request->file('image')->store('images', 'public');
$resize = Image::make($imageFile)->resize(50, 50)->stream();
$save = new Gallery;
$save->image = $path;
$save->status = 1;
$save->user_id = Auth::id();
$save->save();
return redirect('gallery')->with('success', 'Image has been uploaded')->with('image',$name);
}
try below example source code. I have done image resize functionality in one of my project with Laravel version 8
<?php
if($request->hasFile('dealimg')){
$file = $request->File('dealimg');
$original_name = $file->getClientOriginalName();
$file_ext = $file->getClientOriginalExtension();
$destinationPath = 'uploads/deals';
$file_name = "deal".time().uniqid().".".$file_ext;
// $path = $request->deal_img->store('uploads');
$resize_image = Image::make($file->getRealPath()); //for Resize the Image
$resize_image->resize(150, 150, function($constraint){ //resize with 150 x 150 ratio
$constraint->aspectRatio();
})->save(public_path($destinationPath) . '/' . $file_name);
$deal_img = $destinationPath."/".$file_name;
$request->request->add(['deal_img' => $deal_img]);
}
?>
I hope this one helps to you... see this
I'm working with laravel 7 and using intervention/image to store images. However, I want to encode and store images as webp, I'm using the following code but it is not encoding the image in webp rather it is storing in the original format. Can you please tell me what I'm doing wrong?
public function storePoster(Request $request, Tournament $tournament)
{
if ($request->hasFile('poster')) {
$tournament->update([
'poster' => $request->poster->store('images', ['disk' => 'public_uploads']),
]);
$image = Image::make(public_path('uploads/' . $tournament->poster))->encode('webp', 90)->resize(200, 250);
$image->save();
}
}
Try this :
public function storePoster(Request $request, Tournament $tournament)
{
if ($request->hasFile('poster')) {
$tournament->update([
'poster' => $request->poster->store('images', ['disk' => 'public_uploads']),
]);
$classifiedImg = $request->file('poster');
$filename = $classifiedImg->getClientOriginalExtension();
// Intervention
$image = Image::make($classifiedImg)->encode('webp', 90)->resize(200, 250)->save(public_path('uploads/' . $filename . '.webp')
}
}
This is my code to convert to .webp and resize (keep image's ratio)
$imageResize = Image::make($image)->encode('webp', 90);
if ($imageResize->width() > 380){
$imageResize->resize(380, null, function ($constraint) {
$constraint->aspectRatio();
});
}
$destinationPath = public_path('/imgs/covers/');
$imageResize->save($destinationPath.$name);
if you want to convert image in to WEBP without any service or package, try this method. work for me. have any question can ask. Thankyou
$post = $request->all();
$file = #$post['file'];
$code = 200;
$extension = $file->getClientOriginalExtension();
$imageName = $file->getClientOriginalName();
$path = 'your_path';
if(in_array($extension,["jpeg","jpg","png"])){
//old image
$webp = public_path().'/'.$path.'/'.$imageName;
$im = imagecreatefromstring(file_get_contents($webp));
imagepalettetotruecolor($im);
// have exact value with WEBP extension
$new_webp = preg_replace('"\.(jpg|jpeg|png|webp)$"', '.webp', $webp);
//del old image
unlink($webp);
// set qualityy according to requirement
return imagewebp($im, $new_webp, 50);
}
I have some problem in this code. This code is working on my local windows based system. But the same code in not working on online server. I have a function that convert the big images in to small size images according to the parameters. the code of this function is given below.
public function do_resize($source_file, $target_folder, $height = 128, $width = 128){
$filename = $source_file;
$temp_data = explode('/',$filename);
$new_filename = end($temp_data);
$temp_data = explode('.', $new_filename);
$ext = end($temp_data);
$new_filename = $temp_data[0] . $width .'-'. $height .'.'. $ext;
$source_path = $filename;
$folder_path = '';
$temp_folder = explode('/',$target_folder);
foreach ($temp_folder as $folder) {
$folder_path .=$folder . '/';
if (!file_exists($folder_path)) {
mkdir($folder_path);
}
}
$target_path = $target_folder;
if (file_exists($source_file)) //file_exists of a url returns false.It should be real file path
{
return $folder_path . $new_filename;
}
if(isset($config_manip)){
unset($config_manip);
}
$config_manip = array(
'image_library' => 'gd2',
'source_image' => $source_path,
'maintain_ratio' => FALSE,
'new_image' => $target_path,
'create_thumb' => TRUE,
'thumb_marker' => $width . '-'. $height,
'width' => $width,
'height' => $height
);
$CI =& get_instance();
$CI->load->library('image_lib');
$CI->image_lib->initialize($config_manip);
if (!$CI->image_lib->resize()) {
echo $CI->image_lib->display_errors();
echo "<br>";
echo $config_manip['source_image'];
}
// clear //
$CI->image_lib->clear();
return $folder_path . $new_filename;
}
I am calling this function like this.
$name = $this->imageresize->do_resize($brand['logo'], $target_folder, 50, 50);
Then input parameter $brand['logo'] have this value "uploads/images/system/placeholder.png" and parameter $target_folder have this value "uploads/images/cache/brands/brand-logo".
I did not get any error from this code. but It is not resizing the images also. I also set the permission of the directory to 777.
Any one have some solution for this. Thanks
Change:
if (file_exists($source_file)) //file_exists of a url returns false.It should be real file path
{
return $folder_path . $new_filename;
}
on
if (file_exists($folder_path . $new_filename)) //file_exists of a url returns false.It should be real file path
{
return $folder_path . $new_filename;
}
AND $config_manip:
'new_image' => $target_path,
ON
'new_image' => $folder_path . $new_filename,
:)
I installed the patch "intervention/image", "must-master" in order to make my image to reduce the size of it to 300 by 300.
I've done some forms and appears to me always the same mistake.
Call to a member function resize() on string
which got the error?
Controller
public function updateProfile() {
$file = Input::file('imagem');
$profileData = Input::except('_token');
$validation = Validator::make($profileData, User::$profileData);
if ($validation->passes()) {
if ($file == null) {
User::where('id', Input::get('id'))->update($profileData);
Session::flash('message', 'Perfil editado com sucesso');
return view('backend/perfil.index');
}
$file = array_get($profileData,'imagem');
$destinationPath = 'imagens/perfil';
$extension = $file->getClientOriginalExtension();
$filename = rand(11111, 99999) . '.' . $extension;
$reduzir = $filename -> resize (300,300);
$profileData['imagem'] = $filename;
$upload_success = $file->move($destinationPath, $filename);
User::where('id', Input::get('id'))->update($profileData);
Session::flash('message', 'Perfil editado com sucesso');
return Redirect::to('backend/perfil');
} else {
return Redirect::to('backend/perfil')->withInput()->withErrors($validation);
}
}
The issue might be because of these reasons
Have you added this aliases in your app.php
'aliases' => [
//add these three at the bottom
'Form' => Illuminate\Html\FormFacade::class,
'HTML' => Illuminate\Html\HtmlFacade::class,
'Image' => Intervention\Image\Facades\Image::class
],
I believe that you already have form and html helper.
And use this function in the Controller
i.e., just pass the image and size value as the Parameter to this function
In the controller you have just call the below function like
$resizedImage = $this->resize($image, $request->get('image_size'));
And the resize() function was given below
private function resize($image, $size)
{
try
{
$extension = $image->getClientOriginalExtension();
$imageRealPath = $image->getRealPath();
$thumbName = 'thumb_'. $image->getClientOriginalName();
//$imageManager = new ImageManager(); // use this if you don't want facade style code
//$img = $imageManager->make($imageRealPath);
$img = Image::make($imageRealPath); // use this if you want facade style code
$img->resize(intval($size), null, function($constraint) {
$constraint->aspectRatio();
});
return $img->save(public_path('images'). '/'. $thumbName);
}
catch(Exception $e)
{
return false;
}