Я работаю с sharp node package
для вычисления качества изображения.
Я не смог найти в пакете API, который бы вычислял качество.
Итак, я пришелс реализацией, которая выполняет следующие шаги -
- Принять входящий буфер изображений и создать резкий экземпляр
- Создать другой экземпляр из этого экземпляра, установив для качества значение 100
- Сравнитьразмер исходного острого экземпляра и нового острого экземпляра
- Если есть разница в размере, обновите качество и выполните шаг 2 с обновленным качеством
- Верните качество, если сравнение на шаге 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);
Спасибо!