Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: GetDIBits  (Прочитано 19041 раз)
0 Пользователей и 5 Гостей смотрят эту тему.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« : 25-02-2011 17:23 » 

Не пойму, что я не так делаю. Вроде бы всё по докам, а вот косяк...

код доставания массива битов такой:
Код:
bool CMy1Dlg::TakeScreenData()
{
CDialog* m_Dlg=this;

std::vector<BYTE> DATA;

bool bResult=false;

CDC* dc=0;
for(;;)
{
DATA.clear();
RECT dstRect;

m_Dlg->GetClientRect(&dstRect);

LONG wid=dstRect.right -dstRect.left+1;
LONG hig=dstRect.bottom-dstRect.top +1;

dc=m_Dlg->GetDC();

BITMAPINFO bi;
::memset(&bi,0,sizeof(bi));
bi.bmiHeader.biSize          =sizeof(bi.bmiHeader);

DWORD dwdLenInBytes=0;
const CBitmap* bmp=dc->GetCurrentBitmap();

if(!::GetDIBits(*dc,*bmp,0,0,0,&bi,DIB_RGB_COLORS) && bi.bmiHeader.biBitCount)break;

bi.bmiHeader.biWidth=4;
bi.bmiHeader.biHeight=4;

dwdLenInBytes=
(
(
bi.bmiHeader.biWidth*bi.bmiHeader.biBitCount+31
)
/32
)
*4
*bi.bmiHeader.biHeight;

if(!dwdLenInBytes)break;

DATA.resize(dwdLenInBytes);

if(DATA.size()<dwdLenInBytes)break;

DWORD dwdLines=::GetDIBits(
*dc,*bmp
,0,bi.bmiHeader.biHeight
,&DATA[0]
,&bi
,DIB_RGB_COLORS);


bResult=true;
break;
}

if(dc)m_Dlg->ReleaseDC(dc);
return bResult;
}

далее. Вот скрины из дебажного режима
1 - до чтения битового массива
2 - после

на первом в просмотрщике памяти содержимое переменной bi выделено серым. 8 байтов со значением 0xcc - это дебажный маячок на порчу памяти, он не должен быть затронут.
Но смотрим на скрин 2
0x00ff0000 - нормально, на месте,  а вот 8 байтов 0xcc затёрты {00 ff 00 00 ff 00 00 00}

и я не понимаю, почему! Дебаггер то просто ругается, а релиз падает...

Если сделать финт ушами, а именно: объявить массив из двух BITMAPINFO, но работать только с первым, то лишней затирки, естественно, не будет (испортится второй , неиспользуемый, элемент). Но это костыль.

Всё-таки хочется узнать, в чём причина то

* 1.PNG (74.08 Кб - загружено 992 раз.)
* 2.PNG (74.73 Кб - загружено 973 раз.)
« Последнее редактирование: 25-02-2011 17:42 от Алексей1153++ » Записан

Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 25-02-2011 18:01 » 

потерто.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #2 : 25-02-2011 18:03 » 

я знаю ) Вот хочется узнать - почему
Записан

Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 25-02-2011 18:51 » 

Цитата
If the lpvBits parameter is a valid pointer, the first six members of the BITMAPINFOHEADER structure must be initialized to specify the size and format of the DIB. The scan lines must be aligned on a DWORD except for RLE compressed bitmaps.
- где инициализация этих шести полей?)

а....все, вижу)
« Последнее редактирование: 25-02-2011 18:55 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #4 : 25-02-2011 19:03 » 

да, вот тут есть

Код:
if(!::GetDIBits(*dc,*bmp,0,0,0,&bi,DIB_RGB_COLORS) && bi.bmiHeader.biBitCount)break;
Записан

Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 25-02-2011 19:09 » 

 bmiColors[] -  массив. в зависимости от...
они в структуре только первый элемент определили. похоже?
« Последнее редактирование: 25-02-2011 19:11 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #6 : 25-02-2011 19:16 » 

это элемент под один 32-битный пиксел (ну и ещё варианты, в зависимости от битности)

Но почему так сделано - тоже не могу понять. Что-то тут хитрое

Добавлено через 4 минуты и 9 секунд:
пришлось выдрать готовый код отсюда. Код страшненький, но рабочий, тут этой затирки не происходит
http://msdn.microsoft.com/en-us/library/dd183402(v=VS.85).aspx

разницу при работе со структурой я не увидел...

Добавлено через 44 секунды:
(процедура CaptureAnImage)
« Последнее редактирование: 25-02-2011 19:20 от Алексей1153 » Записан

Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 25-02-2011 19:22 » 

там жешь написано.
The bmiColors member contains one of the following:
...
An array of RGBQUAD. The elements of the array that make up the color table.
An array of 16-bit unsigned integers that specifies indexes into the currently realized logical palette.
The number of entries in the array depends on the values of the biBitCount and biClrUsed members of the BITMAPINFOHEADER structure.

там просто union на самом деле...
про остальное не ведаю.... не разбираюсь я в графике...

PS http://msdn.microsoft.com/en-us/library/dd183376(VS.85).aspx
biBitCount = 32
The bitmap has a maximum of 2^32 colors. If the biCompression member of the BITMAPINFOHEADER is BI_RGB, the bmiColors member of BITMAPINFO is NULL. Each DWORD in the bitmap array represents the relative intensities of blue, green, and red, respectively, for a pixel. The high byte in each DWORD is not used. The bmiColors color table is used for optimizing colors used on palette-based devices, and must contain the number of entries specified by the biClrUsed member of the BITMAPINFOHEADER.
If the biCompression member of the BITMAPINFOHEADER is BI_BITFIELDS, the bmiColors member contains three DWORD color masks that specify the red, green, and blue components, respectively, of each pixel. Each DWORD in the bitmap array represents a single pixel.
When the biCompression member is BI_BITFIELDS, bits set in each DWORD mask must be contiguous and should not overlap the bits of another mask. All the bits in the pixel do not need to be used.

может так...?)
« Последнее редактирование: 25-02-2011 19:34 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #8 : 25-02-2011 19:39 » 

Ochkarik, там вовсе не юнион

Код:
typedef struct tagBITMAPINFO {
  BITMAPINFOHEADER bmiHeader;
  RGBQUAD          bmiColors[1];
} BITMAPINFO, *PBITMAPINFO;


Добавлено через 1 минуту и 55 секунд:
>>может так...?)

может, но почему тогда там под одну маску место ? Вручную что ли обеспечивать нужно ? ))

Добавлено через 6 минут и 56 секунд:
struct s_BITMAPINFO_2RGBQUAD:public BITMAPINFO
{
   RGBQUAD GM;
   RGBQUAD BM;
};

как-то так
« Последнее редактирование: 25-02-2011 19:48 от Алексей1153 » Записан

Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 25-02-2011 21:15 » 

Места там под 1 пиксел, потому что надо выделять сколько необходимо, а потом кастовать. Типичный майкрософтовский подход, чтобы все поля уже в структуре были объявлены, но при этом структура имеет неизвестный заранее размер.
типа
Код: (C++)
BITMAPINFO * info = (BITMAPINFO*)new char[sizeof(BITMAPINFO) + sizeof(RGBQUAD) * PIXEL_COUNT];
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #10 : 26-02-2011 07:19 » 

Вад, первый раз такой типичный подход встречаю Улыбаюсь И вот это

+ sizeof() * PIXEL_COUNT

ну никак не соответствует. Добавляется 2 лишних двойных слова, а по твоей формуле - их будет (PIXEL_COUNT-1) лишних.
А ведь под пикселы другой массив указуется Улыбаюсь

А эти 3 RGBQUAD - там действительно маски цветов получаются

Добавлено через 2 часа, 58 минут и 53 секунды:
собственно, разница нашлась:

перед капитальным, вторым, вызовом GetDIBits нужно установить
bi.bmiHeader.biCompression = BI_RGB

(по умолчанию после первого вызова там BI_BITFIELDS)
« Последнее редактирование: 26-02-2011 10:20 от Алексей1153 » Записан

Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 26-02-2011 10:35 » 

Алексей1153++,
PS майкрософт действительно оооочень часто так делает со структурами  неопределенной длины) собственно с их подачи даже я стал так поступать в некоторых случаях) только обычно я еще сразу определяю дефенишн для структуры в замену обычного sizeof.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #12 : 26-02-2011 10:51 » 

Ochkarik, я тоже делаю похожие вещи, но не так, как у них сделано в этом случае. У меня поля указывают размеры всего - и самой структуры, и внешней части. А вот такие перекрытия я не делаю. Если уж внешняя часть, то внешняя
Записан

Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #13 : 26-02-2011 11:07 » 

Алексей1153++, неэкономный ты Леша!) кроме того, не всегда нужен размер из которого потом количество элементов придется каждый раз считать, иногда удобнее количество элементов указывать. или тип обработки элементов...
размер майкрософт обычно указывает только когда структура может проходить через функции, которым содержимое структуры до лампочки)

а насчет флага, там написано было, я уже копипастил)
If the biCompression member of the BITMAPINFOHEADER is BI_BITFIELDS, the bmiColors member contains three DWORD color masks that specify the red, green, and blue components, respectively, of each pixel. Each DWORD in the bitmap array represents a single pixel.
внимательней надо быть Ага
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #14 : 26-02-2011 11:39 » new

про экономность не соглашусь, ну а про цитату - это я уже тоже увидел ) Вот , если указать BI_RGB, то этого довеска не будет
Записан

Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #15 : 26-02-2011 12:44 » 

Вад, первый раз такой типичный подход встречаю Улыбаюсь И вот это

+ sizeof() * PIXEL_COUNT

ну никак не соответствует. Добавляется 2 лишних двойных слова, а по твоей формуле - их будет (PIXEL_COUNT-1) лишних.
А ведь под пикселы другой массив указуется Улыбаюсь
Ну, за точность размера я не ручаюсь - суть в том, что выделяешь размер, равный размеру основной структуры + нужный размер буфера для данных.

В принципе, это удобно при дальнейшем обращении со структурой: работаешь, как ни в чём не бывало. Только выделять память слегка неаккуратно и неудобно.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines