0

I have an image element where I get the blob string URL from and I'm trying to convert it to a blob first then to base64 string. so that I can send the base64 string (this is stored in #originalImage) to server side.

JS

            onFinished: function (event, currentIndex) {
            var form = $(this);

            if ($('#image').attr('src').length) {
                var selectedFile = $('#image').attr('src');
                var blob;
                var reader = new window.FileReader();
                var xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function () {
                    if (this.readyState == 4 && this.status == 200) {
                        blob = this.response;
                        console.log(this.response, typeof this.response);
                        if (blob != undefined) {
                            reader.readAsDataURL(blob);
                        }
                    }
                }
                xhr.open('GET', selectedFile);
                xhr.responseType = 'blob';
                xhr.send();


            }
            reader.onloadend = function () {
                base64data = reader.result;
                console.log(base64data);
                if (base64data != undefined) {
                    $("#originalImage").val(base64data);
                    form.submit();
                }

            }

        }

Controller

        [HttpPost]
        public ActionResult Action(Model blah, string croppedImage, string originalImage){
              // Code here...
         }

It works as expected but my only concern is that where I submit the form which is inside reader.onloadend. is there any problem with this approach or is there any better approach than this?

I appreciate any help on this, Thanks!

ecasper
  • 489
  • 1
  • 10
  • 30

1 Answers1

1

Don't use base64, send the binary to the server, save time, process, memory and bandwidth

onFinished(event, currentIndex) {
  let src = $('#image').attr('src')

  if (src.length) {
    fetch(src)
    .then(res => 
      res.ok && res.blob().then(blob =>
        fetch(uploadUrl, {method: 'post', body: blob})
      )
    )
  }
}

What you could also do is using canvas and avoid another request (but this will convert all image to png)

onFinished(event, currentIndex) {
  let img = $('#image')[0]
  if (!img.src) return

  let canvas = document.createElement('canvas')
  let ctx = canvas.getContext('2d')
  canvas.width = img.width
  canvas.height = img.height
  ctx.drawImage(img, 0, 0)
  canvas.toBlob(blob => {
    fetch(uploadUrl, {method: 'post', body: blob})
  })
}
Endless
  • 34,080
  • 13
  • 108
  • 131
  • Hi! Thanks for your answer!! I like the first method. how do you receive it at the controller end? does it mean that I will loose all the other model properties during the post? – ecasper Nov 17 '16 at 08:45
  • You could do `fd = new FormData(formElm)` to keep the other properties and append the blob into `fd` – Endless Nov 17 '16 at 17:01
  • I guess you're not suggesting me to manually attach other hundreds of model properties to the form prior to the submit. are you? – ecasper Nov 19 '16 at 09:19