Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Алгоритмы > Алгоритм сжатия картинки


Автор: h3d0 26.3.2008, 19:05
Добрый день. Я пишу программу, аналог RАdmina. Столкнулся с промлемой, попробую её описать. Например, есть два компа: удаленный и комп админа. С удаленного компа должен прийти снимок экрана. 

user posted image

Но представим, что на компе админа этот снимок экрана удалённого компа отображается не в полный размер, а в окне – в окне моей программы. Значит снимок размером 1024х768 сожмется, ширина и высота умножатся на коефициент. И на экране админа будет виден не оригинал – а сжатая в размерах версия снимка экрана удалённого компа.

user posted image

Но на удаленном компе поменялся не весь экран, а только определённая область – значит мне нужно чтоб пришел только этот кусочек экрана и «вклеился» в старый снимок экрана (который уже есть на компе админа).

user posted image

Так вот вся проблема заключается в том, что моя программа использует специальную функцию, которая сжимает снимок экрана удаленного компа и вклеивает ёё в окно программы на компе админа, НО! На удалённом компе левый верхний угол оригинала снимка имел, например, координаты Х=22 У=18, но когда снимок приходит на комп админа и прграмма пытается впихнуть его в маленькое окно программы – координаты тоже множатся на коэфициент сжатия. По этому в новом окне тот же верхний левый угол окна имеет координаты, скажем Х=4.4 У=2.6. Поскольку координаты должны быть целыми числами – они округляются (Х=4 У=3) и картнинка смещается!!!

user posted image

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


Мне нужно добиться того, чтобы алгоритм работал правильно - не было артефактов-смещенй. Или же сменить стратегию сжатия совсем (взять другую функцию-алгоритм). Программу прикрепил (язык Delphi). Возможно кто-нибудь уже сталкивался с подобной проблемой. Буду очень признателен за помощь!

Автор: mmvds 26.3.2008, 21:59
Может попробовать заменить округление round() на trunc()?

Автор: 4d5a 27.3.2008, 09:22
Цитата(h3d0 @  26.3.2008,  19:05 Найти цитируемый пост)
пришел только этот кусочек экрана


А что мешает использвать такую схему:

Пересылая фрагменты, обновлять буфер (в натуральную величину) в памяти компа админа, а потом уже масштабировать весь буфер ? Артефактов не будет по определению, правда замедлится процедура перерисовки.

user posted image

Автор: SoWa 28.3.2008, 07:01
Понимаешь, в чем штука. Такие смещения появляются из-за размеров кусочка.
Вот смотри. 1024*768 преспокойно коэффициентом сжимается без потерь(имеется ввиду без округления). А вот 329*127 без тких потерь не сжать коэффициентом.
Возмоный вариант решения- передавать картинку в несжатом формате, а только на админском компе сперва склеивать, потом сжимать. По проблемме передачи несжатой(по размерам ш*в) можно сжимать картинку в качестве. Там же рабочий стол. Найди оптимальный коэффициент потерь качества(например, чтоб буквы были читаемы при максимальном коэффициенте), сжимай там картинку по качеству, отсылай, склеивай, сжимай по размеру.

Автор: RockClimber 28.3.2008, 09:56
Э-э-э... Я в-общем-то, в такого рода алгоритмах дилетант, но может стоит попробовать сделать так: пусть функция, которая вырезает и масштабирует кусок экрана, сначала будет расширять область до значений, которые масштабируются до целых значений? Т. е. если коэффициент масштабирования 0.75, начальная точка имеет координаты (15, 21) и конечная - (321, 425), то заменить сначала координаты на (12, 20) и (324, 428) соответственно, после чего масштабирование пройдет без проблем - получится (9, 15) и (243, 321). Только в этом случае ограничивается разнообразие коэффициентов масштабирования...
Как вариант, можно таким образом минимизировать величину разницы между точным и округленным значением (если масштаб, например, 0.9). Я не думаю, что эти вычисления займут много ресурсов...

Автор: asd 28.3.2008, 16:13
h3d0, 
Почитай вот эту тему http://www.wasm.ru/forum/viewtopic.php?id=14540 на предмет того, как лучше передавать изменения на экране уд-го компа.

Автор: Exaktus 28.3.2008, 20:35
Думаю, стоит посмотреть на вопрос с другой стороны. Исходя из поставленный задачи не помешает глянуть на схему работы http://ru.wikipedia.org/wiki/Virtual_Network_Computing. Если не натолкнет на мысли, то можно порытся в исходниках TightVNC.
В любом случае, просто сжатие в картинку и передача не катит. Тогда уже надо сжимать в картинку только первый кадр, и затем передавать только измененные пиксели. Но тут имеется ряд недостатков.

Автор: h3d0 31.3.2008, 15:04
Есть, правда, ещё вариант - попробовать после вклеивания "усреднять" цвет пикселей на стыке...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)