Автор Тема: FindPixel - поиск пикселей  (Прочитано 16983 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Yura [?]

  • Новичок
  • *
  • Сообщений: 36
  • Репутация: 7
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: FindPixel - поиск пикселей
« Ответ #15, Отправлен: Декабрь 07, 2015, 00:28:46 »
Спасибо за объяснение! Попытка №2:
Код: AutoIt [Выделить]
$hDIB = _WinAPI_CopyBitmap($hBMP)
$tDIB = DllStructCreate($tagDIBSECTION)
_WinAPI_GetObject($hDIB, DllStructGetSize($tDIB), DllStructGetPtr($tDIB))
_WinAPI_DeleteObject($hDIB)

$Size = $tDIB.bmWidth * $tDIB.bmHeight * 4

$Ret = _ImageLoadFromMemory($tDIB.bmBits, $Size)
;$Ret = _ImageLoadFromMemory($tDIB, $Size)
If @error Then
    ConsoleWrite("An error occurred."&@CR)
Else
    ConsoleWrite($Ret&@CR)
EndIf

;-------------------------------------------------------------
Func _ImageLoadFromMemory($Mem, $Size) ;обертка для вызова длл
    $Result = DllCall('FindPixel.dll', 'int', 'ImageLoadMem', 'int*', $Mem, 'int', $Size) ;  "int*" правильно??
    If @error Then Return SetError(1)

    Return $Result[0]
EndFunc



Если работает с 32 битными битмапами, то я еще $hBMP перед кодом выше переделал и добавил 4й байт на альфа канал (может это лишнее или неправильно?):
Код: AutoIt [Выделить]
$hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBMP)
    _WinAPI_DeleteObject($hBMP)
    $hBitmap_clone = _GDIPlus_BitmapCloneArea($hBitmap, 0, 0, $hBMP_width, $hBMP_height,  $GDIP_PXF32PARGB);$GDIP_PXF24RGB)
;_GDIPlus_ImageSaveToFile($hBitmap_clone, "!.bmp")
    _GDIPlus_BitmapDispose($hBitmap)
    $hBMP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap_clone)
    _GDIPlus_BitmapDispose($hBitmap_clone)


С ерором не вылетает, но возвращает 0- не загрузило. Наверно указатель на буфер с данными битмапа ( 'int*', $Mem) неправильно пишу?

Русское сообщество AutoIt

Re: FindPixel - поиск пикселей
« Ответ #15 Отправлен: Декабрь 07, 2015, 00:28:46 »

Оффлайн Prog [?]

  • Осваивающий
  • **
  • Сообщений: 271

  • Автор темы
  • Репутация: 28
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.12.0
Re: FindPixel - поиск пикселей
« Ответ #16, Отправлен: Декабрь 07, 2015, 00:32:37 »
Yura  [?]
Цитировать
Функция загружает в буфер BMP картинку из памяти. Если выполнено успешно, вернет не 0. Может я туплю, но мне такое описание мало о чем говорит. Нужно описание каждого параметра
Первый параметр - адрес памяти, где находится картинка, а второй, размер области памяти. Картинка должна быть в том же виде как она хранится на диске.
Код функции ImageLoadMem.ProcedureDLL ImageLoadMem(*Mem, Size)
  Protected Result = #False
 
  If *Mem And Size>0
    Result = CatchImage(#Image, *Mem, Size)
  EndIf
 
  ProcedureReturn Result
EndProcedure
Описание функции CatchImage

Подозреваю, что данная DLL работает только с 32-битными битмапами
По идее должна работать со всеми распространенными форматами.

Добавил новую функцию
Цитировать
ImageLoadHandle(hBmp)
Загружает картинку по ее дескриптору.
Заодно выкладываю исходник библиотеки. Может кому-то пригодится.


Внимание: Для просмотра прикреплённых файлов необходимо Войти или Зарегистрироваться

Оффлайн Yura [?]

  • Новичок
  • *
  • Сообщений: 36
  • Репутация: 7
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: FindPixel - поиск пикселей
« Ответ #17, Отправлен: Декабрь 07, 2015, 19:07:41 »
По хэндлу удалось загрузить и найти пиксель. Оформил в виде функций:
Код: AutoIt [Выделить]
Func _FPImageLoadByHandle($hBMP)
    $Result = DllCall('FindPixel.dll', 'int', 'ImageLoadHandle', 'handle', $hBMP)
    If @error Then Return SetError(1)

    Return $Result[0]
EndFunc

Func _FPPixel_Buff($X0, $Y0, $Width, $Height, $Color, $Shade = 0, $Steps = 1)
    $Result = DllCall('FindPixel.dll', 'int', 'FindPixel_Buff', 'int', $X0, 'int', $Y0, 'int', $Width, 'int', $Height, 'int', $Color, 'int', $Shade, 'int', $Steps)
    If @error Then Return SetError(1)
    If $Result[0] == -1 Or $Result[0] == -2 Then Return $Result[0]

    Local $aCoord[2]
    $aCoord[0] = BitAND($Result[0], 0xFFFF)
    $aCoord[1] = BitAND(BitShift($Result[0], 16), 0xFFFF)
    Return $aCoord
EndFunc

Вывел сравнение скорости поиска (только поиска, когда картинка уже в буфере):
(нажмите для показа/скрытия)
Либа FastFind написана на плюсах, эта либа на PureBasic, а он вроде как не должен быть медленней, тем более в 7 раз? Пришлось скачать PureBasic и посмотреть исходник. Вы разлагаете цвет на 3 составляющие и каждый раз в цикле проверяете- находится ли каждая составляющая в нужном диапазоне. Это отлично, что есть параметр Shade! Но если Shade=0, а в большинстве случаев так и есть, то делается куча лишних телодвижений. FFNearestPixel без параметра Shade, на этом получается и выигрывает. Можете добавить в начале поиска проверку и если Shade=0, то сравнивать сразу весь цвет без разложения на составляющие? Самому если делать, то надо еще в незнакомый синтаксис вникать. Если что не так понял, извиняйте)

Вы уверенны, что: Color - Задает цвет для поиска, должен быть в формате RGB? Я создал в пейнте черный рисунок с 1 пикселем цвета 0xB5E61D. Цвет смотрю в ControlViewer в формате RGB. Нужный пиксель по нужным координатам  FindPixel() нашел. Но когда я задал $Сolor = 0x1DE6B5, то есть в BGR.

В PureBasic вы для доступа к загруженному изображению используете "#Image" (The number by which to identify the loaded image. #PB_Any can be specified to autogenerate this number. ) Я правильно понимаю, что если во все функции добавить еще один параметр- число, которое будет передаваться в #Image, то можно будет использовать буфер под номером=это число, то есть можно было бы использовать несколько буферов? (например для отслеживания динамических изменений на экране).

ImageLoadHandle(hBmp) есть, обратная функция- получение hBmp из буфера, если это возможно, то тоже было бы отлично. Чтоб можно было скриншотить через вашу либу, а когда надо чтоб была возможность его получить не делая еще один скриншот в AutoIt- это трата времени, иногда критическая. По сути если есть 2 такие функции передачи битмепов, то уже есть хорошая стыковка с AutoIt. ImageLoad, ImageSave можно сделать и средствами AutoIt'а имея битмеп.
« Последнее редактирование: Декабрь 07, 2015, 19:56:41 от Yura »

Оффлайн Prog [?]

  • Осваивающий
  • **
  • Сообщений: 271

  • Автор темы
  • Репутация: 28
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.12.0
Re: FindPixel - поиск пикселей
« Ответ #18, Отправлен: Декабрь 07, 2015, 19:55:17 »
Разница может быть из-за различий в алгоритме. Например, в одном случае начинает искать с левого верхнего угла, а в другом случае, в нижнего правого угла. Пиксель по тем же координатам будет найден за разное время.

Внес измерения в библиотеку.


Внимание: Для просмотра прикреплённых файлов необходимо Войти или Зарегистрироваться

Русское сообщество AutoIt

Re: FindPixel - поиск пикселей
« Ответ #18 Отправлен: Декабрь 07, 2015, 19:55:17 »

Оффлайн Yura [?]

  • Новичок
  • *
  • Сообщений: 36
  • Репутация: 7
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: FindPixel - поиск пикселей
« Ответ #19, Отправлен: Декабрь 07, 2015, 20:04:18 »
Разница может быть из-за различий в алгоритме. Например, в одном случае начинает искать с левого верхнего угла, а в другом случае, в нижнего правого угла. Пиксель по тем же координатам будет найден за разное время.
Я учел это при выборе пикселя для поиска- я его находил посредине монитора, так что с какого бы угла не искали... Алгоритм FFNearestPixel мне понятен- он ищет ближайший пиксель к заданной точке. Ищет расширяя область по радиусу, зона поиска- круг. Начальные координаты дал ему (0,0). Так что оба алгоритма, ваш и тот, пока нашли проверили приблизительно одинаковую площадь.

Кстати быстрые поиски нужны чаще всего ботописцам на игрушки, когда каждая милисекунда на счету. Поиск расширяя зону по кругу в этом случае часто имеет одно преимущество- как правило ищется моб или обьект ближайший к игроку (которого делаем точкой начала поиска) из множества других мобов.
« Последнее редактирование: Декабрь 07, 2015, 20:09:30 от Yura »

Оффлайн Prog [?]

  • Осваивающий
  • **
  • Сообщений: 271

  • Автор темы
  • Репутация: 28
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.12.0
Re: FindPixel - поиск пикселей
« Ответ #20, Отправлен: Декабрь 07, 2015, 20:15:24 »
Yura  [?]
Цитировать
Вы уверенны, что: Color - Задает цвет для поиска, должен быть в формате RGB? Я создал в пейнте черный рисунок с 1 пикселем цвета 0xB5E61D. Цвет смотрю в ControlViewer в формате RGB. Нужный пиксель по нужным координатам  FindPixel() нашел. Но когда я задал $Сolor = 0x1DE6B5, то есть в BGR.
https://ru.wikipedia.org/wiki/RGB
Цитировать
COLORREF — стандартный тип для представления цветов в Win32. Используется для определения цвета в RGB виде. Размер — 4 байта. При определении какого-либо RGB цвета, значение переменной типа COLORREF можно представить в шестнадцатеричном виде так:

0x00bbggrr

rr, gg, bb — значение интенсивности соответственно красной, зелёной и синей составляющих цвета. Максимальное их значение — 0xFF.
Обратите внимание что в шестнадцатеричной записи байты располагаются как BGR, но на самом деле это RGB, потому что в шестнадцатеричной записи, младший байт находится справа, а старший слева, из-за этого кажется что запись BGR, но в памяти цвет располагается в последовательности RGB.

Цитировать
В PureBasic вы для доступа к загруженному изображению используете "#Image" (The number by which to identify the loaded image. #PB_Any can be specified to autogenerate this number. ) Я правильно понимаю, что если во все функции добавить еще один параметр- число, которое будет передаваться в #Image, то можно будет использовать буфер под номером=это число, то есть можно было бы использовать несколько буферов? (например для отслеживания динамических изменений на экране).
Да. Возможно создать практически неограниченное число картинок (сколько памяти хватит).

Цитировать
ImageLoadHandle(hBmp) есть, обратная функция- получение hBmp из буфера, если это возможно, то тоже было бы отлично.
Нужно добавить в DLL такую функцию.ProcedureDLL ImageGetHandle()
  Protected Result = 0
 
  If IsImage(#Image)
    Result = ImageID(#Image)
  EndIf
 
  ProcedureReturn Result
EndProcedure

Оффлайн Yura [?]

  • Новичок
  • *
  • Сообщений: 36
  • Репутация: 7
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: FindPixel - поиск пикселей
« Ответ #21, Отправлен: Декабрь 07, 2015, 20:54:50 »
Цитировать
При определении какого-либо RGB цвета, значение переменной типа COLORREF можно представить в шестнадцатеричном виде так:

0x00bbggrr
:o :blink:
http://www.rgbtohex.net/You entered R: 0, G: 0, B: 255 which converts to the following in Hex code: #0000FF
в rgb - 0хrrggbb. ИлиControlViewer, AutoitInfo и еще несколько сайтов в которых я переводил цвета нагло нас обманывают :)

За ImageID(#Image) спасибо, я тоже уже на нее наткнулся в поиске :)
« Последнее редактирование: Декабрь 07, 2015, 21:00:34 от Yura »

Оффлайн Prog [?]

  • Осваивающий
  • **
  • Сообщений: 271

  • Автор темы
  • Репутация: 28
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.12.0
Re: FindPixel - поиск пикселей
« Ответ #22, Отправлен: Декабрь 07, 2015, 21:08:00 »
Не нужно путать представление цвета в винде и в веб ЯП.
В винде последовательность байт RGB.
R это младший байт, а B старший байт.

В HEX представлении слева располагается старший байт, а справа младший байт.

Русское сообщество AutoIt

Re: FindPixel - поиск пикселей
« Ответ #22 Отправлен: Декабрь 07, 2015, 21:08:00 »

Оффлайн Yura [?]

  • Новичок
  • *
  • Сообщений: 36
  • Репутация: 7
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: FindPixel - поиск пикселей
« Ответ #23, Отправлен: Декабрь 07, 2015, 21:25:53 »
Я вас понял, msdn почитал, но поймите и вы: пользователь вашей либы будет смотреть на COLORREF или будет смотреть на AutoitInfo или другой цветоопредилятор подобный и оттуда брать цвет для поиска? А там не в COLORREF.
Я не программист пока что, учу сейчас Джаву, чтоб работать в этом направлении. Но я программировал микрухи на ассемблере и С, по верхам писал еще на многих языках, с математикой всегда дружил и пол года как защитил кандидатскую. Я разбираюсь, потому что мне это интересно и я намерен развиваться в этом направлении. Но большинству пользователей по..., они не будут разбираться, попробуют, не работает и плюнут.
« Последнее редактирование: Декабрь 07, 2015, 21:32:31 от Yura »

Оффлайн Yashied [?]

  • AutoIt MVP
  • Глобальный модератор
  • *
  • Сообщений: 5379
  • Репутация: 2694
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.x.x
Re: FindPixel - поиск пикселей
« Ответ #24, Отправлен: Декабрь 07, 2015, 21:32:13 »
R это младший байт, а B старший байт.
Если говорить про GDI, где цвета задаются в BGR, то в памяти это будет располагаться так:

R G B A

В GDI+ все цвета задаются в ARGB.


Думай, прежде чем говорить.

Оффлайн Yura [?]

  • Новичок
  • *
  • Сообщений: 36
  • Репутация: 7
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: FindPixel - поиск пикселей
« Ответ #25, Отправлен: Декабрь 08, 2015, 12:01:56 »
Внес измерения в библиотеку.

Проверил опять с Shade=0 при запуске поиска пикселя в цикле 1000 раз. Скорость возросла буквально чуть-чуть, около 0.5 мс. Так как в внутри 2х циклов при  Shade=0 выполняется только этоColor = Point(x, y)
             
              If Shade=0
                If P_Color = Color
                  SetData()
                EndIf
              Else

то скорее всего  функция Point самая времязатратная.

Интересная особенность: в вашей функции поиска ярко выражена зависимость времени поиска от расположения искомого пикселя, это понятно, перебор по строкам и столбцам. В FastFind время поиска всегда почти одинаковое. Если искомый пиксель будет в точке с координами (0,10) например, то ваш поиск будет намного быстрее, если в средине картинки или тем более в конце- в разы медленней. В FastFind- все время около 2 мс у меня, куда бы точку не перемещал. Когда будет время, я поищу исходник FastFind, посмотрю. Такое впечатление, что там не попиксельный перебор, а другой подход. Или есть какая-то подготовительная процедура по обработке битмапа, которая занимает около 2 мс, и потом почти мгновенный поиск пикселя.

Сейчас я напишу , что нашел по вопросу о поисках пикселей в PureBasic, если я там не так что-то понял, прошу тапками не бросать. Я посмотрел по англоязычных форумах по пурику и там были вопросы о повышении производительности сканирования области, поиска пикселей и т.п. Вы используете рисование 2д. Может есть другой способ. Не совсем поиск пикселей, но возможно эта тема так-то поможет (сомневаюсь, но вдруг) http://www.purebasic.fr/english/viewtopic.php?t=27740. Только скажите, вам это интересно или вы уже сделали как сделали, 2 или 10 мс не важно, и не будете ничего менять?
« Последнее редактирование: Декабрь 08, 2015, 12:43:49 от Yura »

Оффлайн Prog [?]

  • Осваивающий
  • **
  • Сообщений: 271

  • Автор темы
  • Репутация: 28
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.12.0
Re: FindPixel - поиск пикселей
« Ответ #26, Отправлен: Декабрь 08, 2015, 13:13:34 »
Та тема была создана давно. В те времена действительно функция Point работала медленно, но начиная с версии 4.50, ее значительно ускорили.

Оффлайн Yura [?]

  • Новичок
  • *
  • Сообщений: 36
  • Репутация: 7
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: FindPixel - поиск пикселей
« Ответ #27, Отправлен: Декабрь 11, 2015, 11:34:13 »
Та тема была создана давно. В те времена действительно функция Point работала медленно, но начиная с версии 4.50, ее значительно ускорили.
Отлично, что ее ускорили. Один вопрос тогда. Что лучше:
1) Сделать скриншот, а потом потратить еще несколько мс чтоб через GetDIBits() выдернуть цвета пикселей в строку или массив. Или даже через рисование и Point в циклах, что вангую будет дольше в несколько раз. Потом искать обычным перебором в циклах в этой строке и выигрывать время на каждом поиске.
2) Сделать как есть у вас сейчас: при каждом поиске каждый цвет пикселя перегонять в DIB через Point (эта команда ведь это делает?).


FFNearestPixel()   => X = 1330, Y = 517, Time = 1.9394303123768; Snapshot_time: 8.70994497860369
FindPixel()   => X = 1330, Y = 517, Time = 10.5035193190783; Snapshot_time: 6.87397916245433

Это то, что есть сейчас: вы делаете скриншот на 2 мс быстрее, чем в FastFind, а потом НА КАЖДОМ поиске теряете время. Почему? А я посмотрел исходники FastFind. Ее автор не против, чтоб кто хочет в ней копался, поэтому выкладываю ссылку https://github.com/FastFrench/FastFind/tree/master/FastFindDLL. Смотрим в SnapShots.cpp. После BitBlt(sdc, 0, ...) идет строка GtSnapShotData[NoSnapShot].SnapShotPixels = getbits(...). Метод getbits прописан в ImageProcessing.cpp и какая неожиданность! через GetDIBits() делает уже сами поняли что. Поиски пикселей прописаны в PixelPcocessing.cpp и аналогом вашей процедуры Search_Pixel есть int WINAPI GenericColorSearch(...), которая используется во всех поисках пикселей. Ищет цвета пикселей из screen_pixel. (LPCOLORREF screen_pixel = GtSnapShotData[NoSnapShot].SnapShotPixels;) То есть из того, что получили в getbits()- строки,  в которую подряд записаны цвета, на каждый цвет по 4 байта- 1 байт пустой и по байту на r, g, b.
Теперь о том, почему, как я писал раньше, время поиска в FastFind одинаковое независимо от расположения пикселя на экране. Просто потому, что всегда проверяются все пиксели, автор не сделал выход из циклов поиска пикселей, когда найден первый пиксель искомого цвета. Но он ищет не просто первый пиксель, а пиксель ближайший к заданной точке, поэтому при нахождении пикселя нужного цвета считает расстояние и сравнивает с предыдущим лучшим результатом.  X = 1330, Y = 517 в своем примере я выбрал именно поэтому- точка в правом нижнем углу моей области поиска, чтоб оба алгоритма прошлись по всей картинке и можно было адекватно сравнить их быстроту.
Желаю вам заморочиться на этом и ускорить свой поиск в несколько раз. Если решитесь - еще раз посмотрите на ссылку, которую дал в предыдущем ответе.


Теперь о FindPixel_Buff и ей подобным. Когда x=0, y=0, Width=0, Height=0, чтоб автоматично поиск шел по всей картинке в буфере. Как вы в WinSize() сделали для окон.

Функция FindPixel() ИМХО лишняя, делает скриншот и потом ищет - не нужно этого, путает больше, чем пользы. Есть 2 отдельные функции- скриншот и поиск, для этого дела и не надо больше.

Search_Pixel() у вас "If Shade<>0", надо "If Shade>0". Когда Shade<0 сделать Shade=0 или Shade=abs(Shade). И желательно проверку от дурака добавить, чтоб значение Shade было в границах 0-255.

Эта длл будет работать на XP? на x64?
Какая у вас версия PureBasic? У меня 5.0, компилятор ругается на перенос строк, приходится лепить их в 1 строку. И длл получаются чуть меньшего размера, чем у вас.
« Последнее редактирование: Декабрь 12, 2015, 00:28:50 от Yura »

Оффлайн Yura [?]

  • Новичок
  • *
  • Сообщений: 36
  • Репутация: 7
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: FindPixel - поиск пикселей
« Ответ #28, Отправлен: Декабрь 15, 2015, 03:58:50 »
1) Написал обертки ко всем функциям, кроме ImageLoadMem - считаю ненужной при наличии ImageLoadHandle, и FindPixel- тоже считаю ненужной.
Добавил ImageLoadHandle, которую автор не внес в библиотеку версии 1.4.
Поиск по умолчанию теперь тот, что автор назвал с отсечкой по Х, а по факту есть обычный поиск в области. Такое изменение на мой взгляд (и как читал ниже не только на мой) полностью логичное.

2) Написал справку в .chm, где все разжевано и есть пример использования функций. Справка включает внесенные мной изменения.

Справка вложением не влазит, закинул в файловый архив: UDF, справку, демо файл, dll и исходник кода в PureBasic. В dll уже внесены описанные выше мелкие изменения. Называется в файловом архиве "FindPixel (Автор dll - Prog)", думаю Prog будет не в обиде:)

У меня не было возможности протестировать справку и тестовый пример на других компьютерах. Если что-то не так там- пишите. Если вместо содержания страниц пишет "Переход на веб-страницу отменен" или "Действие отменено" - зайдите в свойства файла и нажмите "Разблокировать".

Думаю, что теперь эта либа может получить более массовое применение - больше не надо при вызове каждой функции кучу времени тратить на ее написание и разбор параметров. Но, на мой взгляд, там можно еще очень много чего добавить и улучшить. Если автор не будет ее дальше развивать, то не исключаю вероятности, что этим займусь я:)

Ссылка на скачивание:
https://autoit-script.ru/index.php?action=downloads;sa=downfile&id=523

Русское сообщество AutoIt

Re: FindPixel - поиск пикселей
« Ответ #28 Отправлен: Декабрь 15, 2015, 03:58:50 »

 

Похожие темы

  Тема / Автор Ответов Последний ответ
12 Ответов
6759 Просмотров
Последний ответ Январь 04, 2012, 13:40:17
от Guezt Gutsy
5 Ответов
3087 Просмотров
Последний ответ Апрель 29, 2011, 08:55:23
от zoxer1
0 Ответов
1651 Просмотров
Последний ответ Август 18, 2011, 05:32:12
от running-frag
2 Ответов
2286 Просмотров
Последний ответ Ноябрь 25, 2011, 15:20:51
от running-frag
0 Ответов
1740 Просмотров
Последний ответ Апрель 22, 2012, 15:28:50
от madmasles
31 Ответов
10539 Просмотров
Последний ответ Октябрь 15, 2013, 14:08:50
от madmasles
7 Ответов
1703 Просмотров
Последний ответ Июнь 09, 2014, 00:57:19
от gloss
16 Ответов
3380 Просмотров
Последний ответ Октябрь 21, 2014, 11:31:48
от CrazyKing
5 Ответов
1096 Просмотров
Последний ответ Февраль 08, 2015, 19:04:44
от Ksaan
2 Ответов
1103 Просмотров
Последний ответ Март 30, 2015, 19:49:44
от S_K