问题
I have developed a Laravel web application with the help of some tutorial videos and codes given by other developers on stackoverflow .The app is working pretty good except for the image upload feature. I am facing an issue related to the uploaded image being cut either on the sides or on the bottom as well as the image when uploaded through any IOS device then the image under goes rotation. I have installed image intervention but i don't know where to put the code inside my files i am sharing my controller code as well as the image displaying code here controller code
namespace App\Http\Controllers;
use Auth;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\MessageBag;
use App\comment;
use App\User;
use App\post;
use View;
use Lang;
use image;
class usersController extends Controller
{
private $u;
public function __construct(){
$this->u = new User();
}
public function search(Request $request){
$search_input = $request["input"];
$path = $request["path"];
$users = User::where("name","like","%$search_input%")->orWhere("username","like","%$search_input%")->get();
if ($users->isEmpty()) {
return "<p style='text-align: center;width: 100%;color: gray;font-size: 12px;margin: 3px'>".Lang::get('trans.nothingToShow')."</p>";
}else{
foreach ($users as $user) {
if ($user->verify == 1) {
$ifVerify = '<span class="verify-badge" style="width: 420px; height: 700px; background: url(\''.$path.'/imgs/verify.png\') no-repeat; background-size: cover; margin: 0px 2px;"></span>';
}else{
$ifVerify = '';
}
if($user->avatar == "avatar.png"){
$avatar_path = '/imgs/avatar.png';
}else{
$avatar_path = '/storage/avatar/'.$user->avatar;
}
echo '<div class="navbar-search-item">
<a href="'.$path.'/'.$user->username.'">
<div>
<div style="background-image:url(\''.$path.$avatar_path.'\');">
</div>
<p>
'.$user->name.$ifVerify.'<br>
<span>@'.$user->username.'</span>
</p>
</div>
</a>
</div>';
}
}
}
public function profile($username){
$user_info = User::where("username",$username)->get();
foreach ($user_info as $uinfo) {
$user_id = $uinfo->uid;
}
if (isset($user_id)) {
$feedbacks = post::where("to_id",$user_id)->where("privacy",1)->orderBy('time', 'desc')->get();
$feedbacks_count = post::where("to_id",$user_id)->get()->count();
$new_count = post::where("to_id",$user_id)->where('read',0)->get()->count();
// check comments on post (count)
$commentsCount = array();
foreach ($feedbacks as $fb) {
$pid = $fb->pid;
$countComments = comment::where("c_pid",$pid)->get()->count();
array_push($commentsCount,$countComments);
}
return view("pages.profile")->with(["user_info" => $user_info,"feedbacks" => $feedbacks,'feedbacks_count' => $feedbacks_count,'new_count' => $new_count,'commentsCount' => $commentsCount]);
}else{
return view("pages.profile")->with(["user_info" => $user_info]);
}
}
public function settings($username){
$user_info = User::where("username",$username)->get();
if (Auth::user()->username == $username) {
return view("pages.settings")->with("user_info",$user_info);
}else{
return redirect()->back();
}
}
public function s_general(Request $request){
$this->validate($request,[
'avatar' => 'nullable|image|mimes:jpeg,png,jpg|max:3072',
'fullname' => 'required',
'email' => 'required|email'
]);
if ($request['fullname'] == Auth::user()->name && $request['email'] == Auth::user()->email && !$request->hasFile('avatar')) {
return redirect()->back()->with('general_msg', Lang::get('trans.noChanges_MSG'));
}else{
$avatar = $request->file('avatar');
if ($request->hasFile('avatar')) {
$avatar_ext = $avatar->getClientOriginalExtension();
$avatar_name = rand(9,999999999)+time().".".$avatar_ext;
$avatar_new = $avatar->storeAs("avatar",$avatar_name);
}else{
$avatar_name = Auth::user()->avatar;
}
$update_general = User::where('uid',Auth::user()->uid)->update(['name' => $request['fullname'],'email' => $request['email'],'avatar' => $avatar_name]);
return redirect()->back()->with('general_msg', Lang::get('trans.changes_saved'));
}
}
and this is how i display the image
<div class="profile-avatar" style="width: 300px;height:400px; border-radius: 0%;background-image: url('@if(Auth::user()->avatar == "avatar.png") {{ url("/imgs/".Auth::user()->avatar) }} @else {{ url("/storage/avatar/".Auth::user()->avatar) }} @endif');">
please help me with code should i put and where i should put that in order to resolve this issue
this code is for preview of the image
<div style="display: inline-flex;">
<div class="profile-avatar" id="settings_img_elm" style="margin: 10px; width:350px;margin-top: 0; margin-bottom: 0;border-color: #fff; text-align: center;background-image: url('@if(Auth::user()->avatar == "avatar.png") {{ url("/imgs/".Auth::user()->avatar) }} @else {{ url("/storage/avatar/".Auth::user()->avatar) }} @endif');">
</div>
<p style="color: #a7aab5; font-size: 9px;padding: 25px 10px 25px 10px; margin: 0;">@lang("trans.preview")<br>@lang("trans.maxSize")<br>upload vertical <br>images.<br>Save the<br>image first<br> and then<br> check the<br> preview</p>
</div>
<p style="border-bottom: 1px solid #dfe2e6;margin: 0; margin-top: 12px; margin-bottom: 12px;">
<input type="file" name="avatar" style="display: none;" id="settings_img">
<label for="settings_img" class="btn btn-success">@lang("trans.selectImage")</label>
the javascript for the preview image is
function imagePreview(input,elm) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$(elm).css("background-image","url('"+e.target.result+"')");
}
reader.readAsDataURL(input.files[0]);
}
}
$("#settings_img").on("change",function(){
imagePreview(this,"#settings_img_elm");
});
$("#feedback_hFile").on("change",function(){
$(".send_feedback_image").show();
imagePreview(this,"#sfb_image_preview");
});
回答1:
The code below should get you started. The two key things you are looking for here are Interventions orientate and resize methods which should take care of the two issues you mention. Orientation will rotate the image based on EXIF data, and resize can resize your image to whatever specifications you need.
Import the facade
use Intervention\Image\Facades\Image;
Suggestions
Remove use image;
from your imports as it is probably causing or going to cause you issues. It is invalid.
s_general method adjustments
public function s_general(Request $request){
$this->validate($request,[
'avatar' => 'nullable|image|mimes:jpeg,png,jpg|max:3072',
'fullname' => 'required',
'email' => 'required|email'
]);
if ($request['fullname'] === Auth::user()->name && $request['email'] === Auth::user()->email && !$request->hasFile('avatar')) {
return redirect()->back()->with('general_msg', Lang::get('trans.noChanges_MSG'));
}
if ($request->hasFile('avatar')) {
// Grab the original image from the request
$originalImage = $request->file('avatar');
// Grab the original image extension
$originalExtension = $originalImage->getClientOriginalExtension();
// Instantiate a new Intervention Image using our original image,
// read the EXIF 'Orientation' data of the image and rotate the image if needed
$newImage = Image::make($originalImage)->orientate();
// Resize the new image to a width of 300 and a height of null (auto)
// we also use a callback to constrain the aspect ratio so we don't distort the image on resize
$newImage->resize(300, null, function ($constraint) {
$constraint->aspectRatio();
});
// Generate a randomized filename and append the original image extension
$filename = random_int(9, 999999999) + time() . '.' . $originalExtension;
// Save the new image to disk
$newImage->save(storage_path('app/public/avatar/' . $filename));
} else {
$filename = Auth::user()->avatar;
}
User::where('uid', Auth::user()->uid)->update(
[
'name' => $request['fullname'],
'email' => $request['email'],
'avatar' => $filename
]);
return redirect()->back()->with('general_msg', Lang::get('trans.changes_saved'));
}
More suggestions
I know this isn't a code review, but
Use PascalCase for your class names. I see you have a few imports such as App\comment
and App\post
Your constructor doesn't seem to be needed. I'd ditch it. If you are keeping it, i would get use to more descriptive variable names. Short names like $u are generally considered bad practice.
You have a few unused imports, Validator
, Hash
and MessageBag
could be removed to clean this up.
Your controller is doing a lot of stuff that most would consider bad practice. Fumbling around with html for example. 9.9 times out of 10 you should probably be leveraging blade for these things as it's one of its main purposes.
Stick to one naming convention or another. You are using a mixture of camelCase and snake_case for your variables. I prefer camelCase but whichever you choose it's best to stick with it and not mix them.
Sorry, i know this isn't suppose to be a code review, i just thought that a few little suggestions might help you in the future.
回答2:
You can check Intervation docs on how to resize image, I've also created an example for you for s_general
function:
$avatar = $request->file('avatar');
if ($request->hasFile('avatar')) {
//pass uploaded avatar to Intervention Image instance
$image = \Image::make($avatar);
//resize image to 300 width, keep height automated adjusted, or any other width you need
$image->resize(300, null, function ($constraint) {
$constraint->aspectRatio();
});
//Or you can set specific width and height
//$image->resize(300, 200);
$avatar_ext = $avatar->getClientOriginalExtension();
$avatar_name = rand(9,999999999) + time().".".$avatar_ext;
//I used public path to store the image you can change it based on your needs
$image->save(public_path('/avatar/'.$avatar_name));
}else{
$avatar_name = Auth::user()->avatar;
}
回答3:
use image intervention for resizing and for correcting the orientation of the image uploaded from a mobile phone. IF you are showing the preview of this image using simple javascript something like
reader.onload = function (e) {
$(elm).css("background-image","url('"+e.target.result+"')");
then there is a chance that the preview of the image won't be oriented as we want but once you save the image the orientation will be proper. this problem of orientation is encountered mostly on iphone. The code for orientation correction and resizing is
$newImage = Image::make($originalImage)->orientate();
$newImage->resize(300, null, function ($constraint) {
$constraint->aspectRatio();
});
///or for resizing use
$newImage->resize(width,height);
来源:https://stackoverflow.com/questions/59345551/how-to-resize-image-and-reorient-it-if-it-rotates-when-uploaded-through-ios-devi