Base64 versus Binary

En el anterior post, estuve mostrando la posibilidad de enviar al servidor una imagen ya transformada, con la ayuda de canvas. A raíz del mismo surgió un debate sobre el formato en el que se estaba subiendo dicha imagen a servidor, base64. Lo cierto es que no era el principal objetivo del post ya que buscaba la simplicidad pero me gustaría centrarme hoy en ver cómo sería posible pasar esa información a binario antes de ser enviada. Existen varias formas de hacerlo pero en mi caso he hecho uso de toDataURL, atob, ArrayBuffer y Uint8Array.

Siguiendo el mismo ejemplo que el anterior, cuando aceptamos la imagen que estamos visualizando en el canvas podríamos obtenerla y enviarla de la siguiente manera:

            id('btnSave').addEventListener('click', function (e) {

                e.preventDefault();

                //usamos FormData para mandar los valores a servidor
                var formData = new FormData();

                formData.append('nombreImagen', file.name);
                formData.append('contentType', file.type);

                //imagen en binario
                var dataURI = canvas.toDataURL(file.type),
                    byteCharacters = atob(dataURI.split(',')[1]),
                    arrayBuffer = new ArrayBuffer(byteCharacters.length),
                    uInt8Array = new Uint8Array(arrayBuffer);

                for (var i = 0; i < byteCharacters.length; i++) {
                    uInt8Array[i] = byteCharacters.charCodeAt(i);
                }

                var binary = new Blob([arrayBuffer], { type: file.type });

                formData.append('imageData', binary);
                var xhr = new XMLHttpRequest();

                xhr.open('POST', '/Home/UploadImage', true);
                xhr.send(formData);
            });

        };

Por otro lado, en el servidor la forma de recuperarla sería la siguiente:

        //[HttpPost]
        //public ActionResult UploadImage(string imageName, string contentType, string imageData)
        //{
        //    byte[] data = Convert.FromBase64String(imageData);

        //    if (Request.IsAjaxRequest())
        //        return Content(imageData);

        //    return File(data, contentType, imageName);

        //}

        [HttpPost]
        public ActionResult UploadImage(HttpPostedFileBase imageData)
        {
            return File(imageData.InputStream,imageData.ContentType,imageData.FileName);

        }

Si nos fijamos en esta parte respecto a la anterior, en vez de trabajar con un string para posteriormente convertirla, se ha utilizando directamente HttpPostedFileBase para su recuperación. Si tuviéramos varios archivos, podríamos recuperarlo iterando sobre Request.Files

Espero que sea de utilidad 🙂

¡Saludos!