首页 > 解决方案 > NodeJS Sharp 为 JPEG 图像提供了不正确的质量

问题描述

我正在sharp node package计算图像的质量。

我在包中找不到任何可以计算质量的 API。

所以我想出了一个遵循以下步骤的实现 -

  1. 接受传入的图像缓冲区并创建清晰的实例
  2. 通过将 quality 设置为 100 从此实例创建另一个实例
  3. 比较原始锐器实例和新锐器实例的大小
  4. 如果大小有差异,请更新质量并使用更新的质量执行步骤 2
  5. 一旦第 4 步中的比较给出最小的差异,就返回质量

我使用已知质量的图像测试了这种方法,即 50(已确认)

编辑-I generated images with different quality values using Photoshop

但是,上述逻辑返回的质量为 82(预计接近 50)


问题

所以问题是我无法弄清楚图像的质量。

如果上述逻辑返回一个最接近的值,例如 49 或 51,则很好。

然而结果却完全不同。


结果

按照这个逻辑,我得到给定质量的以下结果 -


代码

以下代码片段用于计算质量。

我确实理解需要改进才能获得精确的结果。

但它至少应该提供接近的价值。

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);

谢谢!

标签: node.jsimageimage-processingjpegsharp

解决方案


推荐阅读