Could not read data while printing image - GCP - javascript

I'm not able to print a base64 encoded image with GCP.
This is what I'm using :
var data = "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEBLAEsAAD//gBERmlsZSBzb3VyY ....";
var gadget = new cloudprint.Gadget();
gadget.setPrintButton(cloudprint.Gadget.createDefaultPrintButton("gcpPrint"));
gadget.setPrintDocument("image/jpeg", "JPG Image", data, "base64");
gadget.openPrintDialog();
As mentioned in the docs. But GCP could not read data. Any ideas?

Need to remove :
data:image/jpeg;base64,
from the base64 string.

Related

Javascript: Temporarily store and display image received from backend as binary data?

I am currently trying to display an image, which I receive from a backend server in a particular way/format, on the screen of the browser.
My problem is acutally closely related to this issue, for which no real answer exists.
Here is a screenshot displaying what the backend server's response looks like:
payload.data contains the data of the image, which is a green cloud (also attached at the end of this post for reference).
My first, probably very stupid, question would be: What kind of format/encoding is that?
Anyway, here is what I then further tried to process the data:
const blob = new Blob([action.payload.data], { //contains the data
type: action.payload.headers["content-type"] // 'image/png'
})
console.log("blob: ", blob);
const url = URL.createObjectURL(blob);
console.log("url : ", url)
As a result, the blob is sucessfully created, as well as the url. However, when I open that link, no image gets displayed.
I am stuck here and would appreaciate any kind of helpful hint pointing out where I am doing a mistake here.
Thanks very much for your support in advance.
PS: As promised, here is the actual png image:
It seems like your data attribute is still in binary format. You need to convert the hex into base64 in order to display the image.
First, if the server you're fetching the image form is yours, I would recommend encoding the image on the server before sending it to the client.
If the server is not yours and you can't change the data that is being returned, try something like this:
function hexToBase64(str) {
return btoa(String.fromCharCode.apply(null, str.replace(/\r|\n/g, "").replace(/([\da-fA-F]{2}) ?/g, "0x$1 ").replace(/ +$/, "").split(" ")));
}
And then use it like this:
const img = document.createElement('img');
img.src = 'data:image/jpeg;base64,' + hexToBase64('your-binary-data');
document.body.appendChild(img);
reference: How to display binary data as image - extjs 4

Encoding and Decoding png in base64

I am trying to format an uploaded .png file in my angular front-end so that it can be stored in a database. I am having some issues which I have replicated in this single function. I am taking the data field passed into this function, which represents the png file and encoding it in base64. However, I can't tell if it is working. In this example, I encode the item and then instantly decode it, but the outputs don't equal each other?
addImage(data: any): Observable<File> {
console.log('original', data);
const encodedImg: Image = new Image();
encodedImg.img = {data: btoa(data), contentType: 'image/png'};
console.log('encoded', encodedImg);
console.log('final', atob(encodedImg.img.data), encodedImg.img.contentType);
return this.http.post<File>('/api/image', encodedImg);
}

How to convert a URI to Blob and vice versa?

I need to convert this assetUrl into a Blob file. I tried in this way:
var dataUriToBlob = require('data-uri-to-blob');
var assetBlob = dataUriToBlob(assetUrl);
console.log("assetBlobTIPO", typeof assetBlob)
the console.log says assetBlob is NaN. Not sure it is correct.
Then i also need to convert the Blob file i get from the database into, back to a Uri file, so I can display it in my application when i click on it.
Any solution?

How to decode base64 to image file in Node.js?

I know this question is asked several times, but unfortunately nothing seems to work for me.
I post the src of an img to my node/express. It looks like this:
data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD//gA+Q1JF ... UUUUAFFFFAH/2Q==
The data is saved in picture. I cut of the data:image-stuff and got the raw base64 and the filetype.
var result = {
"type":"",
"data":""
}
var matches = picture.match(/^data:image\/([A-Za-z-+\/]+);base64,(.+)$/),response = {};
result.type = matches[1];
result.data = new Buffer(matches[2], 'base64');
require('fs').writeFile(mediaFolder+'/test.'+result.type, result.data, "binary", function(err){
res.status(500).send("error");
});
res.status(200).send("success");
When I try to open the saved image it says: Damaged or too big. I also tried to set the "binary" parameter in the writeFile methode. The client always gets the 200 http status.
I don't know what's wrong with this. I checked the raw base64 String with an online decoder. It worked perfectly.
I logged every string/match and everything looked okay to me.
Any help would be nice to solve this Problem.
Thanks in advance!
EDIT:
This is how I send the picture:
var base64Image = $('#show-picture').attr('src');
xmlhttp.open("POST","/webapp-ajax",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("picture="+base64Image);
I believe you need to use encodeUriComponent(base64) before sending to server.
try sending a JSON object, and parsing the image on the client side.
For example:
var mimeType = image.split(';')[0];
var base64 = encodeUriComponent(image.split(',')[1]);
var imageData = {
"mimeType" : mimeType,
"src" : base64
}
...
xmlhttp.setRequestHeader("Content-type","application/json");
xmlhttp.send(imageData);

Saving byteArray to pdf file in Titanium

I have a SOAP API that is returning me a file divided in chunks encoded in several base64 strings
i'm not being able to save it to the file system without breaking it
This is the pastebin of a whole file encoded, as is, once i download and chain the responses.
What is the way to save it correctly?
i tried in many ways
var f = Ti.FileSystem.getFile(Ti.FileSystem.tempDirectory, 'test.pdf');
...
var blobStream = Ti.Stream.createStream({ source: fileString, mode: Ti.Stream.MODE_READ });
var newBuffer = Ti.createBuffer({ length: fileString.length });
f.write(fileString);
or
var data = Ti.Utils.base64decode(fileString);
var blobStream = Ti.Stream.createStream({ source: data, mode: Ti.Stream.MODE_READ });
var newBuffer = Ti.createBuffer({ length: data.length });
var bytes = blobStream.read(newBuffer);
f.write(fileString);
or
var data = Ti.Utils.base64decode(fileString);
var blobStream = Ti.Stream.createStream({ source: data, mode: Ti.Stream.MODE_READ });
var newBuffer = Ti.createBuffer({ length: data.length });
var bytes = blobStream.read(newBuffer);
f.write(bytes);
but i'm not understanding which one is the right path
Do I have to convert back to byteArray the string on my own?
What is the right way to save it?
Do I have to create a buffer from the string or ...?
I think that the base64enc for the file is not valid or incomplete, I've tested it using bash and base64 utils. You can perform these steps.
Copy and paste the base64 string on a file called pdf.base64 then run this command:
cat pdf.base64 | base64 --decode >> out.pdf
the output file is not a valid pdf.
You can try to encode and decode a valid pdf file to take a look at the generated binary:
cat validfile.pdf | base64 | base64 --decode >> anothervalidfile.pdf
Try to check if you are chainig chunks correctly or simply make a phone call with the guy who build the soap api.
Before you start downloading your file you need to create the file stream to write too, writing to a blob is not the way to go:
// Step 1
var outFileStream = Ti.Filesystem.getFile('outfile.bin').open(Ti.Filesystem.MODE_WRITE);
After creating your HTTPClient or socket stream and when you receive a chunk of Base64 data from the serve, you need to put that decoded data into a Titanium.Buffer. This would probably go into your onload or onstream in an HTPPClient, :
// Step 2
var rawDecodedFileChunk = Ti.Utils.base64decode(fileString);
var outBuffer = Ti.createBuffer({
byteOrder : // May need to set this
type : // May also need to set this to match data
value: rawDecodedFileChunk
});
Finally you can write the data out to the file stream:
// Step 3
var bytesWritten = outFileStream.write(outBuffer); // writes entire buffer to stream
Ti.API.info("Bytes written:" + bytesWritten); // should match data length
if(outBuffer.length !== bytesWritten) {
Ti.API.error("Not all bytes written!");
}
Generally errors come from having the wrong byte order or type of data, or writing in the wrong order. Obviously, this all depends on the server sending the data in the correct order and it being valid!
You may also want to consider the pump command version of this, which allows you to transfer from input stream to output file stream, minimizing your load.

Categories