3

Im looking to resize an image before it is uploaded to a server, at the moment i am using ng2-imageupload like this:

  <input id="media" class="inputfile" type="file" name="media" image-upload
  (imageSelected)="selected($event)"
  [resizeOptions]="resizeOptions" (change)="onChange($event)">

export class WpMediaFormComponent { file: File;

resizeOptions: ResizeOptions = {
    resizeMaxHeight: 768,
    resizeMaxWidth: 438
};

selected(imageResult: ImageResult) {
    console.log(imageResult);
   this.dataBlob = this.dataURItoBlob(imageResult.resized.dataURL); 
    let blob = this.dataURItoBlob(imageResult.resized.dataURL);
}

This then returns an object, like this:

dataURL:"data:image/jpeg;base64, DATA URI HERE"
type:"image/jpeg;"

I can then convert this object to a blob using this function:

dataURItoBlob(dataURI) {
        // convert base64/URLEncoded data component to raw binary data held in a string
        var byteString;
        if (dataURI.split(',')[0].indexOf('base64') >= 0)
            byteString = atob(dataURI.split(',')[1]);
        else
            byteString = decodeURI(dataURI.split(',')[1]);

        // separate out the mime component
        var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

        // write the bytes of the string to a typed array
        var ia = new Uint8Array(byteString.length);
        for (var i = 0; i < byteString.length; i++) {
            ia[i] = byteString.charCodeAt(i);
        }

        return new Blob([ia], {type:mimeString});
    }

Before doing this I was uploading the image to the server using this code:

 onChange(event: EventTarget) {
        let eventObj: MSInputMethodContext = <MSInputMethodContext> event;
        let target: HTMLInputElement = <HTMLInputElement> eventObj.target;
        let files: FileList = target.files;
        this.file = files[0];
        console.log(this.file);
        //this.update.emit(this.file);
    }

Does anyone have idea how I can feed the blob returned from dataURItoBlob method into the file upload onChange event?

Im a little lost here.

4
  • I am quite sure this is not possible, but would love to be proven otherwise! Commented Mar 9, 2017 at 12:34
  • Oh but it is, I just took an 800kB file and posted it as 30kB, will post an update soon. All server side baby! Commented Mar 9, 2017 at 23:16
  • Im confused now, is the resizing done on the client or server? Commented Mar 10, 2017 at 10:12
  • The image is resized using the ng2-imageresize module, it's resized client side then sent to the server Commented Mar 11, 2017 at 9:12

2 Answers 2

2

So I figured it out with the help of @Brother Woodrow, and this thread: How to convert Blob to File in JavaScript

Here is my updated code, not the only thing I had to change was the selected method:

selected(imageResult: ImageResult) {
    // create a blob 
    let blob: Blob = this.dataURItoBlob(imageResult.resized.dataURL);
    // get the filename
    let fileName: string = imageResult.file.name;
    // create a file
    this.file = new File([blob], fileName);
    console.log(this.file);
    // event emitter send to container then to http post 
    this.update.emit(this.file);        
}

I can now upload 3MB and they are pushed to the server around 150kB in seconds which is great for the user especially as this app will mostly be used by mobile devices.

Sign up to request clarification or add additional context in comments.

1 Comment

rhysclay, Thanks for providing a valid answer. Feel free to mark this as an answer. This way you'll help others by making the question/answer more visible to others. P.S. It's totally ok to answer your own question and mark as answered in StackOverflow stackoverflow.com/help/self-answer
1

You'll need to convert the Data URI to a Blob, then send that back to your server. This might be helpful: Convert Data URI to File then append to FormData

Once you have the blob, it should be easy enough to use FormData and the Angular HTTP class to upload it to your server for further processing.

let formData = new FormData();
formData.append(blob);
this.http.post('your/api/url', fd).subscribe((response) => console.log(reponse);

3 Comments

Thanks I was able to convert the data uri to a blob, but im unsure on how to send it to the server, ill update my code
That should be easy enough, just use FormData and Angular's HTTP class. I updated my post with a small bit of example code.
You are a legend! I actually ended up doing it a slightly different way because i still wanted to post a file with my http but you helped me tease it out enough. Ill post an update soon.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.