Sending image from server to client via base64 encoding - javascript

I'm facing an issues sending an Image (np.ndarray) over my python server to my javascript client.
Starting with the python server, I process the img like this:
1) Load img as np.ndarray
2) enc_img = base64.b64encode(img.copy(order='C'))
3) utf8_img = enc_img.decode("utf-8")
4) json = {
...
"img": utf8_img,
...
}
5) req_return = json.dumps(json, ensure_ascii=False)
// The fct below I found on SO ..
For the client (javascript) I do the following:
function b64EncodeUnicode(str) {
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
return String.fromCharCode(parseInt(p1, 16))
}))
}
img_64 = b64EncodeUnicode(jsonRes.fs_dict.face)
var src = "data:image/jpg;base64,";
src += img_64;
var newImage = document.createElement('img');
newImage.src = src;
newImage.width = newImage.height = "100";
document.querySelector('#face_img').innerHTML = newImage.outerHTML;
To sum it up, I want to send an image over the API and convert it into a valid base64 format to display via html. After experimenting a little I sometimes got "no valid base64 format" but with the provided code I'm not getting any error. The image doesn't show up though.
It is important to not save the file in my scenario.

So I figured the problem. I had troubles encoding the image (nparray) to a proper base64 encoding.
pil_img = Image.fromarray(nparray_img)
buff = BytesIO()
pil_img.save(buff, format="JPEG")
enc_img = base64.b64encode(buff.getvalue()).decode("utf-8")
this resolved the encoding issues for me.
I then return a dictionary containing the img like so:
res = {
"img": enc_img
}
return res
After converting it to JSON via
json.dumps(res), I send it via the API to my JavaScript Client.
When receiving the JSON, I first parse it to access the dictionary again like so:
jsonRes = JSON.parse(xhr.responseText);
img = jsonRes.img;
and finally output it via HTML by using jQuery:
var source = "data:image/jpg;base64,";
source += img;
$(document).ready(function() {
$('#face_img').attr('src',source).height(100).width(100).show();
});
The
('#face_img')
is an ID of my HTML, looking like the following:
<img id="face_img" src="" alt="img_face" />
Hope this helps someone.

Related

How to read remote image to a base64 data url

actually there are many answers for this question. But my problem is,
i want to generate pdf dynamically with 5 external(URL) images. Im using PDFmake node module.
it supports only two ways local and base64 format. But i don't want to store images locally.
so my requirement is one function which takes url as parameter and returns base64.
so that i can store in global variable and create pdfs
thanks in advance
function urlToBase(URL){
return base64;
}
var img = urlToBase('https://unsplash.com/photos/MVx3Y17umaE');
var dd = {
content: [
{
text: 'fjfajhal'
},
{
image: img,
}
]
};
var writeStream = fs.createWriteStream('myPdf.pdf');
var pdfDoc = printer.createPdfKitDocument(dd);
pdfDoc.pipe(writeStream);
pdfDoc.end();
im using PDFmake module from npm
The contents of the remote image can first be fetched with an HTTP request, for example using the ubiquitous request npm module. The image string contents can then be transformed to a buffer and finally converted to a base64 string. To complete the transformation, add the proper data-url prefix, for example, data:image/png,base64, to the beginning of the base64 string.
Here is a rough example for a PNG image:
const request = require('request-promise-native');
let jpgDataUrlPrefix = 'data:image/png;base64,';
let imageUrl = 'https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png';
request({
url: imageUrl,
method: 'GET',
encoding: null // This is actually important, or the image string will be encoded to the default encoding
})
.then(result => {
let imageBuffer = Buffer.from(result);
let imageBase64 = imageBuffer.toString('base64');
let imageDataUrl = jpgDataUrlPrefix+imageBase64;
console.log(imageDataUrl);
});

Use image data from XMLHttpRequest responsetext to display image

I'm using JavaScript to get an image from the XMLHttpRequest response text and set the image src to it:
document.getElementById("img").src = "data:image/png;base64," + xhr.responseText;
From the nodejs script, the image is sent like:
var img = fs.readFileSync('image.png');
res.end(img, 'base64');
The response text doesn't come in base64 and has weird symbols:
�PNG���IHDR���������,���2PLTE
�������������������������#����Ai���
...
I found this question and tried to convert it to base 64:
for (var responseText = xhr.responseText, responseTextLen = responseText.length, bin = "", i = 0; i < responseTextLen; ++i) {
bin += String.fromCharCode(responseText.charCodeAt(i) & 255);
}
document.getElementById("img").src = "data:image/png;base64," + btoa(bin);
The result was:
img id="img"
src="data:image/png;base64,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">
The image still doesn't show. What am I doing wrong?
It sounds like you're looking for buf.toString([encoding][, start][, end]).
Consider the following code:
var fs = require('fs');
var base64_image = fs.readFileSync('image.png').toString('base64');
console.log(base64_image);
This will return image.png as a base64 encoded string in the console.
So you probably want to remove that for () loop and change:
var img = fs.readFileSync('image.png');
To this:
var img = fs.readFileSync('image.png').toString('base64');
I hope that helps!
As Dal suggested, I did the base64 encoding on the server side:
var img = fs.readFileSync('plot.png', 'base64');
res.end(img);
I added the 'base64' encoding option to the readFileSync() instead of the res.end() so img would get sent as a string instead of a buffer as described here.
On the client side, I used this:
document.getElementById("img").src = "data:image/png;base64," + xhr.responseText;

JavaScript: Decompressing GZipped response. Works in C# not in JS

I'm getting gzipped data from a business api i'm working with, but I can't manage to decompress it into something readable in JS, though I managed with C#.
My question is - how do I unzip the received gzipped input to a string or json?
The following code works well for me in C#:
using (HttpWebResponse response = (HttpWebResponse)WebRequest.Create(url).GetResponse())
{
using (GZipStream decompress = new GZipStream(response.GetResponseStream(), CompressionMode.Decompress))
{
using (StreamReader reader = new StreamReader(decompress))
{
responseFromServer = reader.ReadToEnd();
}
}
}
I've read various answers and tried some libraries but still can't manage to decompress it in JS (using same URL).
This is where the code should be in JS:
var requestData = {
url: url,
headers: {
"Allow-Encoding": "gzip"
}
}
request.get(requestData, function(error, response, body) {
// compressed data is in body
});
I've tried pako, zlib but I am probably not using them correctly.
[edit]
Some of my tries:
// Decode base64 (convert ascii to binary)
var strData = new Buffer(body).toString('base64');
// Convert binary string to character-number array
var charData = strData.split('').map(function (x) { return x.charCodeAt(0); });
// Turn number array into byte-array
var binData = new Uint8Array(charData);
// Pako magic
var data = pako.inflate(binData);
// Convert gunzipped byteArray back to ascii string:
var strData2 = String.fromCharCode.apply(null, new Uint8Array(data));
This code is running in a NodeJS application, and i'm using request package
Thanks

Node base64 encode doesn't give whole string

Good day,
I am having a weird issue with Node, I am encoding a file as Base64 and albeit it works for most of my PDFs that I am encoding, one in particular doesn't output the whole base64 string.
The actual b64 string starts like this: "JVBERi0xLjMKJf////8KNiAwIG9i..." but I only get "JVBERi0xLjMK"
Here is my code:
function sendPDF() {
// Grab the final PDF
require('fs').readFile(transaction.deliverable, function (err, data) {
if (err) {
console.log(err);
log(2, "Couldn't read: " + transaction.deliverable);
} else {
transaction.deliverable = new Buffer(data, 'binary').toString('base64');
//transaction.deliverable = data.toString('base64');
console.log(transaction.deliverable);
}
The commented out line was another attempt. The transaction structure is:
function Transaction(snapshot) {
var data = snapshot.val();
this.tid = snapshot.key();
this.request = data.request;
this.pages = [];
this.fileCount = 0;
this.deliverable = null;
this.fileName = "";
}
This transaction simple stores some information that I pull from Firebase however the important var, .deliverable is a string to the path of the PDF I need to encode and send.
I don't get any read errors when this happens, and the next transaction goes through this code block just fine, giving a full base64 string.
I was curious if my toString() was interpolating the base64 string, but then I thought I would have had larger problems earlier.
Any ideas? I can put this on hold and move on with my work but I would love to fix this.. Thank you.

Cropit upload canvas image to NodeJS

I am trying to upload a cropped image with the Cropit jQuery plugin which uses the canvas in the front end. Basically trying to recreate process described here:
How to crop and upload photo using cropit jquery plugin with php
My Node.js effort:
var img = //DATA RECEIVED FROM THE POST REQUEST
var decoded = decodeURIComponent(require('url').parse(img, true).path.replace(/\++/g, ' '))
var exp = decoded.replace('data:image/jpeg;base64','').split(',');
var base64 = exp.shift();
var data = base64url.decode(base64);
fs.writeFile('./public/woooo.jpg', data,function(err,done){
if (err){
console.log(err)
}
})
The result is an image file which cannot be opened. Why? What am I doing wrong? Anyone else has managed this?
Found it:
var decoded = decodeURIComponent(require('url').parse(img, true).path.replace(/\++/g, ' '))//base64url.decode(img);
var exp = decoded.split(',');
var base64 = exp.shift();
var data = base64url.decode(base64);
var data_c = data.replace('data:image/jpeg;base64,','')
var buffer = new Buffer(data_c, 'base64');
fs.writeFileSync('./public/woo.jpg', buffer);

Categories

Resources