Search code examples
laravelvue.jslaravel-5.5laravel-5.6intervention

Storing an HTMLCanvasElement as a JPG in Laravel


I have integrated a cropping script that returns either an image or an HTMLCanvasElement in my Vue Component. In my component's crop method, I then make an axios post call to my upload function. Here is the crop method:

crop() {
  var croppedCanvas = this.cropper.getCroppedCanvas()
  var img = croppedCanvas.toDataURL('image/jpeg', 1.0);
  var formData = new FormData();
  formData.append('image', img) // I can send croppedCanvas here too if I want
  axios.post('/api/upload', formData)
}

Now the problem. I can't seem to save the HTMLCanvasElement or the Image as a JPG file. I tried so many different approaches (toDataURL, toBlob, etc.) and have failed in every single one. My latest implementation was as follows:

public function upload(Request $request) {
    $input = $request->all();
    $img = $input['image'];
    Storage::put('picture.jpg', $img);

    return response(Response::HTTP_OK);
}

This saves a 26 byte file in the storage/public folder which is unaccessible.

Can someone please help with how to go about this.

I simply want to save the HTMLCanvasElement as a JPG file in my storage/public folder.

Thanks.


Solution

  • Actually as mentioned in the docs over here : https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL
    toDataURL method returns back a base64 encoded data so you have to decode it on the server side
    you can use the base64_decode method in laravel like this

    public function upload(Request $request) {
      $img = $request->image;
      $img = str_replace('data:image/jpeg;base64,', '', $img);
      $img = str_replace(' ', '+', $img);
      $data = base64_decode($img);
      Storage::put('picture.jpg', $data);
      return response(Response::HTTP_OK);
    }