How to post an image in base64 encoding via .ajax? - javascript

I have some javascript code that uploads an image to a server. Below is the ajax call that works correctly.
$.ajax({
url: 'https://api.projectoxford.ai/vision/v1/analyses?',
type: 'POST',
contentType: 'application/json',
data: '{ "Url": "http://images.takungpao.com/2012/1115/20121115073901672.jpg" }',
})
I now need to upload the image a a base64 encoding e.g.
data: 'data:image/jpeg;base64,/9j/4AAQSkZJRgA..........gAooooAKKKKACiiigD//Z'
But that doesn't work, i.e. the server doesn't recognise the data I send and complains.
Does anyone know what the correct format is for sending base64 encoded data in the AJAX call ?

Thanks for all the answers which helped me along.
I had also posted the question to the forums on
https://social.msdn.microsoft.com/Forums/en-US/807ee18d-45e5-410b-a339-c8dcb3bfa25b/testing-project-oxford-ocr-how-to-use-a-local-file-in-base64-for-example?forum=mlapi (more Project Oxford specific) and between their answers and your's I've got a solution.
You need to send a Blob
You need to set the processData:false and contentType: 'application/octet-stream' options in the .ajax call
So my solution looks like this
First a function to make the blob (This is copied verbatim from someone more gifted than I)
makeblob = function (dataURL) {
var BASE64_MARKER = ';base64,';
if (dataURL.indexOf(BASE64_MARKER) == -1) {
var parts = dataURL.split(',');
var contentType = parts[0].split(':')[1];
var raw = decodeURIComponent(parts[1]);
return new Blob([raw], { type: contentType });
}
var parts = dataURL.split(BASE64_MARKER);
var contentType = parts[0].split(':')[1];
var raw = window.atob(parts[1]);
var rawLength = raw.length;
var uInt8Array = new Uint8Array(rawLength);
for (var i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], { type: contentType });
}
and then
$.ajax({
url: 'https://api.projectoxford.ai/vision/v1/ocr?' + $.param(params),
type: 'POST',
processData: false,
contentType: 'application/octet-stream',
data: makeblob('data:image/jpeg;base64,9j/4AAQSkZJRgA..........gAooooAKKKKACiiigD//Z'
})
.done(function(data) {alert("success");})
.fail(function() {alert("error");});

This is some working code from my own application. You will need to change the contentType and data args in your ajax operations.
var video = that.vars.video;
var code = document.createElement("canvas");
code.getContext('2d').drawImage(video, 0, 0, code.width, code.height);
var img = document.createElement("img");
img.src = code.toDataURL();
$.ajax({
url: '/scan/submit',
type: 'POST',
data: { data: code.toDataURL(), userid: userid },
success: function (data) {
if (data.error) {
alert(data.error);
return;
}
// do something here.
},
error : function (r, s, e) {
alert("Unexpected error:" + e);
console.log(r);
console.log(s);
console.log(e);
}
});

//After received the foto, convert to byte - C# code
Dim imagem = imagemBase64.Split(",")(1)
Dim bytes = Convert.FromBase64String(imagem)
You load the image in canvas, not necessary upload to server.
var ctx = canvas.getContext('2d');
ctx.drawImage(img, selection.x, selection.y, selection.w, selection.h, 0, 0, canvas.width, canvas.height);
var ctxPreview = avatarCanvas.getContext('2d');
ctxPreview.clearRect(0, 0, ctxPreview.width, ctxPreview.height);
ctxPreview.drawImage(img, selection.x, selection.y, selection.w, selection.h, 0, 0, canvas.width, canvas.height);
$('#avatarCanvas').attr('src', canvas.toDataURL());
$('#hdImagembase64').val(canvas.toDataURL());
See, this code get image and draw in canvas, after draw you get base64 string with canvas.toDataURL()
try this :D

The data parameter for jQuery's $.ajax call can be a String, Object, or Array. Based on the working example you gave, it looks like your upload script expects a parameter called "Url":
data: '{ "Url": "http://images.takungpao.com/2012/1115/20121115073901672.jpg" }'
If you wanted to pass the parameter as an Object, you might try:
data: {
Url: 'data:image/jpeg;base64,/9j/4AAQSkZJRgA..........gAooooAKKKKACiiigD//Z'
}
If you want to pass it as a String, you might try:
data: '{ "Url": "data:image/jpeg;base64,/9j/4AAQSkZJRgA..........gAooooAKKKKACiiigD//Z"}'

Related

How to add custom properties to file form javascript / jquery

I'm aiming to send fileform with images and additional information like height and width. I can't figure out how to add some custom props to file form object.
$("#saveImg").on('click', function () {
var formData = new FormData(),
allFiles = [];
$('input[name=fileUpload]').each(function (index) {
if (inputFileValidation(this)) {
(function (files) {
if (files.length != 0) { allFiles.push(files[0]); }
})(this.files)
}
});
for (var i = 0; i != allFiles.length; i++) {
var img = new Image()
img.src = window.URL.createObjectURL(allFiles[i]);
$(img).on('load', function () {
formData.append("files_h", img.naturalHeight);
formData.append("files_w", img.naturalWidth);
formData.append("files", allFiles[i]);
window.URL.revokeObjectURL(allFiles[i]);
});
}
$.ajax({
url: '#Url.Action("Upload", "Image")',
data: formData,
processData: false,
contentType: false,
type: "POST",
success: function () {}
errors: function () {}
});
});
[HttpPost]
public async Task<IActionResult> Upload (IList<IFormFile> files)
{
//do something ;
}
I also tried:
[HttpPost]
public async Task<IActionResult> Upload (IList<IFormFile> files, IList<IFormFile> files_h, IList<IFormFile> files_w)
{
//do something ;
}
Maybe you have another idea how to send image with additional data? I tried to convert file form and additional info to JSON by that didn't work.
Edit
Thank you all for your suggestion, they are really important to me because I will definitely use them in the future.
However, in this project I have already given up using the file reader due to its asynchrony and having fun with promise. The aim is simple and less javascript and more c#
I apologize for misleading you in the title javascript andjquery - and I mark the answer related to c #. I did this because this answer is related to my next task because the CoreCompat.System.Drawing library is undoubtedly still useful for editing photos in the future.
Thanks!!
If you want to get the Width and Height properties while uploading images in ASP.NET Core. I suggest you to install this package: CoreCompat.System.Drawing
Install-Package CoreCompat.System.Drawing -Version 1.0.0-beta006
In the server, after saving your files to the specific path. You could use System.Drawing.Image class to get the Width and Height properties:
using (var image = System.Drawing.Image.FromFile(filePath))
{
int width = image.Width;
int height = image.Height;
}
You don't have to add files_h and files_w properties to your client model before sending to server.
And then, by using this way, I've edited your js code to:
$("#saveImg").on('click', function () {
var formData = new FormData();
for (var input of Array.from($('input[name=fileUpload]')))
{
if (inputFileValidation(input) && input.files.length) {
formData.append('files', input.files[0]);
}
}
$.ajax({
url: '#Url.Action("Upload", "Image")',
data: formData,
processData: false,
contentType: false,
type: "POST",
success: function () {}
errors: function () {}
});
});
This is one approach; taken from there:
$('#btnUpload').click(function () {
// Checking whether FormData is available in browser
if (window.FormData !== undefined) {
var fileUpload = $("#FileUpload1").get(0);
var files = fileUpload.files;
// Create FormData object
var fileData = new FormData();
// Looping over all files and add it to FormData object
for (var i = 0; i < files.length; i++) {
fileData.append(files[i].name, files[i]);
}
// Adding one more key to FormData object
fileData.append('username', ‘Manas’);
$.ajax({
url: '/Home/UploadFiles',
type: "POST",
contentType: false, // Not to set any content header
processData: false, // Not to process data
data: fileData,
success: function (result) {
alert(result);
},
error: function (err) {
alert(err.statusText);
}
});
} else {
alert("FormData is not supported.");
}
});
Another approach is to use the FileReader class to read the uploaded file, convert it to a base 64 string. Then you can send the base 64 string to the server.

Weird response received using Promise

vm.imageR = $resource("", {}, {
getFile: {
url: '/api/imager/:fileId',
method: 'GET',
transformResponse: function(data, headersGetter) { return { data : data }},
isArray: false,
params: {
fileId: '#fileId'
}
},
...
This is what I receive:
"�PNG
IHDRX�7�"�PLTE���V�3R�-���O�(��������������S�/���P�*��h�H��������θ������׫����奥���ᴴ�����ށ��򿿿���O�E������...
How to correctly parse the image to display as image in HTML (set as src in image)?
If you really have to load the image this way, you will have to base64 the image data being returned on the server side and append that string on your img src.
// in this format
var imgData = "data:image/png;base64,"+theBase64Data;
Otherwise you will have to use an image tag to perform the request.
var img = document.createElement("img");
img.src = '/api/imager/'+fieldId; // whatever the fieldId is
// append it to the dom.
The second option make more sense since you are getting the image from the server anyway, why base64 it?
It's weird, but this was the only change that worked:
Before:
vm.getFile = function (fileId) {
return vm.imageR.getFile({ fileId: fileId });
};
Now:
vm.getFile = function (fileId) {
var retVal = vm.imageR.getFile({ fileId: fileId });
return retVal;
};
Really weird. :)

ASP.NET C# How do I pass canvas image to controller as Bitmap

I have the following javascript that sends the canvas image on my View to the controller in the form of a string. But I would like to convert the string into a Bitmap format. How can I do so?
document.getElementById('save').addEventListener('click', function () {
var image = document.getElementById("canvas").toDataURL("image/png");
image = image.replace('data:image/png;base64,', '');
$.ajax({
type: 'POST',
url: "Attendance/Decode",
data: '{ "imageData" : "' + image + '" }',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (msg) {
alert("Done, Picture Sent.");
}
});
});
Controller Method:
public ActionResult Decode(string imageData)
{
//Convert imageData to Bitmap
}
Is there any other way to send the canvas image as a Bitmap to the controller?
If you're receiving a URI or Base64, you can use BitmapImage() to convert it to bitmap.
Uri:
BitmapImage bitmapImage = new BitmapImage(url);
Base64String:
BitmapImage bitmapImage = new BitmapImage();
byte[] byteBuffer = Convert.FromBase64String(base64String);
MemoryStream memoryStream = new MemoryStream(byteBuffer);
memoryStream.Position = 0;
bitmapImage.SetSource(memoryStream);
memoryStream.Close();
memoryStream = null;
byteBuffer = null;
Hope it helps!

Using JSON Stringify with a variable to push to Node server

I am trying to push the base64 of an image in <canvas> to a Node.js server. I have tried many approaches, but most other answers on Stackoverflow centre around this idea, however it doesn't work for me:
saveImage: function(e) {
var canvas = document.querySelector('#canvasElement');
var base64 = canvas.toDataURL();
var image = 'image';
var object = {};
object[image] = base64;
console.log(object);
$.ajax({
url: '/save',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(object)
});
},

Syntax:Error JSON.parse, When trying to load data for protovis

Hi I'm learning how to work with protovis, so far so good, but now I stumbled upon a problem I can't seem to solve.
The following is the code. (I have the latest jquery loaded in my headers)
<script type="text/javascript+protovis">
var dataURL = "http://eagereyes.org/media/2010/protovis-primer/earthquakes.json";
var JSONdata = $.ajax({ type: "GET", url: dataURL, async: false }).responseText;
var earthquakes = JSON.parse(JSONdata);
var width = 560;
var height = 245;
var barWidth = width/earthquakes.length;
var gap = 2;
new pv.Panel().width(width).height(height+5)
.add(pv.Bar)
.data(earthquakes)
.bottom(0)
.width(barWidth-gap)
.height(function(d) d.Magnitude * (height/9))
.left(function() this.index * barWidth)
.root.render();
When I try this in Firefox i get this alert:
Syntax:Error JSON.parse
I have validated the JSON on http://www.jsonlint.com/ already. So the problem must be elsewhere.
Anyone knows whats going on here?
Edit
I tried loading the same data in the protoviewer app: http://www.rioleo.org/protoviewer/ and it works. So it must be the code.
Have you tried a regular async callback instead of the synchronous approach? Like:
var dataURL = "http://eagereyes.org/media/2010/protovis-primer/earthquakes.json";
$.ajax({
type: "GET",
url: dataURL,
success: function(response) {
var earthquakes = JSON.parse(JSONdata);
var width = 560;
var height = 245;
var barWidth = width/earthquakes.length;
var gap = 2;
new pv.Panel().width(width).height(height+5)
.add(pv.Bar)
.data(earthquakes)
.bottom(0)
.width(barWidth-gap)
.height(function(d) d.Magnitude * (height/9))
.left(function() this.index * barWidth)
.root.render();
}
});
Also, is that JSON file located on the same server that the page making the request shows in the address bar (exactly http://eagereyes.org)?
Finally, the manual JSON.parse() step isn't necessary. If you add the dataType: 'json' parameter, $.ajax() will automatically deserialize as JSON and uses JSON.parse() where available.
Add a semi-colon ; to the end of your response
Which browser are you using? Some browsers don't define the JSON object. You can download a script from the URL below which will define the JSON object if it doesn't already exist.
https://github.com/douglascrockford/JSON-js
You can check whether JSON is defined as follows:
alert(JSON);
update
OK next thing I'd do is check that the ajax call is actually returning the corect data. Change your code to print the JSON returned from the ajax call.
var JSONdata = $.ajax({ type: "GET", url: dataURL, async: false }).responseText;
alert(JSONdata);
var earthquakes = JSON.parse(JSONdata);
$.ajax({
type: "POST",
url: "saveChangesInEditing.php",
data: idObject,
success: function(data){
dataObject = JSON.parse(data);
$("input[name = 'id']").val(dataObject.id);
$("input[name='full_name']").val(dataObject.full_name);
$("input[name='sport']").val(dataObject.sport);
$("input[name='idol']").val(dataObject.idol);
},
error: function(data){
alert("error!" + data);
}
});

Categories

Resources