Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> biBitCount 
:(
    Опции темы
nelly
Дата 9.5.2011, 15:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 17.10.2009

Репутация: нет
Всего: нет



Для biBitCount 32 работает. Для 8 при заполнении Bits "...0xC0000005: Access violation writing location 0x00d33000.". Объясните, пожалуйста, как массив заполнять в случае 8 бит на цвет.
Код

void* Bits;
    PBITMAPINFO bpih = (BITMAPINFO*) LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256);// 
    bpih->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bpih->bmiHeader.biWidth = w;
    bpih->bmiHeader.biHeight = -h;
    bpih->bmiHeader.biPlanes = 1;
    bpih->bmiHeader.biBitCount = 8;
    bpih->bmiHeader.biCompression = BI_RGB;
    bpih->bmiHeader.biSizeImage = 0;
    bpih->bmiHeader.biXPelsPerMeter = 0;
    bpih->bmiHeader.biYPelsPerMeter = 0;
    bpih->bmiHeader.biClrUsed = 0;
    bpih->bmiHeader.biClrImportant = 0;
    
        HBITMAP hbm = CreateDIBSection(hdc, bpih, DIB_RGB_COLORS, &Bits, 0, 0);
    for(int y = 0;y < h;y++)
            {
                for(int x = 0; x < w; x++)
                {
                    ((unsigned*)Bits)[y*w+x] = RGB(0,0,255);//(dst[y][x].b,dst[y][x].g,dst[y][x].r);
                }
            }

PM MAIL   Вверх
GremlinProg
Дата 9.5.2011, 19:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



8 бит - это не unsigned, это BYTE
+ COLORREF и RGBQUAD - не одно и то же
+ для 8 бит в Bits вобще не должно быть ни каких цветовых характеристик,
там только 8-битные индексы в палитру, которая ставится либо при создании диб-секции, в bmiColors,
либо отдельно, функцией  SetDIBColorTable

но первое, конечно - причина подъема исключения, остальное - так, последующие шаги в решении задачи


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
nelly
Дата 9.5.2011, 19:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 17.10.2009

Репутация: нет
Всего: нет



Спасибо за ответ. С байт работает. Только вот палитры у меня нет) Получается, мне нужно таки использовать 32 или 24? У меня есть просто матрица со значениями цветов пикселей, которые я получила после применения фильтра к 8-битной картинке. Но с 32 картинка выглядит не совсем так, как хотелось бы....В чем может быть проблема?
user posted image

PM MAIL   Вверх
GremlinProg
Дата 10.5.2011, 06:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(nelly @  9.5.2011,  21:53 Найти цитируемый пост)
Получается, мне нужно таки использовать 32 или 24?

да, если подразумевается именно такая попиксельная генерация изображения, как в цикле

а если требуется все-таки 8бит, их можно получить впоследствии,
преобразовав полноцветный растр к 8битному (но уже, как правило, с некоторой потерей в качестве)

Добавлено через 3 минуты и 9 секунд
но если требуется просто скопировать изображение, то у исходного 8битного уже есть палитра,
ее и надо скопировать в bmiColors, тогда лишних преобразований не потребуется


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
nelly
Дата 10.5.2011, 06:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 17.10.2009

Репутация: нет
Всего: нет



Исходное 8-битное у меня есть, и палитра там есть, мне на это изображение нужно наложить какой-нибудь фильтр(3х3). После того как применила фильтр, как я понимаю, использовать старую палитру нельзя...цвета то другие. Как получить новую палитру у меня никаких идей нет. 
PM MAIL   Вверх
Earnest
Дата 10.5.2011, 09:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



"Какой-нибудь" фильтр бессмысленно накладывать на палитровое изображение. Маска 3*3 подразумевает свертку или что-то вроде, а эта арифметика с индексами палитры не имеет никакого смысла.  
Так что ты не другие цвета получаешь, а просто мусор, просто по определению.
Кроме одного случая - серошкального изображения, когда палитра представляет собой (0,0,0), (1,1,1) ... (255,255,255). В этом случае индексы эквивалентны уровню яркости и их вполне можно обсчитывать маской. И палитра при этом не изменяется.
В остальных случая изображение нужно преобразовывать в полноцветное (т.е 24 бита) и тогда выполнять преобразования. Затем можно оставить как есть, либо преобразовать к 256 цветам, подобрав подходящую палитру. Но это нетривиальный алгоритм.



--------------------
...
PM   Вверх
GremlinProg
Дата 10.5.2011, 09:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(nelly @  10.5.2011,  08:52 Найти цитируемый пост)
Как получить новую палитру у меня никаких идей нет.

Цитата(Earnest @  10.5.2011,  11:05 Найти цитируемый пост)
либо преобразовать к 256 цветам, подобрав подходящую палитру

квантование или выделение палитры на основе заданной по идее должно производиться автоматически,
если отрисовать полученный полноцветный растр на 8битном холсте

Добавлено через 5 минут и 21 секунду
хотя, нет, все равно придется ее хотя бы сформировать (например равномерно распределить 256 цветов или взять системную палитру),
а индексы - конечно должны расставиться в соответствии с ближайшим доступным в этой палитре цветом


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
GremlinProg
Дата 10.5.2011, 09:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



хотя ... :))
наверное всетаки можно попросить систему сделать такое преобразование: через GetDIBits указать в качестве формата назначения 8битный

и поработать с параметрами biClrUsed и biClrImportant,
т.е. сказать сначала, что мол нет у меня в палитре цветов, чтобы на выходе получить их автоматически

Добавлено через 51 секунду
Цитата(GremlinProg @  10.5.2011,  11:46 Найти цитируемый пост)
сказать сначала, что мол нет у меня в палитре цветов

т.е. занулить их


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
nelly
Дата 10.5.2011, 14:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 17.10.2009

Репутация: нет
Всего: нет



Цитата

"Какой-нибудь" фильтр бессмысленно накладывать на палитровое изображение. Маска 3*3 подразумевает свертку или что-то вроде, а эта арифметика с индексами палитры не имеет никакого смысла.  
Так что ты не другие цвета получаешь, а просто мусор, просто по определению.

Не, ну я на основе палитры и индексов формировала цвета.
Я делала так. B buf лежат те самые индексы на цвета в палитре. Кстати, получены они ракодированием gif картинки (с помощью кода найденного в сети). Картинка отображается верно.
Чтоб получить матрицу непосредственно цветов
Код

for (int i = 0; i < height; i++)
        for (int j = 0; j < width; j++)
        {
            ColorMat[i][j].r = lpbi->bmiColors[buf[i*width+j]].rgbRed;
            ColorMat[i][j].g = lpbi->bmiColors[buf[i*width+j]].rgbGreen;
            ColorMat[i][j].b = lpbi->bmiColors[buf[i*width+j]].rgbBlue;
        }

Фильтр накладывала так:
Код

    for(int x = 0; x < h; x++) 
        for(int y = 0; y < w; y++) 
    { 
        double red = 0.0, green = 0.0, blue = 0.0;    
        //multiply every value of the filter with corresponding image pixel 
        for(int filterX = 0; filterX < filterWidth; filterX++) 
        for(int filterY = 0; filterY < filterHeight; filterY++) 
        { 
            int imageX = (x - filterWidth / 2 + filterX + h) % w; 
            int imageY = (y - filterHeight / 2 + filterY + w) % h; 
            red += ColorMat[imageX][imageY].r * filter[filterX][filterY]; 
            green += ColorMat[imageX][imageY].g * filter[filterX][filterY]; 
            blue += ColorMat[imageX][imageY].b * filter[filterX][filterY]; 
        }         
        //truncate values smaller than zero and larger than 255 
            dst[x][y].r = min(max(int(factor * red + bias), 0), 255); 
            dst[x][y].g = min(max(int(factor * green + bias), 0), 255); 
            dst[x][y].b = min(max(int(factor * blue + bias), 0), 255);
    }

Ну и потом
Код

for(int y = 0;y < h;y++)
            {
                for(int x = 0; x < w; x++)
                {
                    ((unsigned*)Bits)[y*w+x] = RGB(dst[y][x].b,dst[y][x].g,dst[y][x].r);
                }
            }



После некоторых усовершенствований такой результат...Это 32 бита
user posted image

Это сообщение отредактировал(а) nelly - 10.5.2011, 14:53
PM MAIL   Вверх
GremlinProg
Дата 11.5.2011, 06:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(nelly @  10.5.2011,  16:34 Найти цитируемый пост)
После некоторых усовершенствований такой результат...Это 32 бита

такое очючение, что в buf индексы лежат не с самого начала исходного растра, поэтому здесь сдвиг картинки
Цитата(nelly @  10.5.2011,  16:34 Найти цитируемый пост)
((unsigned*)Bits)[y*w+x] = RGB(dst[y][x].b,dst[y][x].g,dst[y][x].r);

вот это-то и не правильно,
какой смысл в индекс впихивать RGB?

в dst теперь полноцветный отфильтрованный растр,
его можно скормить GetDIBits и получить пормальный 8битный, без махинаций

но это уже другая проблема, к виду картинки она отношения пока не имеет


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
nelly
Дата 11.5.2011, 14:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 17.10.2009

Репутация: нет
Всего: нет



Цитата

Цитата

((unsigned*)Bits)[y*w+x] = RGB(dst[y][x].b,dst[y][x].g,dst[y][x].r);

вот это-то и не правильно,
какой смысл в индекс впихивать RGB?

Что-то я совсем запуталась. Я думала для 32-битного не индексы нужны, а сами цвета.
Это с MSDN для 32:
Цитата

Each DWORD in the bitmap array represents the relative intensities of blue, green, and red, respectively, for a pixel.

PM MAIL   Вверх
nelly
Дата 11.5.2011, 16:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 17.10.2009

Репутация: нет
Всего: нет



Спасибо всем огромное за помощь.
Проблема решилась, я просто сделала дурацкую опечатку в коде, где на фильтр умножается.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0549 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.