node.js - NodeJS Sharp 为 JPEG 图像提供了不正确的质量
问题描述
我正在sharp node package
计算图像的质量。
我在包中找不到任何可以计算质量的 API。
所以我想出了一个遵循以下步骤的实现 -
- 接受传入的图像缓冲区并创建清晰的实例
- 通过将 quality 设置为 100 从此实例创建另一个实例
- 比较原始锐器实例和新锐器实例的大小
- 如果大小有差异,请更新质量并使用更新的质量执行步骤 2
- 一旦第 4 步中的比较给出最小的差异,就返回质量
我使用已知质量的图像测试了这种方法,即 50(已确认)
编辑-I generated images with different quality values using Photoshop
但是,上述逻辑返回的质量为 82(预计接近 50)
问题
所以问题是我无法弄清楚图像的质量。
如果上述逻辑返回一个最接近的值,例如 49 或 51,则很好。
然而结果却完全不同。
结果
按照这个逻辑,我得到给定质量的以下结果 -
- 实际质量 50 - 结果 82
- 实际质量 60 - 结果 90
- 实际质量 70 - 结果 90
- 实际质量 80 - 结果 94
- 实际质量 90 - 结果 98
- 实际质量 100 -结果 98
代码
以下代码片段用于计算质量。
我确实理解需要改进才能获得精确的结果。
但它至少应该提供接近的价值。
async function getJpegQuality(image: sharp.Sharp, min_quality: number, max_quality: number): Promise<number> {
if (Math.abs(max_quality - min_quality) <= 1) {
return max_quality;
}
const updated_image: sharp.Sharp = sharp(await image.jpeg({ quality: max_quality }).toBuffer());
const [metadata, updated_metadata]: sharp.Metadata[] = await Promise.all([image.metadata(), updated_image.metadata()]);
// update quality as per size comparison
if (metadata.size > updated_metadata.size) {
const temp_max = Math.round(max_quality);
max_quality = Math.round((max_quality * 2) - min_quality);
min_quality = Math.round(temp_max);
} else {
max_quality = Math.round((min_quality + max_quality) / 2);
min_quality = Math.round((min_quality + max_quality) / 2);
}
// recursion
return await getJpegQuality(image, min_quality, max_quality);
}
用法
const image: sharp.Sharp = sharp(file.originalImage.buffer);
const quality = await getJpegQuality(image, 1, 100);
console.log(quality);
谢谢!
解决方案
推荐阅读
- mysql - 如何在 seqilize 中测量查询执行时间?
- arrays - EXCEL VLOOKUP - 从一个公式中提取多列
- php - Google Calendar API:未经授权的 WebHook 回调通道
- arrays - 自定义对象导出数组并添加到数组
- python - 加载 Tensorflow 模型时出现 KeyError u'ImageProjectiveTransform'
- django - D3v5 和 Django Rest 框架
- java - 如何在 Java 中遍历每个纬度/经度
- python - Python 如何在没有欺骗的情况下发送 ICMP 数据包?
- powershell - 如何在 Format-Table 中获取服务器名称?
- javascript - Sqlite html5在插入时重复记录