decode and move base64 encoded image in laravel

陌路散爱 提交于 2019-12-24 01:56:08

问题


I am trying to implement a image upload with other form elements with dropzone.js in laravel. So far I've managed to display the drag and drop image upload view with other form elements. And also get POST details from the submitted form. But when dropzone is passing the uploaded image to the database data save function it encode image with base64. I think I've managed to get the file extension also. And when I submit the button it gives me this error "Call to a member function move() on string" . Please put me in the right direction.

Here is the Form

<form class="form-horizontal" action="{{ route('save-slider-content') }}" method="POST" enctype="multipart/form-data">
   {{ csrf_field() }}
   <div class="box-body">
     <div class="form-group">
       <label for="inputEmail3" class="col-sm-2 control-label">Title</label>
       <div class="col-sm-10">
         <input type="text" class="form-control" name="sliderTitle" id="sliderTitle" placeholder="Title of the post goes here">
       </div>
     </div>
     <input type="hidden" name="date" id="date" value="<?php echo date("d-m-Y"); ?>">
     <div class="form-group">
       <label for="image" class="col-sm-2 control-label">Image</label>
       <input hidden id="file" name="file"/>
       <div class="col-sm-10">
         <div class="dropzone needsclick dz-clickable" id="fileUpload">
           <div class="dz-default dz-message">
              <i class="fa fa-image fa-5x"></i>
              <h3 class="sbold">Drop an image here to upload</h3>
              <span>You can also click to open file browser</span>
          </div>
         </div>
       </div>
     </div>
     <div class="form-group">
       <label for="inputEmail3" class="col-sm-2 control-label">Link</label>
       <div class="col-sm-10">
         <input type="text" class="form-control" name="sliderLink" id="sliderLink" placeholder="Provide a link">
       </div>
     </div>
   </div><br>
   <!-- /.box-body -->
   <div class="box-footer">
     <button type="submit" class="btn btn-default">Cancel</button>
     <button type="submit" class="btn btn-info pull-right">Post</button>
   </div>
   <!-- /.box-footer -->
 </form>

Here is the dropzone configuration

<script type="text/javascript">
Dropzone.options.fileUpload = {
  url: "save-slider-content",
  addRemoveLinks: true,
  accept: function(file) {
      let fileReader = new FileReader();

      fileReader.readAsDataURL(file);
      fileReader.onloadend = function() {

          let content = fileReader.result;
          $('#file').val(content);
          file.previewElement.classList.add("dz-success");
      }
      file.previewElement.classList.add("dz-complete");
  }
}
  </script>

Route

Route::post('store-slider-content', [ 'as' => 'save-slider-content', 'uses' => 'SliderContent@save_slider_data']);

save_slider_data function in Controller

public function save_slider_data(Request $request)
{
  $slider = new Slider;
  $slider->title = $request->sliderTitle;
  $slider->title_sin = $request->sliderTitleSin;
  $slider->date = $request->date;
  $slider->link = $request->sliderLink;

  $file = $request->file;;
  $image_data = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $file));
  $f = finfo_open();
  $mime_type = finfo_buffer($f, $image_data, FILEINFO_MIME_TYPE);
  $imageName = time().'.'.$mime_type;
  $image_data->move(public_path('slider_uploads'), $imageName);
  return response()->json(['success'=>$imageName]);

  $slider->img_url = $imageName;

  $slider->save();
}

回答1:


Edited to include the logic for either Symfony\Component\HttpFoundation\File\File or Illuminate\Support\Facades\File (Illuminate\Filesystem\Filesystem)

move is a method of a File object, but $image_data is just a string. So one thing you could do is write the decoded image to a temp file, instantiate a File of it, and move it, like

//... your code ...
   $image_data = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $file));
  // ... and then:
//grab a new tmp file
    $tmpFilePath=sys_get_temp_dir().'/'.uniqid(); 
    //write the image to it
    file_put_contents($tmpFilePath, $image_data); 
    //move it. 
    //give it a name
     $imageName = time().'.'.str_replace("image/","",$mime_type);
    //if using Symfony\Component\HttpFoundation\File\File;
    //get an instance of File from the temp file and call ->move on it
    $tmpFile=new File($tmpFilePath);
    $tmpFile->move(public_path('slider_uploads'), $imageName);
    //or if using File facade
    File::move($tmpFilePath, public_path("slider_uploads/$imageName")); 
//...and then, back to your code...
  $slider->img_url = $imageName;
  $slider->save();
  return response()->json(['success'=>$imageName]);
}



回答2:


You can do this:

In config/filesystems.php, register a new disk slider_uploads

'disks' => [

    'local' => [
        'driver' => 'local',
        'root'   => storage_path('app'),
    ],
    'slider_uploads' => [
        'driver' => 'local',
        'root'   => public_path('slider_uploads')
    ]
]

And then use your new disk in storing your image

$image_data = $request->file; 

@list($type, $image_data ) = explode(';', $image_data );
@list(, $image_data ) = explode(',', $image_data ); 
if($image_data !=""){ // storing image in public/slider_uploads/ Folder 
    \Storage::disk('slider_uploads')->put($imageName, base64_decode($image_data )); 
} 


来源:https://stackoverflow.com/questions/48792585/decode-and-move-base64-encoded-image-in-laravel

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!