Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   www.boolean.name > Программирование игр для компьютеров > BlitzMax > FAQ и уроки

Ответ
 
Опции темы
Старый 29.09.2010, 10:29   #1
Dzirt
Элита
 
Аватар для Dzirt
 
Регистрация: 16.01.2008
Адрес: Украина
Сообщений: 1,800
Написано 958 полезных сообщений
(для 3,832 пользователей)
Разбираемся в : Antialiasing

Итак в єтой статье я розкажу вам как сделать сглаживание своими руками.
И так немножко теории...что же такое сглаживание?
Прямиком из вики получаем:
Сгла́живание —технология, использующаяся в обработке изображений с целью делать границы кривых линий более гладкими, убирая «зубцы», возникающие на краях объектов.
Инными словами если мы возьмем картинку нормального размера и отскейлим ее допусти в 4 раза меньше исходного размера - то получим артефакты на подобии этого:
Нажмите на изображение для увеличения
Название: noant.jpg
Просмотров: 242
Размер:	14.7 Кб
ID:	11400

Со сглажеванием же картинка будет выглядет намного "мягче":
Нажмите на изображение для увеличения
Название: ant.jpg
Просмотров: 270
Размер:	15.8 Кб
ID:	11401

Ну думаю тут все ясно....теперь перейдем к реализации:

Разбиваем имагу на сектора
Первым делом нам нужно написать функцию котая бы делила всю имагу на сектора.... желательно чтобы функция была гибка, и вы могли вольно выставлять количество секторов на которые она должна разбиватся.
По этому я сначала создал тип который содержал бы информацию каждого сектора о :
1.Начальной координате Х
2.Начальной координате У
3.Высоте сектора
4.Шириге сектора
5.Его порядкового ид(это не так уж и нужно, но посколько данная функция может еще использоватся и в качестве отладки, то лучше таки создать это поле)
Type sector
    Field x:Float
    Field x2:Float
    Field y:Float
    Field y2:Float
    Field id
EndType
Далее пишем собственно саму функцию.Она должна быть гибкой и работаь с разными имагами поэтому в заголовке пишем:
Function sectors(image,sectors,ImageX,ImageY)
Параметры использованые в функции:
1.image - собственно картинка которую мы будет сглаживать
2.sectors - это количество секторов на которое мы будем ее делить.(какое должно быть их количество и зачем они вообще нужну опишу далее)
3.ImageX- начальная координата Х имаги, это нам понадобится при работе с пиксмапами.
4.ImageY - начальная координата У имаги,это нам понадобится при работе с пиксмапами.

Как разделить картинку на равное количество секторов - конечно все мы знаем: Делим ширину и высоту картинки на кол-во секторов и получаем ширину и высоту каждого сектора.

    sectorsW:Float=ImageWidth(image)/sectors
    sectorsH:Float=ImageHeight(image)/sectors
Итак вообщем вот конечная функция(я люблю пользоватся временными переменными в функции...вам желаю избавится от этой привычки или просто не развивать ее, так как собирается иногда много мусора в функции) :
'Divine image to sectors
Function sectors(image,sectors,ImageX,ImageY)
    sectorsW:Float=ImageWidth(image)/sectors
    sectorsH:Float=ImageHeight(image)/sectors
    tempImageX:Float=ImageX
    tempImageY:Float=ImageY

    For c=1 To sectors
        For i=1 To sectors
            sid=sid+1
            NewSector: sector= New sector
            NewSector.x=ImageX
            NewSector.y=ImageY
            NewSector.x2=sectorsW
            NewSector.y2=sectorsH
            NewSector.id=sid
            sector_list.AddLast NewSector    

            ImageX=ImageX+sectorsW
        Next
        ImageX=tempImageX
        ImageY=ImageY+sectorsH
    Next

End Function
Проверить получилось ли у нас задуманое можно очень легко. Просто в главный цикл вписуем чтобы на месте каждго сектора рисовался квад, и отоброжался его ид в центре:
    For NewSector : sector = EachIn sector_list
            SetAlpha 0.1
            SetColor 0,0,0
            DrawRect NewSector.x,NewSector.y,NewSector.x2,NewSector.y2
            SetColor 0,255,0
            DrawRect NewSector.x+1,NewSector.y+1.0,NewSector.x2-1.0,NewSector.y2-1.0
            SetColor 255,255,255
            SetAlpha 1
            DrawText NewSector.id,NewSector.x+NewSector.x2/2.5,NewSector.y+NewSector.y2/2.5
       Next
Вот что у меня получилось из этого :
Нажмите на изображение для увеличения
Название: Sectors.jpg
Просмотров: 277
Размер:	80.9 Кб
ID:	11396

Хм, теперь давайте разберемся зачем же эти сектора... Сектора нужны для того, чтобы мы могли по ним сгладить имагу.Итак по этапно как мы это будем именно делать:
1.Имага розбита на сектора
2.С помощю перебора каждого сектора мы вычислим какой цвет для него средне-статистичен(инными словами посмотрим каждый пиксель который содержит сектор и возьмем среднее значение цвета.)
3.Закрасим весь секор средним цветом из полученого в этапе 2 значения.

Не сложно догадатся что чем бльше секторов мы сделаем - те качественее будет сглаживание, но и втоже время увеличит время обработки.

Функция сглаживания
Итак приступим к самой функции сглаживания:
1.Для начала нужно знать что чтобы рабоать с имагой в Бмаксе нам нужно сначала поставить ей флаг DYNAMICIMAGE. Делаем это при загрузке имаги :
mainImage=LoadImage("sammple.png",DYNAMICIMAGE )
+ при работе с пиксмапой ее прийдется заблокировать :
pixmap=LockImage(image)
ну а потом естественно разблокировать
UnlockImage(image)


Также следует знать что при работе с пикселями пиксмапы, Бмакс пользуется интом ARGB.Чтобы его розложить на стандартный А,R,G,B нужно попарится немножко... но вот вам фугкции намного упрощающие задачу:

1.Функйия переформатирования из стандартный А,R,G,B в инт ARGB:
Function SetARGB(a=255,r=255,g=255,b=255)
    Return (((a) Shl 24) + ((r) Shl 16) + ((g) Shl 8) + (b))
End Function
2.Функция вытаскивания значения R из инта:
Function IntR(rgbint)
    Return ((rgbint Shr 16) & $ff)
End Function
3.Функция вытаскивания значения G из инта:
Function IntG(rgbint)
    Return ((rgbint Shr 8) &  $ff)
End Function
4.Функция вытаскивания значения B из инта:
Function IntB(rgbint)
    Return (rgbint & $ff)
End Function
5.Функция вытаскивания значения А из инта:
Function IntA(rgbint)
    Return ((rgbint Shr 24) & $ff)
End Function

Теперь когда мы вооружены и опасны, можно перебрать весе пиксели всех секторов и закрасить их средним значением.
Описывать построчно не буду, итак все понятно как это сделать....единственное что хочу сказать - не нужно создавать вякие массивы или типы для того чтобы сравнивать пиксили сектора...достаточно создать переменную которая будет плюсовать значения каждого пикселя:
TempA=IntA(pixel)
TempR=IntR(pixel)
TempG=IntG(pixel)
TempB=IntB(pixel)
                                                                                        
GlobalSectorA=GlobalSectorA+TempA
GlobalSectorR=GlobalSectorR+TempR
GlobalSectorG=GlobalSectorG+TempG
GlobalSectorB=GlobalSectorB+TempB
После того как мы сложили все значения в эту переменную, просто поделите на количество пикселей -и получите среднее значение....это еще в школе проходили.

Функция сглаживания:
'main antialiase function
Function antialiase(image)

    pixmap=LockImage(image)
        For NewSector : sector = EachIn sector_list
            temp_valX=NewSector.x-imageX
            temp_valX2=(NewSector.x2+NewSector.x)-imageX
            temp_valY=NewSector.y-imageY
            temp_valY2=(NewSector.y2+NewSector.y)-imageY
            GlobalSectorA=0
            GlobalSectorR=0
            GlobalSectorG=0
            GlobalSectorB=0
            count=0
    
                For h=temp_valY  To temp_valY2-1
                    For w=temp_valX To temp_valX2-1
                        count=count+1
                        pixel=ReadPixel (pixmap,w,h)
                        TempA=IntA(pixel)
                        TempR=IntR(pixel)
                        TempG=IntG(pixel)
                        TempB=IntB(pixel)
                                                                                        
                        GlobalSectorA=GlobalSectorA+TempA
                        GlobalSectorR=GlobalSectorR+TempR
                        GlobalSectorG=GlobalSectorG+TempG
                        GlobalSectorB=GlobalSectorB+TempB

                    Next
                Next
                
                GlobalSectorA=GlobalSectorA/count
                GlobalSectorR=GlobalSectorR/count
                GlobalSectorG=GlobalSectorG/count
                GlobalSectorB=GlobalSectorB/count

                For h=temp_valY  To temp_valY2-1
                    For w=temp_valX To temp_valX2-1
                        pixel=WritePixel (pixmap,w,h,SetARGB(GlobalSectorA,GlobalSectorR,GlobalSectorG,GlobalSectorB))
                    Next
                Next
    
        Next            
    
    UnlockImage(image)
    Return image
EndFunction
Осталось назначить нужное кол-во секторов(качество), отскейлить ,сгладить и посмотреть чтоже у нас из этого вышло :

Нажмите на изображение для увеличения
Название: Final.png
Просмотров: 344
Размер:	11.7 Кб
ID:	11397


Если у кого не получилось сделать самому
Исходны код с ресами :Anti.rar

У кого нету бМакса, но посмотреть охота:
AntiEXE.rar
(Offline)
 
Ответить с цитированием
Эти 7 пользователя(ей) сказали Спасибо Dzirt за это полезное сообщение:
ABTOMAT (29.09.2010), baton4ik (10.10.2010), impersonalis (29.09.2010), Mr_F_ (29.09.2010), Randomize (02.10.2010), Reks888 (29.09.2010), Жека (30.09.2010)
Старый 29.09.2010, 11:36   #2
ABTOMAT
Ференька
 
Аватар для ABTOMAT
 
Регистрация: 25.01.2007
Адрес: улица Пушкина дом Колотушкина
Сообщений: 10,399
Написано 5,229 полезных сообщений
(для 15,135 пользователей)
Ответ: Разбираемся в : Antialiasing

Это не антиалязинг, а блюр. Но всё равно годно, спасибо.
__________________
Мои проекты:
Анальное Рабство
Зелёный Слоник
Дмитрий Маслов*
Различие**
Клюква**

* — в стадии разработки
** — в стадии проектирования
Для проектов в стадии проектирования приведены кодовые имена

(Offline)
 
Ответить с цитированием
Эти 2 пользователя(ей) сказали Спасибо ABTOMAT за это полезное сообщение:
Randomize (26.07.2011), SBJoker (29.09.2010)
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Часовой пояс GMT +1, время: 08:58.


vBulletin® Version 3.6.5.
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com