Hi Anders ,
I got the second code snippet I mention above exactly from that example, but I still don’t understand how to pass the JSON data to getImageFromBase64. To make it short, basically I don’t understand how to add that code to into the JSON fetching part so that I have this:
var base64Image = how_do_I_put_here_my_json_data_value?
I’m still getting mad with fetching and displaying a JSON object with base64 encode images in it. I understood how to display JSON data, I understood how to display base64 encoded images, but I don’t know how to put the two things together as I keep getting displayed always the LAST image found in the JSON data which is being replicated for every JSON entry. On the other hand the other JSON entries (title, description) are shown correctly.
The code should look like this, but there is actually a bug with this code. So it will overwrite the path all the time. There is already an issue here about it. I will see what we can do to get this fixed soon. You can also look into this thread for an alternate solution:
Oh, I understand… As explained by Karsten Nikolai in the link you provided:
«Images converted from Base-64 gets saved to a temporary location. The filenames are generated from timestamps with second resolution, which means that images overwrites each other if more than one is loaded within one second»
maybe adding to the generated name a 6 random characters string could be sufficient. I really hope this will be fixed.
To those who have ran into the same problem, the following code solves the issue (as suggested by Karsten Nikolai post mentioned by Anders above):
Add two requires:
var Base64 = require("FuseJS/Base64");
var FileSystem = require("FuseJS/FileSystem");
Remove all the ImageTools.getImageFromBase64({ }); part and replace it with the following code which decodes the base64 string to an ArrayBuffer and then it writes the returned buffer to a file:
var rndName = randomString(6) + ".jpg";
var buffer = new ArrayBuffer(4);
var buffer = Base64.decodeBuffer(item.imageencoded);
var fullImagePath = FileSystem.cacheDirectory + "/" + rndName;
FileSystem.writeBufferToFile(fullImagePath, buffer)
.then(function() {
item.image = fullImagePath;
datas.add(item);
//console.log("Successful write:" + fullImagePath);
}, function(error) {
//console.log(error);
});
Use this function to create a random filename:
function randomString(length) {
var result = '';
var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
for (var i = length; i > 0; --i) result += chars[Math.round(Math.random() * (chars.length - 1))];
return result;
}
This solution has also the advantage that your base64 encoded images (which are now converted to files) are correctly displayed in the emulator (local preview) which, at the time of writing, does not work when using ImageTools.getImageFromBase64.
I’m using deliberately .cacheDirectory because files in this directory are automatically removed when space is low. You can use .dataDirectory but remember that files in this directory are persistent so you need to remove them periodically.