NodeJS Sharp обеспечивает неправильное качество для изображений JPEG - PullRequest
0 голосов
/ 19 сентября 2019

Я работаю с sharp node package для вычисления качества изображения.

Я не смог найти в пакете API, который бы вычислял качество.

Итак, я пришелс реализацией, которая выполняет следующие шаги -

  1. Принять входящий буфер изображений и создать резкий экземпляр
  2. Создать другой экземпляр из этого экземпляра, установив для качества значение 100
  3. Сравнитьразмер исходного острого экземпляра и нового острого экземпляра
  4. Если есть разница в размере, обновите качество и выполните шаг 2 с обновленным качеством
  5. Верните качество, если сравнение на шаге 4 дает наименьшееразница

Я проверил этот подход, используя изображение известного качества, т.е. 50 (подтверждено)

РЕДАКТИРОВАТЬ - I generated images with different quality values using Photoshop

ОднакоПриведенная выше логика возвращает качество как 82 (ожидается, что-то близко к 50)


Проблема

Так что проблема в том, что я не могу выяснитькачество of image.

Хорошо, если приведенная выше логика возвращает ближайшее значение, такое как 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);

Спасибо!

...