Файл JPG, загруженный в модуль node canvas, теряет качество после операций и экспорта

#javascript #canvas #todataurl #image-quality #node-canvas

#javascript #холст #todataurl #качество изображения #узел-холст

Вопрос:

Я использую реализацию node canvas https://github.com/Automattic/node-canvas

Я использую его для вырезания jpg-экспорта дизайна информационного бюллетеня на фрагменты и создания HTML-шаблона на основе изображений, который удобен для электронной почты. По сути, это просто фрагменты из исходного кода с разрешением около 550 пикселей, основанные на моих требованиях к отправке электронной почты.

Проблема в том, что когда я загружаю исходный файл jpg, я вижу некоторые потери в экспортированных фрагментах. Вот пример:

Исходный и экспортированный пример

Как вы можете видеть, версия справа (исходный файл — jpg) несколько четче и имеет лучшее качество, чем то, что обработал node canvas.

Я уже использую экспорт jpg в полном качестве во всех моих вызовах toDataURL, в отличие от 0.92 в спецификации. Я использую функцию LoadImage, которую предоставляет node canvas, возможно ли там потерять качество?

this.writeImage(canvas.toDataURL('image/jpeg', 1.0), i);

Кроме того, я уже увеличил настройки качества в контексте:

     ctx.patternQuality = 'best';
    ctx.quality = 'best';
    ctx.antialias = 'subpixel';
    ctx.imageSmoothingEnabled = false
  

Я думаю, может быть, я неправильно использовал указанные выше настройки? Или, может быть, пропустил один?

Одна из идей, которые летают, — увеличить исходный код в 2 раза, а затем изменить размер при обработке, чтобы сохранить исходное качество jpeg.

Мой вопрос в том, что я могу сделать, чтобы предотвратить потерю качества при обработке? Не имеет смысла получать изображение более низкого качества в конце процесса со всеми примененными шагами, и все же…

Большое вам спасибо, Драгош.

Последующее редактирование:

На самом деле я задаю вопрос неправильно, источник, который я использую, на самом деле PNG, именно потому, что я хотел получить высокое качество при экспорте в формате jpeg. Экспорт явно не будет таким хорошим, как исходный PNG, но я получил исходный файл в формате JPG, и все же у него были потери по сравнению с потенциальным JPG, который я мог бы использовать, но технически я вырезаю из PNG.

Комментарии:

1. Это не решение, и неясно, в чем причина ухудшения. Сжатие JPEG с использованием дискретных вейвлет-преобразований en.wikipedia.org/wiki/JPEG_2000#Wavelet_transform . Вейвлеты покрывают область размером 8 на 8 пикселей. Вы не можете просто вырезать JPG в произвольных точках x, y (вверху слева), поскольку это изменяет положение выборок вейвлетов, делая невозможным воспроизведение исходных вейвлетов. Вы должны вырезать (вверху слева) с кратностью 8, чтобы иметь шанс сохранить исходное качество. Также похоже, что вы используете шаблон для рендеринга изображения, не рендерите его с помощью ctx.drawImage

2. Спасибо за ваш ответ! Я определенно использую ctx.drawImage для обрезки. Однако, основываясь на том, что вы сказали, сокращение в 8 пикселей может нанести ущерб моему бизнес-варианту использования, однако, основываясь на том, что вы сказали: что, если я не буду использовать drawImage для вырезания и просто подготовлю пустой холст, а затем, вместо вырезания и обрезки с помощью drawImage, я просто помещу ВЕСЬ исходный код на этотхолст и используйте перевод, чтобы получить меня по области источника, который я хотел видеть. Что-то вроде трафарета, если хотите. Это будет означать, что все изображение все еще присутствует, когда я запускаю toDataURL, но я вижу только ту часть, которую хочу видеть?

3. toDataUrl выполняется на холсте, который не зависит от контекста и, следовательно, не подвергается никакому преобразованию

4. Я понял, что задал вопрос немного неправильно, я добавил больше информации, я в безопасности от 8 на 8? Вы говорите, что моя вторая идея обрезки с помощью экспорта тоже не сработает?