I want to save received base64 string in mysql table in a BLOB field. I have used sequelize version 5 as my ORM and the model is defined as follows.
sequelize.define('PLAYER', {
player_id: {
primaryKey: true,
type: DataTypes.INTEGER,
allowNull: false,
autoIncrement: true
},
player_name: DataTypes.STRING,
player_image: {
type: DataTypes.BLOB('medium'),
get () {
let data = this.getDataValue('player_image');
return data ? data.toString('base64') : '';
}
}
}
In my put method,
db.PLAYER.findByPk(req.params.playerId).then((player)=>{
if (req.body.player_image) {
const base64 = req.body.player_image.replace(/^data:image\/[a-z]+;base64,/, "");
const blob = b64toBlob(base64, 'image/jpeg');
player.player_image = blob;
}
player.player_name = req.body.player_name;
player.save().then(() => {
res.status(200).json(player);
}).catch(function (err) {
return next(err);
});
});
For Base64 to Blob conversion.
const b64toBlob = (b64Data, contentType = '', sliceSize = 512) => {
const byteCharacters = atob(b64Data);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, { type: contentType });
return blob;
}
A blob is saving in the table but my response body is as follows. I have converted BLOB to base64 before sending the response.
{
"player_id": 1032,
"player_name": "Oliver Driscoll",
"player_image": "[object Blob]"
}
Which means the saved blob is actually "[object Blob]". Not the image.
The received base64 (req.body.player_image
) for the end point is confirmed as correct. I am running out of time and don't know what to do as this is the requirement (Saving the image as blob).
I Know, this is a old issue. But i had this same problem, and after so many tries, i was able to solve it. So, if anyone have this problem in the future, i will let my solution here:
In my case i was able to get a Blob already, from a fetch response. So i have in my code like this:
await fetch(imageUrl)
.then(async (response) => {
// GET Blob Object from response; can use response.arrayBuffer() directly too
let myBlobImg = await response.blob();
// Convert Blob.ArrayBUffer to a Buffer
let myBufferImg = Buffer.from(await myBlobImg.arrayBuffer());
})
Then i just save myBufferImg
on DB, as a Buffer. In your case @silent_27 could be
player.player_image = Buffer.from(await myBlobImg.arrayBuffer());
I'm using SQlite3 DataBase on NodeJS with sqlite3^5.0.1 package.
I save like this on my dataBase and works fine. I've tried save like myBlobImg.text();
. But this away, i was not able to load on a <img src={}>
html tag in my application.
If anyone need to know, to show this BLOB on a <img>
HTML, i just do a get on my DB to get my ProductObject and convert to a base64 image:
// imageData is the Buffer saved on BD. imageData.data is an Array from Buffer
let imgBase64 = Buffer.from(product.productImage.imageData.data).toString('base64');
imgBase64 = `data:image/jpeg;base64,${imgBase64}`;
//....
<img src={imgBase64}>
I Had to use Buffer.from
again otherwhise if i just use like
let imgBase64 = product.productImage.imageData.toString('base64');
the imgBase64 would be "[Object ojbect]