![]() |
Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply |
![]() ![]() ![]() |
|
Dmitry_177 |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 22.9.2006 Репутация: нет Всего: нет |
Если загрузить битмап из файла в переменную типа HBITMAP так:
Как можно узнать его высоту, ширину, и цвет в какой-то определенной точке не прибегая к модую Graphics? |
|||
|
||||
Snowy |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 11363 Регистрация: 13.10.2004 Где: Питер Репутация: 30 Всего: 484 |
Размер
Цвет точки
А, если нужна серъёзная работа с изображением, то GetDIBits справка по нему и поиск в руки. |
||||
|
|||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 16 Всего: 459 |
-------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
bems |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 21 Всего: 88 |
разве можно HBITMAP вместо HDC?
не знаю как GetBitmapDimensionEx, а GetObject работает только для части битмапов. с его использованием я делал так
-------------------- Обижено школьников: 8 |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 16 Всего: 459 |
А точнее только для DDB, для DIB и DIB Section вроде не работает. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Dmitry_177 |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 22.9.2006 Репутация: нет Всего: нет |
Вот если делать через GetDIBits, у меня возникло несколько вопросов:
Правильно ли я создаю контекст устройства memDC := GetDC(0);? Не понятно что это за массив bmiColors, как так идет счет точек что-то я не пойму, там же всего одно число а не два, например x и y... Объясните пожалуйста.. |
|||
|
||||
bems |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 21 Всего: 88 |
это значения цветов, которые есть в битмапе. (объявлен, как с одним элементом но это в основном не так) само содержимое битмапа скопируется в область lpvBits (если передать в этом параметре не nil) Оно будет состоять из индексов массива bmiColors (типа первая точка имеет цвет, содержащийся в массиве по такому-то индексу, вторая - по такому - то и тд.) Но массив bmiColors не используется если в BITMAPINFOHEADER.biCompression указать BI_RGB, а в BITMAPINFOHEADER.biBitCount - 24 или 32. Тогда bmiColors вообще не трогаешь, а читаешь значения из lpvBits. Если 24 бита то там массив записей RGBTRIPLE, если 32 - RGBQUAD. если твой битмап отводит меньше чем 24 бита на точку, то все равно можно использовать такой вариант - GetDIBits сконвертит все в соответствии с тем, как ты инициализировал BITMAPINFOHEADER (нужно соответствующи оюразом заполнить biSize, biWidth, biHeight, biPlanes, biBitCount и biCompression ) например сначала вызвать GetDIBits с lpvBits=nil и получить реальную BITMAPINFOHEADER, потом изменить в ней формат пикселей на тот, с которым проще работать (24 или 32), выделить память под lpvBits (высота и ширина есть, количество бит на точку задаешь сам - значит можешь пощитать размер в памяти) и вызвать GetDIBits снова но уже с измененной BITMAPINFOHEADER и lpvBits<>nil (указатель на буфер для цветов). Получишь в буфере сконвертированую версию содеожимого битмапа. Из нее и читай цвета в трех составляющих. Добавлено @ 22:45 biHeight может быть отрицательным - значит строки в получаемом массиве идут в порядке от верхней к нижней. Если biHeight положительная, то строки - снизу вверх. Второй вариант почему-то более распространен Добавлено @ 22:46 и прочитай на форуме статью alexeis1 про формат битмапов. -------------------- Обижено школьников: 8 |
|||
|
||||
Dmitry_177 |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 22.9.2006 Репутация: нет Всего: нет |
У меня в файле битмап сохранен 24 битами на точку... Т.е. вот это:
если твой битмап отводит меньше чем 24 бита на точку, то все равно можно использовать такой вариант - GetDIBits сконвертит все в соответствии с тем, как ты инициализировал BITMAPINFOHEADER (нужно соответствующи оюразом заполнить biSize, biWidth, biHeight, biPlanes, biBitCount и biCompression ) например сначала вызвать GetDIBits с lpvBits=nil и получить реальную BITMAPINFOHEADER, потом изменить в ней формат пикселей на тот, с которым проще работать (24 или 32), выделить память под lpvBits (высота и ширина есть, количество бит на точку задаешь сам - значит можешь пощитать размер в памяти) и вызвать GetDIBits снова но уже с измененной BITMAPINFOHEADER и lpvBits<>nil (указатель на буфер для цветов). Мне не надо делать? А еще мне не понятна область lpvBits если само содержимое битмапа копируется, посмотрел в описании функции: function GetDIBits(DC: HDC; Bitmap: HBitmap; StartScan, NumScans: UINT; Bits: Pointer; var BitInfo: TBitmapInfo; Usage: UINT): Integer; stdcall; Я как понял это указатель на буфер цветов, а вот как его объявлять не пойму никак... И еще, при считывании размеров:
BMI.bmiHeader.biWidth и BMI.bmiHeader.biHeight (пускай хоть и отрицательный) не правильно определяются ширина с высотой, т.е. Реальные размеры картинки 283 x 149, если посмотреть в свойствах файла в виндовсе, а у меня определяется как 70 x 5... Что-то я не пойму никак что не так... |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 16 Всего: 459 |
Ой блин да вот простейший пример
-------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Dmitry_177 |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 22.9.2006 Репутация: нет Всего: нет |
p := Pointer(lpBits); //тут начало растра.
А как мне этот сам растр считывать? |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 16 Всего: 459 |
да как угодно, хоть байтами хоть строками, хоть пикселами.
-------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Dmitry_177 |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 22.9.2006 Репутация: нет Всего: нет |
Опять же таки не пойму я... Мы узнали высоту и ширину(пока еще не пробовал так как в примере, но допустим)... Как считывать байтами или пикселями, тоже понятно... А вот как определить цвет определенной точки например (x=22; y=33)? В каком порядке считываются точки? Если построчно то я как понимаю так нужно посчитать порядковый номер точки: Width*(y-1)+x которая и будет тем цветом который мы хотим узнать?
Это сообщение отредактировал(а) Dmitry_177 - 12.12.2006, 00:02 |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 16 Всего: 459 |
Ох и зря вы не прочитали про графический формат BMP http://forum.vingrad.ru/index.php?showtopic=94227&hl=
Там все подробно описано и про то, что размер строки (для 24 бита/пиксель ) определяется 3 * width при этом выравнивается на границу 4х байт, т.е. дополняется байтами до кратности 4м, и что строки в буфере идут снизу вверх, т.е. первая строка в буфере, является последней в изображении. А найти нужный пиксел легко. Совершенно верно Width*(Height - y+1)+x, главное правильно посчитать длину строки в байтах (в статье приводится формула там есть даже пример чтения из файла, правда без API, т.е. напрямую.) -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Delphi: WinAPI и системное программирование" | |
|
Запрещено: 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |