Как отключить субдискретизацию с помощью .NET / GDI +? - PullRequest
4 голосов
/ 14 апреля 2009

Я пытаюсь сохранить изображение в формате JPEG с помощью класса Bitmap. Я заметил, что острые края всегда были размытыми, независимо от уровня качества, который я указал. Я понял, что это связано с подвыборкой одного или нескольких каналов. Как отключить субсэмплинг при сохранении изображения?

Я сейчас использую этот код:

EncoderParameters parameters = new EncoderParameters(1);
parameters.Param[0] = new EncoderParameter(Encoder.Quality, 85L);

ImageCodecInfo codec = GetEncoderInfo("image/jpeg");
image.Save(path, codec, parameters);

Примечание

Я знаю, что JPEG с потерями, но это не проблема здесь. Если я использую ImageMagick и сохраняю изображение с параметрами по умолчанию, я получаю аналогичные результаты. Однако если указать субдискретизацию 1: 1: 1, размытие исчезнет.

Я не хочу использовать PNG, потому что мне нужно лучшее сжатие. Если я сохраню изображение как BMP, а затем преобразую его вручную в JPEG, я получу отличные результаты без размытия. Таким образом, формат не является проблемой здесь.

Ответы [ 3 ]

4 голосов
/ 14 апреля 2009

JPEG - это формат изображения, который использует сжатие с потерями . Это приведет к деградации вашего изображения, независимо от того, какое качество вы выберете.

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


Проблема (после прочтения ваших правок), вероятно, связана с тем, что GDI + использует 4: 1: 1 субсэмплинг для файлов JPG в своем кодировщике по умолчанию.

Полагаю, вы можете установить другой кодировщик (не знаю, как это сделать). В противном случае, я бы рекомендовал использовать что-то вроде MagickNet для сохранения ваших файлов JPG. (Это оболочка .net для ImageMagick - их несколько.)


Редактировать 2: После более подробного изучения, похоже, что вы сможете оказать какое-то влияние на это, настроив кодировщик Таблица яркости и Таблица цветности .

2 голосов
/ 12 июля 2009

Я пытался выяснить, как это сделать в течение 2 дней, просто меня поражает, что M $ не включил бы такую ​​простую функцию в GDI +. В качестве альтернативы я реализовал свой собственный компрессор Bitmap -> Jpeg, написав небольшую функцию-обертку вокруг libjpeg. Критическим шагом является отключение подвыборки следующим образом:

</p> <pre><code>struct jpeg_compress_struct cinfo; ... jpeg_set_defaults(&cinfo); cinfo.comp_info[0].h_samp_factor = 1; cinfo.comp_info[0].v_samp_factor = 1; cinfo.comp_info[1].h_samp_factor = 1; cinfo.comp_info[1].v_samp_factor = 1; cinfo.comp_info[2].h_samp_factor = 1;

Однако это создало для меня еще одну проблему: libjpeg не поддерживает написание тегов exif, которые мне тоже нужны. Конечно, GDI + не будет добавлять теги без перекодирования jpg, что полностью противоречит цели. Я посмотрел на libexif, но не смог его скомпилировать в визуальной студии. Если бы кто-нибудь нашел способ отключить субсэмплинг в GDI +, я все равно хотел бы услышать об этом ...

0 голосов
/ 16 июня 2009

Изменили ли вы свойство SmoothingMode для вашего объекта Graphics? В своих экспериментах я обнаружил, что указание значения SmoothingMode, отличного от значения по умолчанию, стирает острые края. Попробуйте и посмотрите, поможет ли это.

...