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

Posted

技术标签:

【中文标题】在 laravel 中解码和移动 base64 编码的图像【英文标题】:decode and move base64 encoded image in laravel 【发布时间】:2018-07-25 08:16:31 【问题描述】:

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

这是表格

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

【问题讨论】:

【参考方案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]);

【讨论】:

现在我收到此错误 Call to undefined method Illuminate\Support\Facades\File::move() 即使我添加了 use File 已经在控制器中 @Kasun 有趣!我实际上使用的是Symfony\Component\HttpFoundation\File\File,我更新了Illuminate\Support\Facades\File的正确代码【参考方案2】:

你可以这样做:

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 b> 创建这些文件夹

以上是关于在 laravel 中解码和移动 base64 编码的图像的主要内容,如果未能解决你的问题,请参考以下文章

VC++详解Base64编解码原理以及Base64编解码接口实现(附源码)

python3的base64编解码

Base64 编解码

在 laravel 中验证 base64 解码图像

Base64编解码是什么?

Base64编解码中的坑