How to resize base64 image using gm - node.js

I can't seem to make it work to resize. How can I resize base64 image using gm?
I have the following code:
var regexBase64ContentType = /^data:image\/\w+;base64,/;
var buffer = new Buffer(imgData.replace(regexBase64ContentType, ""),'base64');
gm(buffer, "img.png")
.resize(height, width)
.toBuffer('PNG', function(err, buf){
return buf;
});

Related

Can GraphicsMagick for Node.js process a non-fixed number of images to output a GIF sequence?

I'm using GraphicsMagick for Node.js to generate a GIF sequence from 16 jpg images.
This works very well.
However currently I hardcoded the number of images in the sequence, when I use the function gm().in
I can't find a way or another function to make this number dynamic.
Here is my code:
var tmp_filenames = [];
var nNbStates = 16;
for (var nStateNum=0; nStateNum < nNbStates; nStateNum++)
{
tmp_filenames.push('mypath\myinputfilename' + nStateNum + '.jpg');
}
var gm = require('gm');
gm()
.in(tmp_filenames[0])
.in(tmp_filenames[1])
.in(tmp_filenames[2])
.in(tmp_filenames[3])
.in(tmp_filenames[4])
.in(tmp_filenames[5])
.in(tmp_filenames[6])
.in(tmp_filenames[7])
.in(tmp_filenames[8])
.in(tmp_filenames[9])
.in(tmp_filenames[10])
.in(tmp_filenames[11])
.in(tmp_filenames[12])
.in(tmp_filenames[13])
.in(tmp_filenames[14])
.in(tmp_filenames[15])
.write(output_filename, function (err) {
if (!err) console.log('gif file created!');
});
Thanks for reading.
OK I found a solution.
I was not familiar with this way of using variables and functions
This should work:
var tmp_filenames = [];
var nNbStates = 16;
var bmp = gm();
for (var nStateNum=0; nStateNum < nNbStates; nStateNum++)
{
tmp_filenames.push('mypath\myinputfilename' + nStateNum + '.jpg');
bmp.in(tmp_filenames[nStateNum])
}
.write(output_filename, function (err) {
if (!err) console.log('gif file created!');
});

Base64 image resizer nodejs

I am working on a node+express backend.
I am receiving base64 images string from API and I am storing it into MongoDB. Before storing I want to reduce the image size (scaling). I tried JIMP but it is not reading base64 input.
Can anyone please suggest any good node module which accepts base64 image, scale it and return a new base64 string.
Thanks
A little late but I just implemented this feature using the sharp library, so might as well share it now.
I created a function that takes a base64 and the height and width (optional) you want to resize the image to and returns the resized base64 string.
I can just call this function whenever I want.
Code
// Don't forget to import sharp
import sharp from "sharp"
export const resizeBase64 = async ({ base64Image, maxHeight = 640, maxWidth = 640 }) => {
const destructImage = base64Image.split(";");
const mimType = destructImage[0].split(":")[1];
const imageData = destructImage[1].split(",")[1];
try {
let resizedImage = Buffer.from(imageData, "base64")
resizedImage = await sharp(resizedImage).resize(maxHeight, maxWidth).toBuffer()
return `data:${mimType};base64,${resizedImage.toString("base64")}`
} catch (error) {
throwError({ error })
}
};
You can still use JIMP, but all you need to do is to drop the prefix before reading the base64.
Depend on your image format use a specific jpg or png in the following example.
Example:
Jimp.read(Buffer.from((yourImageBuffer).replace(/^data:image\/png;base64,/, ""), 'base64'), function (err, image) {
// Do you stuff here with the image
})
....some logic....
let max_width = 371;
let max_height = 280;
var image = new Image();
image.src = YOUR_BASE64_STRING;
let image_width = image.width;
let image_height = image.height;
let ratio = 1;
if(image_width > max_length || image_height > max_length){ //need to scale
ratio = max_length / image_width;
if(image_height > image_width){
ratio = max_length / image_height;
}
}
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
canvas.width = image_width * ratio; // target width
canvas.height = image_height * ratio; // target height
ctx.drawImage(image,
0, 0, image.width, image.height,
0, 0, canvas.width, canvas.height
);
var RESIZED_BASE64_STRING = canvas.toDataURL();
....some logic....

Capture and save image with robotjs

I tried to capture and save an image from screen with robotjs (http://robotjs.io/) but when I open the file bitmap the image is not in a valid format. This is my code:
var robot = require("robotjs");
var fs = require("fs");
var size = 10;
var img = robot.screen.capture(0, 0, size, size);
fs.writeFileSync('img.bmp',img.image);
Jimp supports converting Raw Pixel Buffer into PNG out-of-the-box and works a lot faster.
let robot = require("robotjs");
let Jimp = require('jimp');
const img = robot.screen.capture(0, 0, width, height).image;
new Jimp({data: img, width, height}, (err, image) => {
image.write(fileName);
});
The image will be saved with the wrong colors. To fix it, you can use the following code:
function screenCaptureToFile2(robotScreenPic, path) {
return new Promise((resolve, reject) => {
try {
const image = new Jimp(robotScreenPic.width, robotScreenPic.height);
let pos = 0;
image.scan(0, 0, image.bitmap.width, image.bitmap.height, (x, y, idx) => {
image.bitmap.data[idx + 2] = robotScreenPic.image.readUInt8(pos++);
image.bitmap.data[idx + 1] = robotScreenPic.image.readUInt8(pos++);
image.bitmap.data[idx + 0] = robotScreenPic.image.readUInt8(pos++);
image.bitmap.data[idx + 3] = robotScreenPic.image.readUInt8(pos++);
});
image.write(path, resolve);
} catch (e) {
console.error(e);
reject(e);
}
});
}
var pic = robot.screen.capture();
screenCaptureToFile2(pic)
Note that your img.image Buffer from Robotjs is a raw buffer with pixels; not a BMP or PNG or any other format.
You should do some data conversion and probably save it using a library that supports writing to file (I do not see that in Robotjs).
Please look at this other question, which also uses robot.screen.capture and saves file to a PNG file using Jimp library. That code answers your question too.

Get file size of GIFs with node-canvas?

After much struggling, I've managed to get node-canvas installed on Windows.
When I try to read in the image size of a GIF, however, it just gives me back 0 for the width and height.
var FileSystem = require('fs');
var Canvas = require('canvas');
FileSystem.readdir(baseDir, function(err, files) {
files.forEach(function(filename) {
var path = Path.join(baseDir, filename);
FileSystem.readFile(path, function(err, buf) {
var img = new Canvas.Image;
img.src = buf;
console.log(path, img.width, img.height);
});
});
Is it not supposed to be able to read GIFs?
You must install giflib and reinstall node-canvas like is said in here https://github.com/LearnBoost/node-canvas/wiki/Installation---OSX and then you will be able to manipulate your gif file (retrieve width/height). But beware, the image processed with canvas will stop being animated.

Image not saving on a Palm device

Updated: webOS version 2.1...
This base64 encoded image data generates the correct data image when I append it to the source of an image, like this:
var img = new Image();
img.src= data
var data = "data:image/png;base64,iVBORw0KGgoAAAANSUh
EUgAAAJYAAACmCAIAAAC3GeEYAAEkgklEQVR4AQD9/wIAADt8Fj5/GUSA IESAIEN/GUd/H0V+IEaEIE
WFHUOEHEqJIE2KIk2KI1GQKFSQLFaQKlaOKVaQKlORLlaYLVaVKFWV KVWUKliWKFiXJlKVIliTJW2oP
m6jOW+kPGqkPmehPWWePWagOmmjP2ykQ2ulQmylRWykQmqmP2qr QGqnP26qSGyvRmquQWyyQGquP2yu
RHSzSHWwSXGxSGytRG+vSG6vSW2vRWquRGqtRGmsQnO1R3Gw SG+rSXavUXWwUnKqR3CuRWquP26zQ3C
yRXK0SHG0SWupR2qoR3CuS2qrQ3CsSG6vS22pR26qSGyq RWetO22uQ2yqP22wRGetP2yyP4TEWgElAB
UrBRYmAx05AidHBB9MCydRDylSGChWGCZUFyFLEyNK Ex5IDBtJBhc/Bx9FDBxDDh5HDyRGExs8DRs4D
B04DRw8Exo6DxMuBw8kAhEeABIYAQ4VABAUAA0S AAwVAg8bAw0bAgwaAxAYAAULAQgQAQcQBQsPAAwQ
AggMAwMLAQAIAAgOBAYOAAsWBg4bChMgDxUk DxcmERopEh8vFBwuExspEhcnDxUpDhcqERUnDhUnDRQ
rDxgsERgvEx8xGQA+fxk7gxU9hBc9ghg/ gR1CgBxBhBtChRxIhyFMiyNMiyNNjiZNiypRkCpSjydRkC
VVkSpTkihYmi9YlC9XlCxVlClYlixW lSpZlS1eli16skJnqDxppj1qpDxmpD9mpD1loj1opz9qqENvq
Udpp0FmqD9npkFtpUVvp0ZvrUVs q0NsrEFtrURsrkBrsT9vskFvrj5srz5ssUJsrkJsrkNtr0NusEVm
qjxrrz5ttkNquEFqtEFu"
I am trying to save the image using my custom service, but it does not save the correct image. Here is the Node.js code for saving the image:
var fs = IMPORTS.require('fs');
var path = IMPORTS.require('path');
var buff = new Buffer(img.substr('data:image/png;base64,'.length), 'base64');
path.exists('/media/internal/wallpapers/', function(exists){
if (exists) {
var id = fs.openSync('/media/internal/wallpapers/i.png', 'w', 666);
var written = fs.writeSync(id, buff,0, buff.length, 0);
fs.closeSync(id);
}
});
The saved version of the image has totally different pixel values.
EDIT
I came to find out that the image data above isn't correct. I am using a PNG library to generate base64 image data of a canvas pixel array. The link is http://www.xarg.org/2010/03/generate-client-side-png-files-using-javascript/.
That is an alternative to canvas.toDataURL();. webOS does not support toDataURL, so I had to use a library.
Here is the code I have used with this library to manipulate my canvas image data as a pixel array:
EditorAssistant.prototype.getDataURL = function(width,height,pixelArray) {
var p = new PNGlib(height, width, 256); // Construcor takes height, weight and color-depth.
var background = p.color(0, 0, 0, 0);
var k = 0;
for (var j = 0; j<height; j++) {
for (var i =0; i<width; i++) {
var x =i;
var y =j;
p.buffer[p.index(x,y)] = p.color(pixelArray[k], pixelArray[k+1], pixelArray[k+2]);
k+=4;
}
}
return 'data:image/png;base64,'+p.getBase64() ;
}
Does this library work and where am I doing it wrong?
libpng.js only supports 256 color images, so that may be the problem. There are other base64 encoding utilities which may work as expected.

Resources