问题
Is there any way to write API which will convert normal image into Progressive Using Nodejs. I don't want to use Base64. I have done so much R & D on this. One library i found i.e lib turbo-jpeg But in this only they are decoding the image .I want to encode that image too. Please check this below link for reference. If anyone got any solution then please let me know.
Link is - https://github.com/LinusU/cwasm-jpeg-turbo
Please help me out to write API to convert image into progreesive.
Thank you in advance.
回答1:
You can use graphicsmagick with gm module to convert supported image formats to progressive JPEG.
Here's a simple example (tested on macOS with GraphicsMagick v1.3.31 and Node.js v10.15.3):
const fs = require('fs');
const path = require('path');
const https = require('https');
const gm = require('gm'); // https://www.npmjs.com/package/gm
const gmIdentify = gmInstance =>
new Promise((resolve, reject) => {
gmInstance.identify((err, data) => {
if (err) {
reject(err);
return;
}
resolve(data);
});
});
const gmStream = (gmInstance, writeStream, format = 'jpg') =>
new Promise((resolve, reject) => {
gmInstance
.stream(format)
.pipe(writeStream)
.once('finish', resolve)
.once('error', reject);
});
// This function downloads the file from the specified `url` and writes it to
// the passed `writeStream`.
const fetchFile = (url, writeStream) =>
new Promise((resolve, reject) => {
https.get(url, res => {
if (res.statusCode !== 200) {
reject(new Error('Something went wrong!'));
return;
}
res
.pipe(writeStream)
.once('finish', () => {
resolve();
})
.once('error', err => {
reject(err);
});
});
});
const main = async () => {
// Download a sample non-progressive JPEG image from the internet
const originalJpegUrl =
'https://upload.wikimedia.org/wikipedia/commons/b/b4/JPEG_example_JPG_RIP_100.jpg';
const originalPath = path.join(__dirname, './original.jpeg');
await fetchFile(originalJpegUrl, fs.createWriteStream(originalPath));
originalJpegData = await gmIdentify(gm(fs.createReadStream(originalPath)));
console.log(
`Interlace for the original jpeg file is set to ${
originalJpegData['Interlace']
}`,
);
// Convert the downloaded file to Progressive-JPEG
const progressiveJpegPath = path.join(__dirname, 'progressive.jpg');
await gmStream(
gm(fs.createReadStream(originalPath))
.interlace('line' /* or 'plane' */) // https://www.imagemagick.org/MagickStudio/Interlace.html
.quality(originalJpegData['JPEG-Quality']), // save with the same quality as the original file
fs.createWriteStream(progressiveJpegPath),
);
const progressiveJpegData = await gmIdentify(
gm(fs.createReadStream(progressiveJpegPath)),
);
console.log(
`Interlace for the converted jpeg file is set to ${
progressiveJpegData['Interlace']
}`,
);
};
main();
It downloads this non-progressive JPEG image and converts it to a progressive JPEG image and saves it as progressive.jpg
in the same directory as the script.
回答2:
If someone just like me c/p @fardjad's answer and came across the following error, for me (Ubuntu 16.04) just worked to change one line:
(node:14862) UnhandledPromiseRejectionWarning: Error: Could not execute GraphicsMagick/ImageMagick: gm "identify" "-ping" "-verbose" "-" this most likely means the gm/convert binaries can't be found
From:
const gm = require('gm'); // https://www.npmjs.com/package/gm
To:
const gm = require('gm').subClass({imageMagick: true});
来源:https://stackoverflow.com/questions/55789208/convert-normal-image-into-progressive-image-using-node-js