3

I am trying to use ngx-image-cropper to upload images on my application, but I cannot save the cropped image. For example, if I try to save the main file (the file which is loaded through the input type="file"), everything works fine. In this case, the file is sent like this:

{name: "300_3.jpg", 
lastModified: 1510510128437, 
lastModifiedDate: Sun Nov 12 2017 20:08:48 GMT+0200 (GTB Standard Time), webkitRelativePath: "", 
size: 81972, …}

But if I try to upload the cropped version of the image, the file looks like this:

data:image/png;base64,iVBORw0KGgoAAAANSU............

And the response from the server is something like:

{error: "Bad Request",
exception:"org.springframework.web.multipart.support.MissingServletRequestPartException",
message: "Required request part 'file' is not present",
path: "/api/myEndPoint/",
status: 400,
timestamp: 1518424822285}

So basically I need to send an abject as in the first case, but all I have is a base64 item.

Here is also the HTML code, in case it helps:

<image-cropper
                    [imageChangedEvent]="imageChangedEvent"
                    [maintainAspectRatio]="true"
                    [aspectRatio]="4 / 4"
                    [resizeToWidth]="250"
                    format="png"
                    (imageCropped)="imageCropped($event)"
                    (imageLoaded)="imageLoaded()"
                    (loadImageFailed)="loadImageFailed()"
                    *ngIf="isUploadedFile">
                </image-cropper>

Can someone please advise how may I upload the cropped version and not the initial file I uploaded? Or is this something which needs to be fixed on the server, so it can accept the file I sent? Thanks!

decebal
  • 1,151
  • 3
  • 18
  • 38
  • You probably need to convert your base64 data to multipart: See here if it helps. https://stackoverflow.com/questions/4998908/convert-data-uri-to-file-then-append-to-formdata – David Feb 12 '18 at 09:36

3 Answers3

7

That string:

data:image/png;base64,iVBORw0KGgoAAAANSU............

means that you have your cropped image as dataURI. If you want to bring your upload of cropped image to work, then you should convert it from dataURI to Blob. If you have done this, then you can create from Blob an File and upload this to server.

Here is a function for converting dataURI to Blob:

  dataURItoBlob(dataURI): Blob {
    const byteString = atob(dataURI.split(',')[1]);
    const mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
    const ab = new ArrayBuffer(byteString.length);
    let ia = new Uint8Array(ab);
    for (let i = 0; i < byteString.length; i++) {
      ia[i] = byteString.charCodeAt(i);
    }
    return new Blob([ab], { type: mimeString });
  }

And now you can create File and upload it to server. Here is an example of uplaod function:

  uploadAttachmentToServer() {
    const fileToUpload: File = new File([this.dataURItoBlob(yourCroppedImage)], 'filename.png');
    this.attachmentService.postAttachment(fileToUpload).subscribe(data => {
      // success, do something
    }, error => {
      // failure, do something
    });
  }
Gregor Doroschenko
  • 11,488
  • 5
  • 25
  • 37
2

Actually ngx-image-cropper provides an attribute imageCroppedFile which gives you the cropped image as converted to Blob, for example in your html:

<image-cropper
                [imageChangedEvent]="imageChangedEvent"
                ...
                (imageCroppedFile)="fileCropped($event)">
</image-cropper>

then in your component you can convert from Blob to File:

fileCropped(blob: Blob) {
    const file = new File([blob], 'image.png');
    // upload the file
}
azatprog
  • 304
  • 2
  • 4
0

The ngx-image-cropper comes with a base64ToFile function which returns a Blob object.

import { ImageCropperedEvent, base64Tofile } from 'ngx-image-cropper'

and your code should look like:

someFunction(): File {
  // Assuming you have stored the event.base64 in an instance variable 'croppedImage'
  const file: File = new File([base64ToFile(this.croppedImage)], 'fileName.png');
  return file;
}
Pang
  • 9,564
  • 146
  • 81
  • 122