在laravel中解码并移动base64编码的图像

时间:2018-02-14 17:04:04

标签: php laravel base64 dropzone

我正在尝试使用其他表单元素在laravel中使用dropzone.js实现图像上传。到目前为止,我已设法显示拖放图像上传视图与其他表单元素。并从提交的表单中获取POST详细信息。但是当dropzone将上传的图像传递给数据库数据保存功能时,它会使用base64对图像进行编码。我想我也设法获得了文件扩展名。当我提交按钮时,它会给我这个错误"在字符串" 上调用成员函数move()。请把我放在正确的方向。

这是表格

<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>

这是dropzone配置

<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::post('store-slider-content', [ 'as' => 'save-slider-content', 'uses' => 'SliderContent@save_slider_data']);

Controller中的save_slider_data函数

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();
}

2 个答案:

答案 0 :(得分:1)

你可以这样做:

config/filesystems.php中,注册一个新磁盘slider_uploads

'disks' => [

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

然后使用新磁盘存储图像

$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 )); 
} 

答案 1 :(得分:1)

已编辑以包含 Symfony\Component\HttpFoundation\File\File Illuminate\Support\Facades\File (Illuminate\Filesystem\Filesystem)的逻辑

moveFile对象的方法,但$image_data只是一个字符串。所以你可以做的一件事就是将解码后的图像写入临时文件,实例化File,并移动它,如

//... 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]);
}