Node.js, socket.io and base64-to-image not working - javascript

I am using node.js and socket.io to transfer an image from a server to a client. These are my codes ,
renderer.js:
const imgFile = fs.readFileSync(screenShotPath);
const imgFile64 = new Buffer(imgFile).toString('base64');
console.log("image data:"+ imgFile64);
socket.emit('img', imgFile64);
receiver.js:
var base64ToImage = require('base64-to-image');
socket.on("img", function(info) {
console.log("inside receiver");
var base64Str = info;
var path = 'path to file';
var optionalObj = {'fileName': 'test', 'type':'png'};
var imageInfo = base64ToImage(base64Str,path,optionalObj);
});
I am getting an error stating 'Invalid base64 string'.
Can someone please help?

You can do that without base64-to-image
socket.on("img", function(info) {
console.log("inside receiver");
var base64Str = info;
var buff = new Buffer(base64Str ,"base64");
fs.writeFileSync("test.png", buff)
});
PS:
On the server side, you don't have to do new Buffer(imgFile) because imgFile is already Buffer

Related

Gcloud API file.save() data format

I'm using the gcloud API on a Nodejs web server to upload files. I'd prefer the files not be uploaded on the client side and instead uploaded on the server. Currently, I am producing a blob on the client side, then converting it to text and passing that to the server through a POST request. All of the information gets successfully passed from the client to the server as expected. This data is also uploaded to gcloud, however, Gcloud does not recognize this as a valid file nor does my computer when I download it.
What is the best way to get the contents of the file to gcloud from the server side? I've tried using dataURIs and reading the orignal file by text and both produce similiar issues. I've also explored piping a readFileStream from the blob on the server end but blobs are not natively supported by node so I have not done so yet.
Client Side
function readSingleFile(e, func, func2){
var file = e.target.files[0];
if(!file){
return; // Add error msg_here
}
var reader = new FileReader();
reader.onload = function(e){
let contents = e.target.result;
let img = document.createElement('img')
let cvs = document.createElement('canvas');
img.onload = ()=>{
cvs.width = img.width;
cvs.height= img.height;
let ctx = cvs.getContext('2d');
ctx.drawImage(img,0,0);
cvs.toBlob((res)=>{res.text().then((text)=>{func2(text)})}, "image/jpeg", 0.92);
}
img.src=contents;
func(contents);
}
reader.readAsDataURL(file);
}
Server Side
function publishPrintjob(dataObj){
try{
var newElemKey = database.ref().child('queue').push().key; // Get random Key
// Create a new blob in the bucket and upload the file data.
const gcloudFile = storage.file('images/' + newElemKey + '.jpg');
gcloudFile.save(dataObj.sockImageFile, function(err) {
if (!err) {
Console.log("File Uploaded!")
}
});
var data = {
date: dataObj.Date,
email: dataObj.email,
design: dataObj.Design,
author: dataObj.Author,
address: dataObj.address,
imageKey: newElemKey,
}
admin.database().ref('queue/' + newElemKey).set(data);
} catch(err){
console.log(err)
}
}
Note: func simply shows the image on the client side, func2 just adds the contents to the POST object.
Uploading a file directly from the computer would be easiest using the storage.bucket(bucketName).upload() function from the cloud storage library. However, this uses location of a file locally and thus will not work unless a file is transferred to the server and saved first. This could be achieved using multi-part form data. Using multipart or uploading locally are better methods for uploading to google storage.
Instead, I solve this by first converting the image to a dataURI, sending the data URI to the server via the body of a GET request, and then converting it to a buffer with a readable stream that can be piped to google storage.
Client
let formData = getFormData('myForm');
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// Typical action to be performed when the document is ready:
}
};
xhttp.open("POST", "dashboard", true);
xhttp.setRequestHeader('Content-Type', 'application/json');
xhttp.send(JSON.stringify(formData));
xhttp.onload = ()=> {
console.log(JSON.parse(xhttp.response))
// Handle server response here
};
}
Server
// DataObject is the body of the GET request, the property imageFile is the URI from readFileAsURI
function uploadImageOnServer(dataObj){
try{
var newElemKey = database.ref().child('queue').push().key; // Get random Key to use as filename
// Create a new blob in the bucket and upload the file data.
const gcloudFile = storage.file('images/' + newElemKey + '.jpeg');
var fs = require('fs'); // Should be required at the top of the file
var string = dataObj.ImageFile;
var regex = /^data:.+\/(.+);base64,(.*)$/;
var matches = string.match(regex);
var ext = matches[1];
var data = matches[2];
var buffer = Buffer.from(data, 'base64');
// Create the readstream
const readableInstanceStream = new Readable({
read() {
this.push(buffer);
this.push(null);
}
});
readableInstanceStream.pipe(gcloudFile.createWriteStream()) // link to gcloud storage api
.on('error', function(err) {
console.log('error')
})
.on('finish', function() {
console.log('upload complete')
});
} catch(err){
console.log(err)
}
}

fs readFilesync error path must be a string

i have a code for uploading file
here the code :
var oriPath = JSON.stringify(req.files.profilePicture);
var data = fs.readFileSync(oriPath.path);
var ext = path.extname(oriPath.name);
if (!ext) {
return next(err);
}
var newName = Date.now().toString() + ext;
var path = config.fullhostname + config.uploadDir + newName;
if (!fs.writeFileSync(path, data)) {
return next("Failed to upload image", 400)
}
and showing error like this : uncaughtException TypeError: path must be a string refers to var data = fs.readFileSync(oriPath.path);
but the file is successfuly uploaded, how to fix that? thank you
try to force string conversion:
var data = fs.readFileSync(String(oriPath.path))

Cannot open downloaded file from S3 with angular and NodeJS

I´m trying to download an jpg image from amazon S3 using the NodeJs SDK. I´m able to get the file object on the backend. However when I try to create a blob object and download it from angular, I cannot open the file. When I try to open it with any image editor I get an error as if the file is damaged or incorrectly formatted.
Here´s my Node JS code:
function downloadFile(file,callback) {
//Arranging file name
var fileKey = file.lifeCycle + "/" + file.id + "." + file.extension;
// download the file via aws s3 here
console.log('Trying to download file', file.id);
var AWS = require('aws-sdk');
var s3 = new AWS.S3();
var s3Params = {
Bucket: 'myBucket',
Key: fileKey
};
/*
res.attachment(fileKey);
var fileStream = s3.getObject(s3Params).createReadStream();
fileStream.pipe(res);
*/
s3.getObject(s3Params, function (err, data) {
if (err === null) {
res.send(data);
} else {
res.status(500).send(err);
}
callback(null);
});
}
});
The angular code:
vm.fileData = new ApiDownloadFile({fileId: 1});
vm.downloadFile = function(){
console.log("Downloading...");
vm.fileData.$query()
.then(function(response){
$log.log(response);
window.BlobBuilder = window.BlobBuilder ||
window.WebKitBlobBuilder ||
window.MozBlobBuilder ||
window.MSBlobBuilder;
console.dir(response.headers);
var blob = new Blob(response.Body.data,{type:response['content-type']});
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = "1.jpg";
link.click();
},function(err){
$log.log(err);
});
};
I solved the problem. The issue seemed to be with the Uint8 conversion.
I added this lines and it worked fine:
.then(function(response) {
try{
$log.log(response);
var arrayBufferView = new Uint8Array(response.Body.data); // Convert the response to fix the problem of opening the file
$log.log(arrayBufferView);
var file = new Blob( [arrayBufferView], {type: response.ContentType});

Web Audio API and Node.js

How would I correctly receive/send raw audio data?
I currently receive raw audio data over WebSockets (with Node.js) and write them to a file. Data is sent as byte[] array of 1024 byte in size from a Java client. Audio format is PCM, Mono, 16bit, 44100Hz.
I'm trying to pass on the raw audio data directly to browser, but it doesn't seem to work. What am I missing? Sorry for being new at this. The browsers I tested all support (Webkit) AudioContext. For each package received in browser, I get the following message:
Uncaught SyntaxError: An invalid or illegal string was specified. audio.php:19 1024
Node.js (server):
var WebSocketServer = require('ws').Server
, wss = new WebSocketServer({port: 8081});
var Clients = [];
function findClient(url) {
return (Clients.indexOf(url));
}
wss.on('connection', function(ws) {
Clients.push(ws);
console.log('Connected: %s', ws.upgradeReq.url);
console.log('Clients: %s', Clients.length);
ws.on('message', function(message, flags) {
if(flags.binary) {
ws.send(message, {binary:true});
}
console.log('data arrived: %s', message);
});
ws.on('close', function(user) {
console.log('Disconnected: %s', ws.upgradeReq.url);
Clients.splice(findClient(ws));
console.log('Clients: %s', Clients.length);
});
Client browser:
<script language="javascript">
if (window.webkitAudioContext) {
var ctx = new webkitAudioContext();
} else if (window.AudioContext) {
var ctx = new AudioContext();
}
function testSound(buff) {
var src = ctx.createBufferSource();
src.buffer = ctx.createBuffer(buff, false);
//src.looping = false;
src.connect(ctx.destination);
src.noteOn(0);
}
var ws = new WebSocket('ws://localhost:8081');
ws.binaryType = 'arraybuffer';
ws.onmessage = function(e) {
console.log(e.data.byteLength);
testSound(e.data);
}
</script>

Not able to load the response

var soapre1 = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:glob=\"http://sap.com/xi/SAPGlobal20/Global\">";
var soapre2 = "<soapenv:Header/><soapenv:Body><glob:EmployeeLeaveRequestByParticipantQuery><EmployeeLeaveRequestSelectionByParticipant><EmployeeLeaveRequestParticipantRoleCode listVersionID=\"?\">2</EmployeeLeaveRequestParticipantRoleCode>";
var soapre3 = "<!--Zero or more repetitions:--> <EmployeeLeaveRequestParticipantWorkAgreementIDInterval><IntervalBoundaryTypeCode>1</IntervalBoundaryTypeCode> <!--Optional:--> <LowerBoundaryWorkAgreementID schemeID=\"?\" schemeAgencyID=\"?\">1009</LowerBoundaryWorkAgreementID></EmployeeLeaveRequestParticipantWorkAgreementIDInterval>";
var soapre4 = " <!--Zero or more repetitions:--> </EmployeeLeaveRequestSelectionByParticipant></glob:EmployeeLeaveRequestByParticipantQuery> </soapenv:Body></soapenv:Envelope>";
var soapRequest = soapre1+soapre2+soapre3+soapre4;
var authstr = 'Basic ' +Titanium.Utils.base64encode('S0009231839'+':'+ 'm8390967743!');
var soapxhr = Ti.Network.createHTTPClient();
soapxhr.setRequestHeader('SOAPAction',soapRequest);
soapxhr.open("POST","http://erp.esworkplace.sap.com/sap/bc/srt/pm/sap/ecc_empleavereqparctqr/800/default_profile/2/binding_t_http_a_http_ecc_empleavereqparctqr_default_profile");
soapxhr.setRequestHeader('Authorization', authstr);
soapxhr.setRequestHeader('Content-Type','text/xml','charset=utf-8');
soapxhr.send();
soapxhr.onload = function(e)
{
Ti.API.info('abcd');
//get the xml data and let it roll!
var doc = this.responseXML;
Ti.API.info(doc);
}
soapxhr.onerror = function (e){
alert('Error');
Ti.API.info(e);
}
Unable to load the response Its directly getting error
[INFO] {
source = "[object TiNetworkClient]";
type = error;
}
Any one advice how to fix the issue!
# Thanks in advance
In all browser its saying error! but i found some wsdl and soap request so in order to open the response i need to pass the method name to the http request ! then it working

Categories