使用Laravel 5存储上传的图像

I'm trying to upload, convert and store an image in Laravel using Image Magick.

Inside App\Http\Controllers\ArticleController:

$image = $this->storeMainImage($request->file('thumbnail'));

The function:

private function storeMainImage($file) {
  $folder = 'uploads/images/'; <--- ?????
  $code = uniqid();
  $thumb_code = $folder . 'thumb_' . $code . '.jpg';
  $image_code = $folder . $code . '.jpg';
  if(@is_array(getimagesize($file))){
    exec('convert '.$file.'  -thumbnail 225x225^ -gravity center -extent 225x225  -compress JPEG -quality 70  -background fill white  -layers flatten  -strip  -unsharp 0.5x0.5+0.5+0.008  '.$thumb_code);
    exec('convert '.$file.'  -compress JPEG -quality 70  -background fill white  -layers flatten  -strip  -unsharp 0.5x0.5+0.5+0.008  '.$image_code);
    return $image_code;
  } else {
    return false;
  }
}

I don't get any errors with this, but I have no idea if it's actually uploading the file and where abouts it's storing it.

To work with Image Magick, first you have to make sure if your server has that module. Else you can install it. See this to install imagemagick

Else you can use gd by configuring image.php file in your config folder. gd is available by default

since $folder = 'uploads/images/'; <--- ????? has no starting point specified, the starting point will be where you are when running the script. Therefore to make sure the storing path, you should define your path using storage_path() or public_path() if you are storing in storage or public folder respectively. Check here for more paths available according to the version you are using. Given link is for Laravel 5.2. You can change the version at the top right corner of the page.

$request->file() can return: \Symfony\Component\HttpFoundation\File\UploadedFile or array or null

You should check it before processing. Just dump it with var_dump($file) or dd($file). Not sure, but it should not be string.

Use public_path() for $folder variable, it will help you to prevent any problems in future.

And also check this awesome package for Laravel: http://image.intervention.io/getting_started/introduction

I've made a script which supports uploading multiple images/files within Laravel, which uses the Image Intervention package. This maybe useful for you and others on SO. I've added some comments and removed unnecessary code to have a better understanding of what is happening.

HTML markup

<form method="post" action="{{ route('admin.upload.store') }}" enctype="multipart/form-data">
    {{!! csrf_field() !!}}
    <input type="file" name="files[]" accept="image/gif, image/jpeg, image/png">
    <button type="submit">Upload image(s)</button>
</form>

UploadController

Uses Laravel's built-in RESTful resource controller routes

/**
 * Store a newly created resource in storage.
 * Supports uploading multiple files at once.
 *
 * @param  Request $request
 * @return Response
 */
public function store(Request $request)
{
    // Loop through the files array
    foreach($request->file('files') as $file) {

        // Validate each file, we want images only
        $validator = Validator::make(compact('file'), [
            'files' => 'mimes:jpeg,bmp,gif,png'
        ]);

        if ($validator->fails()) {
            return redirect()->route('admin.upload.index')->withErrors($validator);
        }

        // Create a new upload model for the file
        $upload = new Upload([
            'name'      => pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME) . '_' . Str::random(2),
            'extension' => strtolower($file->getClientOriginalExtension()),
            'mimetype'  => $file->getMimeType(),
            'size'      => $file->getSize(),
        ]);

        // Create the image
        $file = Image::make($file)->widen(1200, function($constraint) {
            $constraint->upsize(); // Prevent upsizing the image if doesn't exceed the maximum width
        })->encode($upload->extension);

        // Store it within 'storage/app/uploads'
        Storage::disk('uploads')->put($upload->fullName(), $file);

        // Save the upload file details in the database
        $upload->save();
    }

    return redirect()->route('admin.upload.index')->with(['success' => 'Files uploaded']);
}