Home » vue » Storing an HTMLCanvasElement as a JPG in Laravel

Storing an HTMLCanvasElement as a JPG in Laravel

Posted by: admin November 26, 2021 Leave a comment

Questions:

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.

Answers:

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