Произвольный цвет заливки для 8-битной DIB-секции
От: Xo  
Дата: 30.11.04 11:32
Оценка:
Добрый день!

Задача следующая: на 8-битном битмапе рисовать различные геометрические фигуры
с заданным цветом (оттенком) заливки. Реализую это следующим образом:

    /* BITMAPINFO structure */
    BITMAPINFO *AdibBMI = (BITMAPINFO *)malloc( sizeof( BITMAPINFO ) + sizeof( RGBQUAD ) * 0xff );
    AdibBMI->bmiHeader.biSize        = sizeof( BITMAPINFO );
    AdibBMI->bmiHeader.biWidth       = 200;
    AdibBMI->bmiHeader.biHeight      = 200;
    AdibBMI->bmiHeader.biPlanes      = 1;
    AdibBMI->bmiHeader.biBitCount    = 8;
    AdibBMI->bmiHeader.biCompression = BI_RGB;

    for( int i = 0; i < 0x100; i++ ) {
        RGBQUAD quad = { i, i, i, 0 };
        AdibBMI->bmiColors[i] = quad;
    }

    /* DIB section */
    HDC AdibDC = CreateCompatibleDC( NULL );
    HBITMAP AdibBitmap = CreateDIBSection( AdibDC, AdibBMI, DIB_PAL_COLORS, (void **) &AdibBits, NULL, 0 );

    SelectObject( AdibDC, AdibBitmap );

    SelectObject( AdibDC, GetStockObject( WHITE_BRUSH ) );
    Ellipse( AdibDC, 0, 0, 20, 10 );

    free( AdibBMI );
    DeleteDC( AdibDC );
    DeleteObject( AdibBitmap );


Заливка всегда получается черной.
В чем может быть проблема?
Re: Произвольный цвет заливки для 8-битной DIB-секции
От: Pavel Dvorkin Россия  
Дата: 30.11.04 11:51
Оценка:
Здравствуйте, Xo, Вы писали:

Xo>Добрый день!


Xo>Задача следующая: на 8-битном битмапе рисовать различные геометрические фигуры

Xo>с заданным цветом (оттенком) заливки. Реализую это следующим образом:


Xo> /* DIB section */

Xo> HDC AdibDC = CreateCompatibleDC( NULL );
Xo> HBITMAP AdibBitmap = CreateDIBSection( AdibDC, AdibBMI, DIB_PAL_COLORS, (void **) &AdibBits, NULL, 0 );

Попробуй здесь вместо AdibDC передать hdc, полученный от GetDC(hAnyWnd)


hdc
[in] Handle to a device context. If the value of iUsage is DIB_PAL_COLORS, the function uses this device context's logical palette to initialize the DIB colors.

Сдается мне, что у твоего AdibDC с этой самой logical palette не все хорошо, так как в нем пока что выбрана монохромная битовая карта.

Xo>Заливка всегда получается черной.

Xo>В чем может быть проблема?

With best regards
Pavel Dvorkin
With best regards
Pavel Dvorkin
Re[2]: Произвольный цвет заливки для 8-битной DIB-секции
От: Xo  
Дата: 30.11.04 12:19
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Попробуй здесь вместо AdibDC передать hdc, полученный от GetDC(hAnyWnd)


Спасибо. Это помогает, если стоит задача отрисовки непосредственно в контексте устройства
(при этом на самом битмапе фигура не отображается).
А если рассматривать такой вариант: работа с изображением организована как работа
с некоторой областью памяти. На нем надо рисовать (заданным цветом) различные
геометрические фигуры. Можно ли каким-то образом использовать для этого стандартные
ф-ции типа FillRect, Ellipse и т.п.?
Re[3]: Произвольный цвет заливки для 8-битной DIB-секции
От: Andrew S Россия http://alchemy-lab.com
Дата: 30.11.04 15:50
Оценка:
PD>>Попробуй здесь вместо AdibDC передать hdc, полученный от GetDC(hAnyWnd)

Xo>Спасибо. Это помогает, если стоит задача отрисовки непосредственно в контексте устройства

Xo>(при этом на самом битмапе фигура не отображается).
Xo>А если рассматривать такой вариант: работа с изображением организована как работа
Xo>с некоторой областью памяти. На нем надо рисовать (заданным цветом) различные
Xo>геометрические фигуры. Можно ли каким-то образом использовать для этого стандартные
Xo>ф-ции типа FillRect, Ellipse и т.п.?

Можно. Все стандартно на MemoryDC. А то, что делаете вы — неверно. Не надо выделять массив malloc'ом, надо просто использовать указатель на поверхность, возвращаемый функцией CreateDIBSection.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[4]: Произвольный цвет заливки для 8-битной DIB-секции
От: Xo  
Дата: 01.12.04 08:37
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>Не надо выделять массив malloc'ом, надо просто использовать указатель на поверхность, возвращаемый функцией CreateDIBSection.


malloc'ом я выделяю память только под структуру BITMAPINFO+палитра.
А при работе с изображением использую указатель AdibBits:

    unsigned char *AdibBits;


AS>Можно. Все стандартно на MemoryDC.


Вроде так и делаю...

MemoryDC:
    HDC AdibDC = CreateCompatibleDC( NULL );


DIBsection:
    HBITMAP AdibBitmap = CreateDIBSection( AdibDC, AdibBMI, DIB_PAL_COLORS, (void **) &AdibBits, NULL, 0 );


Выбор растра, кисти и отрисовка:
    SelectObject( AdibDC, AdibBitmap );
    SelectObject( AdibDC, GetStockObject( WHITE_BRUSH ) );
    Ellipse( AdibDC, 0, 0, 20, 10 );


Где я не прав ?
Re[5]: Произвольный цвет заливки для 8-битной DIB-секции
От: Andrew S Россия http://alchemy-lab.com
Дата: 01.12.04 08:45
Оценка:
AS>>Не надо выделять массив malloc'ом, надо просто использовать указатель на поверхность, возвращаемый функцией CreateDIBSection.

Xo>malloc'ом я выделяю память только под структуру BITMAPINFO+палитра.

Xo>А при работе с изображением использую указатель AdibBits:

У вас размер выделяемой памяти фиксирован ( sizeof( BITMAPINFO ) + sizeof( RGBQUAD ) * 0xff). Зачем тут malloc?

Xo>Выбор растра, кисти и отрисовка:

Xo>
Xo>    SelectObject( AdibDC, AdibBitmap );
Xo>    SelectObject( AdibDC, GetStockObject( WHITE_BRUSH ) );
Xo>    Ellipse( AdibDC, 0, 0, 20, 10 );
Xo>


Xo>Где я не прав ?


Хотя бы в том, что надо сохранять старые объекты, возвращаемые SelectObject, и потом обратно назначать их. Но не суть важно — приведеный код должен отрисовывать эллипс на битмапе. Он это делает или таки нет? Если нет — смотрите возвращаемые значения и GetLastError.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[3]: Произвольный цвет заливки для 8-битной DIB-секции
От: Pavel Dvorkin Россия  
Дата: 01.12.04 08:46
Оценка:
Здравствуйте, Xo, Вы писали:

Xo>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>Попробуй здесь вместо AdibDC передать hdc, полученный от GetDC(hAnyWnd)


Xo>Спасибо. Это помогает, если стоит задача отрисовки непосредственно в контексте устройства


В контексте устройства ничего не рисуется. Рисуется на выбранной в контексте битовой карте, которая и выбрана у тебя.

Xo>(при этом на самом битмапе фигура не отображается).


Отображается. Должна по крайней мере, если она к моменту Ellipse выбрана в контексте.


Xo>А если рассматривать такой вариант: работа с изображением организована как работа

Xo>с некоторой областью памяти. На нем надо рисовать (заданным цветом) различные
Xo>геометрические фигуры. Можно ли каким-то образом использовать для этого стандартные
Xo>ф-ции типа FillRect, Ellipse и т.п.?

Именно так оно и есть. CreateDIBSection возвращает HBITMAP, если ее выбрать в HDC, то рисование пойдет в этой карте (ее можно потом отсоединить от DC и сохранить, к примеру, в файл .bmp). С другой стороны, CreateDIBSection возвращает указатель на байты карты, по нему можно править карту напрямую, независимо от HBITMAP и HDC, да и вообще ни от чего. И то и другое в конечном счете изменяет байты карты.

With best regards
Pavel Dvorkin
With best regards
Pavel Dvorkin
Re[6]: Произвольный цвет заливки для 8-битной DIB-секции
От: Xo  
Дата: 01.12.04 09:18
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>У вас размер выделяемой памяти фиксирован ( sizeof( BITMAPINFO ) + sizeof( RGBQUAD ) * 0xff). Зачем тут malloc?

Согласен

AS>Хотя бы в том, что надо сохранять старые объекты, возвращаемые SelectObject, и потом обратно назначать их.

Часть кода для сохранения/восстановления дескрипторов исходных объектов я временно опустил.

AS>приведеный код должен отрисовывать эллипс на битмапе. Он это делает или таки нет? Если нет — смотрите возвращаемые значения и GetLastError.

Отрисовывает. Только всегда черным цветом, вне зависимости от выбранной кисти и пера Результат вызова ф-ции при этом true, т.е. сама отрисовка проходит успешно. Мне же надо заполнять рисуемую фигуру заданным цветом из палитры (градации серого).
Re[4]: Произвольный цвет заливки для 8-битной DIB-секции
От: Xo  
Дата: 01.12.04 09:26
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

Xo>>А если рассматривать такой вариант: работа с изображением организована как работа

Xo>>с некоторой областью памяти. На нем надо рисовать (заданным цветом) различные
Xo>>геометрические фигуры. Можно ли каким-то образом использовать для этого стандартные
Xo>>ф-ции типа FillRect, Ellipse и т.п.?

PD>Именно так оно и есть. CreateDIBSection возвращает HBITMAP, если ее выбрать в HDC, то рисование пойдет в этой карте.


Рисование происходит. Вот только каким образом можно изменить цвет заливки с черного на какой-либо другой из палитры,
заданной при создании DIB-секции?
Re[7]: Произвольный цвет заливки для 8-битной DIB-секции
От: Andrew S Россия http://alchemy-lab.com
Дата: 01.12.04 15:06
Оценка:
Xo>Отрисовывает. Только всегда черным цветом, вне зависимости от выбранной кисти и пера Результат вызова ф-ции при этом true, т.е. сама отрисовка проходит успешно. Мне же надо заполнять рисуемую фигуру заданным цветом из палитры (градации серого).

Установите при создании диб секции DIB_RGB_COLORS вместо DIB_PAL_COLORS.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[8]: Произвольный цвет заливки для 8-битной DIB-секции
От: Xo  
Дата: 01.12.04 16:20
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>Установите при создании диб секции DIB_RGB_COLORS вместо DIB_PAL_COLORS.

Большое спасибо, Andrew S! Заработало

Правильно ли я понял, что:
    1) DIB_PAL_COLORS указывается при необходимости использования выбранной в DC палитры и при этом значения bmiColors — 16битные индексы из этой самой палитры?
    2) когда в bmiColors задается своя палитра RGB или изображение имеет глубину цвета > 8 бит, DIB-секция должна быть создана с DIB_RGB_COLORS?
Re[9]: Произвольный цвет заливки для 8-битной DIB-секции
От: Andrew S Россия http://alchemy-lab.com
Дата: 01.12.04 16:32
Оценка:
Xo>Правильно ли я понял, что:
Xo>

    Xo>1) DIB_PAL_COLORS указывается при необходимости использования выбранной в DC палитры и при этом значения bmiColors — 16битные индексы из этой самой палитры?

    Да.

    Xo>2) когда в bmiColors задается своя палитра RGB или изображение имеет глубину цвета > 8 бит, DIB-секция должна быть создана с DIB_RGB_COLORS?


    Нет. В этом случае bmiColors может либо не использоваться (т.е. число ентри = 0), либо содержит указанное количество элементов и используется для оптимизации перевода в девайсы, поддерживающие палитру. На практике я не припомню, чтобы кто то эту возможность пользовал.

    Xo>
http://www.rusyaz.ru/pr — стараемся писАть по-русски
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.