
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.219.66.32] |
![]() |
|
Страницы: (3) [1] 2 3 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Если загрузить битмап из файла в переменную типа HBITMAP так:
![]() ![]() var hBmp: HBITMAP; ... hBmp := LoadImage(0, '1.bmp', IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); Как можно узнать его высоту, ширину, и цвет в какой-то определенной точке не прибегая к модую Graphics? |
![]() |
Сообщ.
#2
,
|
|
![]() ![]() function PictureSize: TSize; var ResHandle: HWND; ResData: HWND; BMI: PBitmapInfo; begin Result.cx := 0; Result.cy := 0; ResHandle := FindResource(HInstance, MAKEINTRESOURCE(200), RT_BITMAP); if ResHandle <> 0 then begin ResData := LoadResource(HInstance, ResHandle); if ResData <> 0 then try BMI := LockResource(ResData); if Assigned(BMI) then try Result.cx := BMI.bmiHeader.biWidth; Result.cy := BMI.bmiHeader.biHeight; finally UnlockResource(ResData); end; finally FreeResource(ResData); end; end; end; А цвет точки - у структуры PBitmapInfo есть параметр bmiColors, который является массивом структур TRGBQuad в котором и содержиться информация по каждому пикселю. Добавлено Пардон, у тебя из файла загрузка, тогда через GetDIB получай указатель на PBitmapInfo и по аналогии |
Сообщ.
#3
,
|
|
|
Я тут так подумал, может лучше так будет?
размер: ![]() ![]() var size: tagSIZE; ... GetBitmapDimensionEx(hBmp, size); цвет: ![]() ![]() color := GetPixel(hBmp, x, y); |
![]() |
Сообщ.
#4
,
|
|
Может и лучше, но не факт что быстрее
![]() |
![]() |
Сообщ.
#5
,
|
|
Цитата Dmitry_177 @ цвет: color := GetPixel(hBmp, x, y); Вообще-то GetPixel первым параметром принимает контекст устройства, а не дескриптор bitmap'а. Можно сделать как-нибудь так ![]() ![]() var bmp, oldbmp:HBITMAP; bmpInf:BITMAP; DC,MemDC:HDC; bWidth,bHeight:integer; color:COLORREF; begin bmp:=LoadImage(0, '1.bmp', IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); DC:=GetDC(0); MemDC:=CreateCompatibleDC(DC); oldbmp:=SelectObject(MemDC,bmp); GetObject(bmp,sizeof(BITMAP),@bmpInf); bWidth:=bmpInf.bmWidth; // ширина bHeight:=bmpInf.bmHeight; // высота color:=GetPixel(MemDC,10,10); // цвет SelectObject(MemDC,oldbmp); DeleteDC(MemDC); ReleaseDC(0,DC); end; |
Сообщ.
#6
,
|
|
|
Вот если делать через GetDIBits, у меня возникло несколько вопросов:
![]() ![]() var memDC: HDC; hBkgnd: HBITMAP; begin hBkgnd := LoadImage(0, '1.bmp', IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); memDC := GetDC(0); GetDIBits(memDC, hBkgnd, 0, 0, nil, BMI, DIB_RGB_COLORS); ReleaseDC(0, memDC); if (BMI.bmiColors[0].rgbRed = 255) and (BMI.bmiColors[0].rgbGreen = 0) and (BMI.bmiColors[0].rgbBlue = 0) then MessageBox(0, '0 - Красный', '', 0); end; Правильно ли я создаю контекст устройства memDC := GetDC(0);? Не понятно что это за массив bmiColors, как так идет счет точек что-то я не пойму, там же всего одно число а не два, например x и y... Объясните пожалуйста.. |
Сообщ.
#7
,
|
|
|
IMHO
![]() ![]() memDC := GetDC(0); это получение контекста рабочего стола |
Сообщ.
#8
,
|
|
|
Приветствую всех!
Мой вопрос почти по этой теме. Дело в том что GetObject воздвращает bmBitsPixel равное текущему BPP десктопа, то есть, например, всегда 32 у меня, так как стоит цвет 32 High Color. Соответсвенно при смене на 16 - даже 24ый битмап опознаётся как 16ый. То есть возвращается то как он конкретно сейчас конкретно на этом Compatible устройстве будет выведен. Но меня это пока не очень интересует. Как бы мне получить реальный BPP битмапа? То есть то сколько бит на пиксель записано в фаиле? (HBITMAP загружается - всё нормально, GetDIBits - работает нормально, то есть возвращает 3 * W * H в случае с 24 битным битмапом.) Неужели надо размер массива полученных точек делить на площадь его? ![]() |
Сообщ.
#9
,
|
|
|
Цитата Rouse_ @ А цвет точки - у структуры PBitmapInfo есть параметр bmiColors, который является массивом структур TRGBQuad в котором и содержиться информация по каждому пикселю Разве? Совсем нет. И кстати, для полноцветных битмапов данные в файле могут храниться структурах как RGBQUAD так и в RGBTRIPLE (определяется по BITMAPINFOHEADER.biBitCount). Цитата Dmitry_177 @ Не понятно что это за массив bmiColors Массив bmiColors содержится только в неполноцветных файлах, и это не цвета точек, это палитра. Сам массив изображения как правило начинается за массивом bmiColors. Но если рисунок полноцветный, то этот массив в файле отсутствует. ЗЫ: никогда не вычисляй размер bmiColors через BITMAPINFOHEADER.biBitCount, т.к. если рисунок к примеру 256-ти цветный, то не факт что и записей в палитре будет 256. Как правило меньше. Добавлено Цитата WDaft @ Как бы мне получить реальный BPP битмапа? То есть то сколько бит на пиксель записано в фаиле? Очень просто. Считывай заголовок с помощью BlockRead(sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER)). Затем, если BITMAPINFOHEADER.biBitCount равен 16,24 или 32 то файл не содержит палитры, и размер рассчитывается как (W * H * (biBitCount / 8)). Если biBitCount равен 1,2,4 или 8 то нужно расчитать размер палитры. Ее размер можешь вычислить как (sizeof(RGBQUAD) * biClrUsed). Сразу за ней и начинается изображение. А теперь тонкости(мягкотелые без них не могут ![]() BITMAPINFOHEADER и BITMAPCOREHEADER. Если попался CORE, то палитра хранится в формате RGBTRIPLE и ее размер расчитывается по bcBitCount. Это во первых. Во вторых старайся использовать как можно меньше полей заголовка, поскольку встречаются отклонения от стандарта, сам вычисляй. В третьих, палитровые рисунки могут быть сжаты по RLE. В четвертых, заголовки можешь определить по bcSize. В пятых - поле bfSize частенько некорректное, а BITMAPINFOHEADER начинается сразу за BITMAPFILEHEADER. Остальное мелочи ![]() |
Сообщ.
#10
,
|
|
|
AndNot, 10x! =)
Я предвидел ответ в виде этого метода. И всё же - нет ли WinAPIшного метода для определения битности по HBITMAPу? Или только так? ![]() |
Сообщ.
#11
,
|
|
|
Вот и фиг то что не припомню
![]() Добавлено А разве сложно через заголовок посмотреть BPP? |
Сообщ.
#12
,
|
|
|
Не так сложно, но разве Микрософтовцы при загрузке Битмапа ИХНЕЙ же функцией не знают какой там BPP записан? Какого они кроют от нас эту инфу теперь?
И ведь всё равно при GetDIBits получается массив именно столько байт на пиксель, сколько в файле - то есть всё правильно. |
Сообщ.
#13
,
|
|
|
Цитата WDaft @ Битмапа ИХНЕЙ же функцией не знают какой там BPP записан? Зачем им это? Цитата WDaft @ Какого они кроют от нас эту инфу теперь? Я переправлю дидюшке биллу ![]() Цитата WDaft @ И ведь всё равно при GetDIBits получается массив именно столько байт на пиксель, сколько в файле - то есть всё правильно. И это естественно, поэтому и есть функции преобразования к нужному тебе формату, при этом не обязательно знать уже загруженный, вот и получилась такая хрень. Хотя черт ее знает, может и есть какая апи. |
![]() |
Сообщ.
#14
,
|
|
Цитата AndNot @ Разве? Совсем нет. Да? Странно, а вот спецификация данного формата говорит что да: Цитата Each bitmap file contains a bitmap-file header, a bitmap-information header, a color table, and an array of bytes that defines the bitmap bits. The file has the following form: BITMAPFILEHEADER bmfh; BITMAPINFOHEADER bmih; RGBQUAD aColors[]; BYTE aBitmapBits[]; The bitmap-file header contains information about the type, size, and layout of a device-independent bitmap file. The header is defined as a BITMAPFILEHEADER structure. The bitmap-information header, defined as a BITMAPINFOHEADER structure, specifies the dimensions, compression type, and color format for the bitmap. The color table, defined as an array of RGBQUAD structures, contains as many elements as there are colors in the bitmap. The color table is not present for bitmaps with 24 color bits because each pixel is represented by 24-bit red-green-blue (RGB) values in the actual bitmap data area. The colors in the table should appear in order of importance. This helps a display driver render a bitmap on a device that cannot display as many colors as there are in the bitmap. If the DIB is in Windows version 3.0 or later format, the driver can use the biClrImportant member of the BITMAPINFOHEADER structure to determine which colors are important. |
Сообщ.
#15
,
|
|
|
Цитата Rouse_ @ Странно, а вот спецификация данного формата говорит что да Ну и где здесь сказано что: Цитата Rouse_ @ А цвет точки - у структуры PBitmapInfo есть параметр bmiColors, который является массивом структур TRGBQuad в котором и содержиться информация по каждому пикселю bmiColors это именно массив палитры (в вышеприведенном файле это - RGBQUAD aColors[]), который у полноцветных отсутствует(в таком случае этого поля просто нет). Цвета точек расположены в массиве "BYTE aBitmapBits[]", сразу за палитрой(если есть), о чем я и толковал. И даже в большинстве непалитровых битмапов каждая точка хранится в структуре RGBTRIPLE, т.к. 32-х разрядные появились опосля(также как и 16-ти битные). Несколько лет назад писал загрузчик бмп,кур и иконок под дос. Посмотри кусочек: ![]() ![]() sub esp,size BitmapInfoHeader mov edx,esp mov ecx,size BitmapCoreHeader mov esi,edx ; esi - входной буффеp mov ah,3Fh int 21h ; считали заголовок __core: ; пpедполагаем что заголовок BitmapCoreHeader movzx ecx,[esi+BitmapCoreHeader.biBitCount] cmp [esi+BitmapCoreHeader.biSize],size BitmapCoreHeader je __read_palette __win: ; заголовок BitmapInfoHeader mov ecx,size BitmapInfoHeader - size BitmapCoreHeader mov ah,3Fh int 21h ; считываем остаток заголовка movzx ecx,[esi+BitmapInfoHeader.biBitCount] ; считываем и конвеpтиpуем палитpу (если нам это надо ;-) __read_palette: cmp cl,18h je __select_outpnt ; -> pисунок полноцветный,уходим! push ecx ; сохpаняем BPP ; получаем количество цветов mov ebx,1 shl ebx,cl ; ebx - количество цветов ; выделяем память под палитpу lea ecx,[ebx*4] call Alloc PASCAL,ecx xchg edx,eax cmp [esi+BitmapCoreHeader.biSize],size BitmapCoreHeader jne __win_pal ; -> виндозный pисунок sub ecx,ebx ; ecx - pазмеp палитpы в байтах mov ah,3Fh int 21h ; считываем палитpу ; пpеобpазуем в RGBQuad xchg ecx,ebx ; ecx - количество цветов ; ebx - pазмеp палитpы в байтах push esi lea edi,[edx+ecx*4-4] lea esi,[edx+ebx-3] std xor eax,eax __conv_pal: movsw lodsb stosw loop __conv_pal cld pop esi jmp short __end_pal __win_pal: cmp [esi+BitmapInfoHeader.biClrUsed],0 je __read_pal ; использована не вся палитpа mov ebx,[esi+BitmapInfoHeader.biClrUsed] __read_pal: shl ebx,2 ; ebx - pазмеp палитpы в байтах xchg ecx,ebx ; ecx - pазмеp палитpы mov ah,3Fh int 21h ; считываем палитpу xchg edx,edi ; палитpа обpаботана __end_pal: pop ecx Если есть желание разбираться, то увидишь, про что я все это время толковал ![]() Код кстати рабочий. Проверен на сотнях бмпшек всех разновидностей. |