How to read and save base64 image with fs - javascript

I am creating an api node that on the front end (it is separate from the api, I am using fetch to send the data) I am selecting a jpg file and sending in base64 form to the api, I usually receive the base64 in the controller with "var imagem = req.body.imagem; ". I need now to take this base64 and turn it into an image to save in the ../../public/img directory. How could I do that?
const mongoose = require('mongoose');
const Cup = require('../models/Cup');
module.exports = {
//listagem
async index(req, res) {
const cups = await Cup.find();
return res.json(cups);
},
//criaçao
async store(req, res) {
var nome = req.body.nome;
var caminho = req.body.caminho;
var tema = req.body.tema;
var imagem = req.body.imagem;
const cup = await Cup.create({
nome: nome,
caminho: caminho,
tema: tema
});
return res.json(cup);
}
}

You can convert an image from a base64 representation to its binary representation by converting the string to a Buffer - new Buffer(b64_image, 'base64') (read more on this in this answer). You can then save the buffer to the local filesystem using either fs.writeFile (in case you'd like to save the file asynchronously) or fs.writeFileSync (in case you'd like to save the file synchronously).
What you're trying to do could be accomplished with something like this:
const fs = require("fs");
const base64Image = "BASE_64_IMAGE";
const imageBuffer = new Buffer(base64Image, "base64");
fs.writeFileSync("image.png", imageBuffer);

Related

How can I display an Image without downloading it from a url in NodeJS?

In NodeJS I used package named node-fetch, also for taking JSON Response, but how about an Image response? How can I do that? In my current codes, It does only save the image not showing like PIL from python.
var tr = "https://i.picsum.photos/id/866/200/300.jpg?hmac=rcadCENKh4rD6MAp6V_ma-AyWv641M4iiOpe1RyFHeI"
export async function get_image() {
const get_url = await fetch(tr)
const image = get_url.body.pipe(fs.createWriteStream('./image.png'))
}
await get_image();
You can get an image in Base64 format and save it in a variable using the axios module like so:
const axios = require('axios')
const imageURL = 'https://i.picsum.photos/id/866/200/300.jpg?hmac=rcadCENKh4rD6MAp6V_ma-AyWv641M4iiOpe1RyFHeI';
(async ()=>{
// Get image Buffer from url and convert to Base64
const image = await axios.get(imageURL, {responseType: 'arraybuffer'});
const base64Image = Buffer.from(image.data).toString('base64');
// Do stuff with result...
console.log(base64Image);
})();
// Or if you prefer, a one liner
(async ()=>{
const base64Image = Buffer.from((await axios.get(imageURL, {responseType: 'arraybuffer'})).data).toString('base64');
})();
You can check if it worked by using a website to decode the base64 string into an image.

Downloading an Azure Storage Blob using pure JavaScript and Azure-Storage-Js

I'm trying to do this with just pure Javascript and the SDK. I am not using Node.js. I'm converting my application from v2 to v10 of the SDK azure-storage-js-v10
The azure-storage.blob.js bundled file is compatible with UMD
standard, if no module system is found, following global variable
will be exported: azblob
My code is here:
const serviceURL = new azblob.ServiceURL(`https://${account}.blob.core.windows.net${accountSas}`, pipeline);
const containerName = "container";
const containerURL = azblob.ContainerURL.fromServiceURL(serviceURL, containerName);
const blobURL = azblob.BlobURL.fromContainerURL(containerURL, blobName);
const downloadBlobResponse = await blobURL.download(azblob.Aborter.none, 0);
The downloadBlobResponse looks like this:
downloadBlobResponse
Using v10, how can I convert the downloadBlobResponse into a new blob so it can be used in the FileSaver saveAs() function?
In azure-storage-js-v2 this code worked on smaller files:
let readStream = blobService.createReadStream(containerName, blobName, (err, res) => {
if (error) {
// Handle read blob error
}
});
// Use event listener to receive data
readStream.on('data', data => {
// Uint8Array retrieved
// Convert the array back into a blob
var newBlob = new Blob([new Uint8Array(data)]);
// Saves file to the user's downloads directory
saveAs(newBlob, blobName); // FileSaver.js
});
I've tried everything to get v10 working, any help would be greatly appreciated.
Thanks,
You need to get the body by await blobBody.
downloadBlobResponse = await blobURL.download(azblob.Aborter.none, 0);
// data is a browser Blob type
const data = await downloadBlobResponse.blobBody;
Thanx Mike Coop and Xiaoning Liu!
I was busy making a Vuejs plugin to download blobs from a storage account. Thanx to you, I was able to make this work.
var FileSaver = require('file-saver');
const { BlobServiceClient } = require("#azure/storage-blob");
const downloadButton = document.getElementById("download-button");
const downloadFiles = async() => {
try {
if (fileList.selectedOptions.length > 0) {
reportStatus("Downloading files...");
for await (const option of fileList.selectedOptions) {
var blobName = option.text;
const account = '<account name>';
const sas = '<blob sas token>';
const containerName = '< container name>';
const blobServiceClient = new BlobServiceClient(`https://${account}.blob.core.windows.net${sas}`);
const containerClient = blobServiceClient.getContainerClient(containerName);
const blobClient = containerClient.getBlobClient(blobName);
const downloadBlockBlobResponse = await blobClient.download(blobName, 0, undefined);
const data = await downloadBlockBlobResponse.blobBody;
// Saves file to the user's downloads directory
FileSaver.saveAs(data, blobName); // FileSaver.js
}
reportStatus("Done.");
listFiles();
} else {
reportStatus("No files selected.");
}
} catch (error) {
reportStatus(error.message);
}
};
downloadButton.addEventListener("click", downloadFiles);
Thanks Xiaoning Liu!
I'm still learning about async javascript functions and promises. Guess I was just missing another "await". I saw that "downloadBlobResponse.blobBody" was a promise and also a blob type, but, I couldn't figure out why it wouldn't convert to a new blob. I kept getting the "Iterator getter is not callable" error.
Here's my final working solution:
// Create a BlobURL
const blobURL = azblob.BlobURL.fromContainerURL(containerURL, blobName);
// Download blob
downloadBlobResponse = await blobURL.download(azblob.Aborter.none, 0);
// In browsers, get downloaded data by accessing downloadBlockBlobResponse.blobBody
const data = await downloadBlobResponse.blobBody;
// Saves file to the user's downloads directory
saveAs(data, blobName); // FileSaver.js

writefile with fs, nodejs and express

I'm trying to save an image on the server with fs.writefile and base64, it can write and save the image in the correct directory but the image is blank and says "no support this type of file".
my server function:
let base64 = '';
let file = req.body.arquivo
let reader = new FileReader()
reader.onloadend = function(){
base64 = reader.result
}
let img = base64.replace(/^data:image\/\w+;base64,/, "");
let buffer = new Buffer(img, "base64")
fs.writeFile(`./public${caminho}${nome}`, buffer, (err) => {console.log(err)});
const candy = await Candy.create({
nome: nome,
doce: doce,
caminho: caminho,
tema: tema
});
return res.json(candy);
},
here is when I open the image in the directory that was saved:

How to upload image to S3 using Node

I am writing an Express app that takes in a base64 encoded string that represents an image. Right now, i'm not really sure how I can take that string and upload the image to AWS S3, so i'm reading in the encoded image string data, decoding it, writing a file using fs, and then trying to upload. I have this working for an endpoint that just takes in a raw file, and all of its content is correctly uploaded to AWS s3.
Now when I try to do what I described above, i'm able to upload to S3, but the file has 0kb and is empty, and i'm not sure why. I tested just taking the stringData and writing a file to a test file, and it works. However, when I try uploading to s3, the file shows but it's empty. Here is my code:
router.post('/images/tags/nutritionalInformation/image/base64encoded', function (req, res) {
console.log(req.body.imageString);
var base64Stream = req.body.imageString;
var imgDecodedBuffer = decodeBase64Image(base64Stream);
console.log(imgDecodedBuffer);
// write to image file
var prefix = guid().toString() + ".jpg";
var filePath = './uploads/' + prefix;
console.log(filePath);
fs.writeFile(filePath, imgDecodedBuffer.data, function(err) {
console.log(err);
});
var stream = fs.createReadStream(filePath);
console.log(stream);
return s3fsImpl.writeFile(prefix, stream).then(function () {
fs.unlink(filePath, function (err) {
if (err) {
console.error(err);
}
});
});
})
Here are the relevant import statements:
var fs = require('fs');
var s3fs = require('s3fs');
var multiparty = require('connect-multiparty'),
multipartyMidleware = multiparty();
var s3fsImpl = new s3fs('blahblah', {
accessKeyId: 'ACCESS_KEY_ID',
secretAccessKey: 'SECRET'
});
Any help would be greatly appreciated!
If you simply just pass in the buffer, which I presume is in your imgDecodedBuffer.data value, it should work.

ReadFile in Base64 Nodejs

I'm trying to read an image from client side encoded in base64.
How to read with nodejs?
My code:
// add to buffer base64 image
var encondedImage = new Buffer(image.name, 'base64');
fs.readFile(encondedImage, "base64", function(err, buffer){
if ( err ) {
console.log('In read file')
console.log(err)
} else {
// check err
lwip.open(buffer, 'jpg', function(err, image){
console.log('in open')
if ( err ) console.log(err)
if ( image ) console.log(image)
// check 'err'. use 'image'.
// image.resize(...), etc.
});
}
})
But, I got this error:
In read file
[Error: Path must be a string without null bytes.]
Latest and greatest way to do this:
Node supports file and buffer operations with the base64 encoding:
const fs = require('fs');
const contents = fs.readFileSync('/path/to/file.jpg', {encoding: 'base64'});
Or using the new promises API:
const fs = require('fs').promises;
const contents = await fs.readFile('/path/to/file.jpg', {encoding: 'base64'});
I think that the following example demonstrates what you need:
I removed the link because it was broken.
The essence of the article is this code part:
var fs = require('fs');
// function to encode file data to base64 encoded string
function base64_encode(file) {
// read binary data
var bitmap = fs.readFileSync(file);
// convert binary data to base64 encoded string
return new Buffer(bitmap).toString('base64');
}
// function to create file from base64 encoded string
function base64_decode(base64str, file) {
// create buffer object from base64 encoded string, it is important to tell the constructor that the string is base64 encoded
var bitmap = new Buffer(base64str, 'base64');
// write buffer to file
fs.writeFileSync(file, bitmap);
console.log('******** File created from base64 encoded string ********');
}
// convert image to base64 encoded string
var base64str = base64_encode('kitten.jpg');
console.log(base64str);
// convert base64 string back to image
base64_decode(base64str, 'copy.jpg');
var fs = require('fs');
function base64Encode(file) {
var body = fs.readFileSync(file);
return body.toString('base64');
}
var base64String = base64Encode('test.jpg');
console.log(base64String);
The following code reads a text file. Then converts it to text, then reads it as base64 and puts that into a binary buffer, and saves it back to a true binary.
import { readFileSync, writeFileSync } from 'fs'
import { tmpdir } from 'os'
const contents = readFileSync('./temp.txt')
const buffedInput = Buffer.from(contents.toString(), 'base64')
writeFileSync(`${tmpdir}/temp.zip`, buffedInput)

Categories