使用node對圖像進行壓縮,我選用的是resize-optimize-images,能知道這個包還是非常巧合,網(wǎng)上的博客,適合node圖片壓縮的包有兩個: gm和images, images在win10中有很大的兼容性問題,而gm在electron中編譯一直失敗. 所以我在github上以images和resize為關(guān)鍵字,搜索結(jié)果中排名前三十的包全部試用了一遍,大部分在electron都存在問題,node-OpenCV是一個萬能的圖形庫, 但是十分臃腫, 正當(dāng)我準(zhǔn)備手?jǐn)]插值壓縮算法的時候,忽然發(fā)現(xiàn)了resize-optimize-images這個包非常小巧,而且正好能夠滿足要求
壓縮的基本思路是在圖片中找到相對比較短的邊, 以他為基準(zhǔn)壓縮到一個比較小的比例(如640*480),然后將原始圖片復(fù)制出來,再將壓縮后的圖片寫進去即可. 圖像的大小最終取決于三個因素:圖片像素、編碼質(zhì)量和位深度,圖形像素在執(zhí)行完這條個函數(shù)之后就達(dá)到一個比較小的范圍了,一般不會超過100k,而編碼質(zhì)量是一種類似于PS中表面模糊的效果,使用的是插值算法,一般編程80-90區(qū)間內(nèi)可以對圖像進行進一步的壓縮,但是不建議壓的太多,會失真。真彩色的位深度一般是四個字節(jié)
const fs = require('fs');
const getPixels = require("get-pixels") // 這是一個獲取圖片像素的node包
const resizeOptimizeImages = require('resize-optimize-images');
getPixels(fileAbPath, function (err, pixels) {
if (err) {
return
}
let compressRio = 0.9;
let [imageWidth, imageHeight] = pixels.shape
//找到比較小的邊
let loopVar = imageWidth > imageHeight ? imageHeight : imageWidth;
while (loopVar >= 480) {
loopVar = loopVar * compressRio;
imageWidth = imageWidth * compressRio;
imageHeight = imageHeight * compressRio;
}
imageWidth = Math.floor(imageWidth)
imageHeight = Math.floor(imageHeight)
const content = pixels.data
fs.writeFile(outPath, content, async function (err) {
const options = {
images: [outPath],
width: imageWidth,
height: imageHeight,
quality: 85
};
// 執(zhí)行壓縮.
await resizeOptimizeImages(options);
});
})