I am trying to JSONify a blob file so that I can send it over AJAX requests. I have tried with the code below without any success. When I parse a JSONified file, I only get a different file with much smaller size.
function test(blob, cb) {
var fileReader = new FileReader()
fileReader.readAsArrayBuffer(blob)
fileReader.onloadend = function() {
// client
var arry = Array.from(new Uint8Array(fileReader.result))
var data = {data: arry }
var json = JSON.stringify(data)
// server
var parse = JSON.parse(json)
var arr = parse.data.buffer
var blob = new Blob([arr])
}
}
You can try to use FileReader.readAsDataURL() method, and send the data as base64 encoded string, and than decode it on the server side. Base64 string will be much smaller than json string representing an array.
Here is an example
function getBase64() {
var file = document.querySelector('input[type=file]').files[0];
var reader = new FileReader();
reader.addEventListener("load", function () {
document.getElementById("result").value = reader.result;
}, false);
if (file) {
reader.readAsDataURL(file);
}
}
<input type="file" onchange="getBase64()" />
<br/>
<textarea id="result"></textarea>
You can use FormData.
JQuery example (for simplicity):
var oFormData = new FormData();
$(':input', this).each(function (){
if(this.name){
var oValue = this.value;
if(this.type == 'file'){
oValue = this.files[0]; //TODO if "input file multiple" need loop each value
}
oFormData.append(this.name, oValue);
}
});
$.ajax({
url: 'http://example.com/xhr',
type: "POST",
data: oFormData,
processData: false,
contentType: false,
error: function (oRequest, sTextStatus, oErrorThrown){
console.log(sTextStatus);
},
success: function (oData, sTextStatus, oRequest){
console.log(oData);
},
});
Related
I am trying to send Dropzone File Using JSON so I want to decode the image into base64
I tried this function:
function getBase64Image(imgElem) {
var canvas = document.createElement("canvas");
canvas.width = imgElem.clientWidth;
canvas.height = imgElem.clientHeight;
var ctx = canvas.getContext("2d");
ctx.drawImage(imgElem, 0, 0);
var dataURL = canvas.toDataURL("image/png");
return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
}
now for Dropzone I write this to test the base64 converter
$("form#dropzone").dropzone({
url: allPaths.baseUrl + 'Services/PictureUpload.asmx/HandleFileDropped',
uploadMultiple: true,
autoProcessQueue: false,
acceptedFiles: "image/*",
init: function() {
this.on("addedfile", function(file) {
console.log(getBase64Image(file));
});
}
});
and I got the error that File object is not valid
I found that the file.DATAURL has the base64 already (without the needing of the above function) so I will post my solution here:
$("form#dropzone").dropzone({
url: allPaths.baseUrl + 'Services/PictureUpload.asmx/HandleFileDropped',
uploadMultiple: true,
autoProcessQueue: false,
acceptedFiles: "image/*",
init: function() {
this.on("addedfile", function (file) {
var reader = new FileReader();
reader.onload = function(event) {
// event.target.result contains base64 encoded image
var base64String = event.target.result;
var fileName = file.name
handlePictureDropUpload(base64String ,fileName );
};
reader.readAsDataURL(file);
});
}
});
I used a different approach since I save trough a json object in Ajax.
First, I declared an global array.
images = [];
I acceded to the files in my dropzone area like this, and pushed them to my array images.
for (var i = 0; i < $animalImage.files.length; i++) {
images.push($animalImage.files[i]);
}
Second I added that array to my json object(animal) mapping them with the info that I was expecting in my Model(asp.net C#)
animal.Pictures = $.map(images, function (img) {
return {
base64: img.dataURL.replace(/^data:image\/[a-z]+;base64,/, ""),
fileName: img.name,
type: img.type
};
});
As you can see I mapped base64, information that I got from the image.
Hope it helps.
An image file is sent from ASP.Net MVC using FilePathResult. How can this image be converted into a base64 string at client side (web browser) when http response is received. It is showing data in the raw form in response.data object. I've tried
var blob = new Blob([response.data], { type: 'image/jpeg' });
var reader = new FileReader();
reader.onloadend = function () {
var base64data = reader.result;
console.log(base64data);
}
reader.readAsDataURL(blob);
When you fetch the binary as text with ajax, browsers will try to parse the character set and change your data.
You must fetch the data as a blob to avoid to tell them not to
function getBase64(blob) {
var blob = xhr.response
var reader = new FileReader();
reader.onload = function () {
var base64data = reader.result;
console.log(base64data);
}
reader.readAsDataURL(blob);
}
var xhr = new XMLHttpRequest()
xhr.open('GET', '/myfile.png', true)
xhr.responseType = 'blob' // get data as blob
xhr.onload = function() {
getBase64(xhr.response)
}
xhr.send()
// or if you are using fetch
fetch('/myfile.png')
.then(function(res) {
res.blob() // get data as blob
.then(getBase64)
})
I hope I am not misunderstood:
Try this script, for the easier ajax I'm using jquery:
$.ajax({
url: 'someImage.png',
type: 'POST',
success: function(r) {
var data = btoa(r);
$('img.photo').attr('src', "data:image/png;base64," + data);
},
});
you can change above code as you need.
I am using the File reader in JavaScript,i need to Post my image to WebApi and convert it into byte Array and save it in server,Its working fine,Now my problem is base64 string increasing the size of image, Let say if i upload image of 30Kb, it is storing has 389Kb in server,How i can save in same size or reduce size of image need help
//File Reader
function OnFileEditImageEntry(file) {
var reader = new FileReader();
reader.onloadend = function (evt) {
var ImageBase64 = evt.target.result;
return ImageBase64 ;
};
reader.readAsDataURL(file);
}
//WEB API//
public IHttpActionResult UpdateUserDetails(ImageModel model)
{
try
{
if (model.ImageBase64 != "")
{
var PicDataUrl = "";
string ftpurl = "ftp://xxx.xxxxx.xxxx/";
var username = "xxx";
var password = "xxxxx";
string UploadDirectory = "xxxx/xx";
string FileName =model.ImageFileName;
String uploadUrl = String.Format("{0}{1}/{2}", ftpurl, UploadDirectory,FileName);
FtpWebRequest req = (FtpWebRequest)FtpWebRequest.Create(uploadUrl);
req.Proxy = null;
req.Method = WebRequestMethods.Ftp.UploadFile;
req.Credentials = new NetworkCredential(username, password);
req.EnableSsl = false;
req.UseBinary = true;
req.UsePassive = true;
byte[] data =Convert.FromBase64String(model.ImageBase64);
req.ContentLength = data.Length;
Stream stream = req.GetRequestStream();
stream.Write(data, 0, data.Length);
stream.Close();
}
}
}
Send the raw binary instead of increasing the size ~30% with base64/FileReader
with fetch
// sends the raw binary
fetch('http://example.com/upload', {method: 'post', body: file})
// Append the blob/file to a FormData and send it
var fd = new FormData()
fd.append('file', file, file.name)
fetch('http://example.com/upload', {method: 'post', body: fd})
With XHR
// xhr = new ...
// xhr.open(...)
xhr.send(file) // or
xhr.send(fd) // send the FormData
Normally when uploading files, try to avoid sending a json as many developers tends to to wrong. Binary data in json is equal to bad practice (and larger size) eg:
$.post(url, {
name: '',
data: base64
})
Use the FormData#append as much as possible or if you feel like it:
fd.append('json', json)
I made an simple image manipulation experiment with html, css and javascript/jquery.
We can upload an image from local drive and displayed in browser.
After that we can also edit/tag the displayed image.
I use this jquery image tag plugin.
Then I think about, how can i save/print the edited image?
This is my code snippet :
$(function () {
$(":file").change(function () {
if (this.files && this.files[0]) {
var reader = new FileReader();
reader.onload = imageIsLoaded;
reader.readAsDataURL(this.files[0]);
}
});
});
function imageIsLoaded(e) {
$('#myImg').attr('src', e.target.result);
$('#myImg').imageTag();
};
Here's the real live app : http://nanonimos.com/upload-tag-image/
and this is the source code.
Any clue/advice would be greatly appreciated :)
You can convert the whole div to an canvas then convert the canvas into data uri(png,jpeg).
Check this Fiddlecanvastoimage for more.
Use this function(From Stackoverflow) to convert dataURI to blob:
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 = unescape(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});
}
and then whenever you want to save just post this file to server.
In HTML5 you can do like this:
var blob = dataURItoBlob(data);
var fd = new FormData();
fd.append("imageFile", blob);
Then send it with ajax like this:
$.ajax({
type: "POST",
url:"url to file",
data: fd,
success: function(result){
//check success
};
});
people!
I have tried to send via HTTP POST (using AngularJS) the content of a file (images to be more precise) converted in ArrayBuffer (UInt8) to a Django server but I cannot manage to save it correctly in file on the server.
Javascript code:
filesToUpload = document.getElementById('files')
var files = filesToUpload.files;
for(var i = 0; i < files.length; i++)
{
var reader = new FileReader();
reader.onload = (function(fileToBeUploaded) {
return function(e) {
var fileContent = e.target.result;
var bin = new Uint8Array(fileContent);
console.log(bin);
var request = $http({
url: urlAddImagesRestaurant,
method: "post",
data: {
fileStructure: fileToBeUploaded,
datafile: bin
}
});
return request.then( service.handleSuccess, service.handleError );
};
})(files[i]);
reader.readAsArrayBuffer(files[i]);
}
}
Has someone any idea how to save the content of the arraybuffer in django?