在Laravel中解码并移动Base64编码的图像

3
我正在尝试在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']);

在控制器中的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个回答

3

编辑:包含逻辑以处理要么Symfony\Component\HttpFoundation\File\FileIlluminate\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]);
}

现在我得到了这个错误 **Call to undefined method Illuminate\Support\Facades\File::move()**,尽管我已经在控制器中添加了 use File - Kasun
@Kasun 很有趣!我实际上一直在使用 Symfony\Component\HttpFoundation\File\File,现在我已经更新为正确的代码 Illuminate\Support\Facades\File - chiliNUT

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

谢谢,它可以工作!但是我认为在保存图像后获取文件扩展名时出现了错误,图像名称显示为1518632094.image/png,因此在slider_uploads文件夹中创建了1518632094.image这些文件夹,而不是images。 - Kasun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接