Как сделать качественное масштабирование изображения? - PullRequest
18 голосов
/ 09 декабря 2008

Я пишу некоторый код для масштабирования 32-битного изображения RGBA на C / C ++. Я написал несколько попыток, которые были несколько успешными, но они медленные, и самое главное качество изображения не приемлемо.

Я сравнил одно и то же изображение, масштабированное OpenGL (то есть моей видеокартой), и мою рутину, и по качеству она сильно расходится. Я искал в Google Code, просматривал исходные деревья всего, что, как я думал, пролило некоторый свет (SDL, Allegro, wxWidgets, CxImage, GD, ImageMagick и т. Д.), Но обычно их код либо извилист, разбросан по всему месту, либо пронизан ассемблер и мало или нет комментариев. Я также прочитал несколько статей в Википедии и в других местах, и я просто не нахожу четкого объяснения того, что мне нужно. Я понимаю основные понятия интерполяции и выборки, но я изо всех сил пытаюсь получить правильный алгоритм. Я НЕ хочу полагаться на внешнюю библиотеку для одной процедуры и должен преобразовать их в формат изображения и обратно. Кроме того, я бы все равно хотел знать, как это сделать самому. :)

Я уже видел похожий вопрос, который задавали о переполнении стека, но на этот вопрос не было ответа, но я надеюсь, что есть кто-то, кто может помочь подтолкнуть меня в правильном направлении. Возможно, укажите мне на некоторые статьи или псевдокод ... что-нибудь, что поможет мне учиться и делать.

Вот что я ищу:

  1. Нет ассемблера (я пишу очень переносимый код для нескольких типов процессоров).
  2. Нет зависимостей от внешних библиотек.
  3. В первую очередь меня интересует масштабирование ВНИЗ, но позже мне нужно будет написать процедуру увеличения.
  4. Качество результата и ясность алгоритма являются наиболее важными (я могу оптимизировать его позже).

Моя рутина по существу принимает следующую форму:

DrawScaled(uint32 *src, uint32 *dst, 
      src_x, src_y, src_w, src_h, 
      dst_x, dst_y, dst_w, dst_h );

Спасибо!

ОБНОВЛЕНИЕ: Чтобы уточнить, мне нужно что-то более продвинутое, чем повторная выборка для уменьшения масштаба, которая слишком сильно размывает изображение. Я подозреваю, что мне нужен какой-то бикубический (или другой) фильтр, который в некоторой степени противоположен алгоритму бикубического масштабирования (то есть каждый целевой пиксель вычисляется из всех исходных пикселов, участвующих в проекте, в сочетании с алгоритмом взвешивания, который обеспечивает четкость.

Пример

Вот пример того, что я получаю из алгоритма wxWidgets BoxResample, и того, что я хочу получить для растрового изображения 256x256, масштабированного до 55x55.

  • www.free_image_hosting.net / добавление / 1a25434e0b.png

И наконец:

  • www.free_image_hosting.net / добавление / eec3065e2f.png

оригинальное изображение 256x256

Ответы [ 11 ]

0 голосов
/ 09 декабря 2008

Взгляните на ImageMagick , который выполняет все виды фильтров масштабирования.

...