Форум программистов, компьютерный форум CyberForum.ru

Мучение: Создание из двумерного массива bitmap-а в оттенках серого - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 17, средняя оценка - 4.59
vikkey
0 / 0 / 0
Регистрация: 01.12.2011
Сообщений: 8
01.12.2011, 11:58     Мучение: Создание из двумерного массива bitmap-а в оттенках серого #1
Требуется помощь:
Осуществлен вывод значений двумерного массива значений в рабочее окно программы с помощью SetPixel(...). Однако это вариант не подходит из-за медленной отрисовки этого массива. (2D Массив представляет собой изображение 8 разр. в оттенках серого).
Пробую следующим кодом, создавая предварительно динамический массив
...
const int FLAGZOOM = 600;
unsigned char * RusFlag[FLAGZOOM*FLAGZOOM];
...
и заполняя его, создать bitmap, чтобы потом отобразить его на экране стандартными способами. Умею загружать bitmap-ы с диска и отображать, но с этим просто беда: отображаются, простите, вертикальные розовые полосы. Где вкралась ошибка? HELP!!!
кусок кода в array_to_bitmap.txt
Вложения
Тип файла: txt array_to_bitmap.txt (1.3 Кб, 44 просмотров)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.12.2011, 11:58     Мучение: Создание из двумерного массива bitmap-а в оттенках серого
Посмотрите здесь:

C++ Создание и вывод двумерного массива
Создание двумерного массива C++
C++ Создание двумерного массива
создание двумерного массива C++
C++ Создание двумерного динамического массива
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
BRcr
 Аватар для BRcr
4003 / 2292 / 155
Регистрация: 03.02.2011
Сообщений: 5,064
Записей в блоге: 10
01.12.2011, 12:24     Мучение: Создание из двумерного массива bitmap-а в оттенках серого #2
vikkey, лучше выкладывайте так, вам куда как быстрее помогут:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
 // ___________________________________________Создаем как bmp
                   HDC hdc, hdcm;
    HBITMAP hBitmap;
    char buffer[20], *s;
    int length = 0;
    int h;
 
    // Структура для описания Bitmap
    BITMAPINFOHEADER bmi = {sizeof( bmi ), FLAGZOOM, -FLAGZOOM, 1, 8, BI_RGB, 0, 0, 0, 0, 0};
    // Заполнение массива цветами
    int i = 0, m, l, jj;
    do {
        for ( l = 0; l < FLAGZOOM; l++ ) {
            for ( m = 0; m < FLAGZOOM; m++ ) {
                h = ( int )floor( ArrayWindow[l][m] );
                char str[10] = "0x00";
                s = itoa( h, buffer, 16 );
                length = strlen( s );
                if ( length < 2 ) {
                    for ( jj = 0; jj < 3; jj++ ) {
                        strcat( str, "0" );
                        strcat( str, s );
                    }
                }
                else {
                    for ( jj = 0; jj < 3; jj++ ) {
                        strcat( str, s );
                    }
                }
                RusFlag[i] = ( unsigned char * ) str;
                i++;
            }
        }
    }while ( i < FLAGZOOM * FLAGZOOM );
 
    // Преобразование массива в Bitmap
    hdc = GetDC( hWnd );
    hdcm = CreateCompatibleDC( hdc );
    hBitmap = CreateCompatibleBitmap( hdc, FLAGZOOM, FLAGZOOM );
    SetDIBits( hdcm, hBitmap, 0, 600, RusFlag, ( LPBITMAPINFO ) &bmi, DIB_RGB_COLORS );
    // Вывод Bitmap на экран
    SelectObject( hdcm, hBitmap );
    BitBlt( hdc, 0, 0, FLAGZOOM, FLAGZOOM, hdcm, 0, 0, SRCCOPY );
    // Oai?ea ioni?a
    DeleteObject( hBitmap );
    DeleteDC( hdcm );
    ReleaseDC( hWnd, hdc );
    // ____________________________________________End блока
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
02.12.2011, 11:39     Мучение: Создание из двумерного массива bitmap-а в оттенках серого #3
Используй SetPixelV, она быстрее.)
vikkey
0 / 0 / 0
Регистрация: 01.12.2011
Сообщений: 8
05.12.2011, 10:52  [ТС]     Мучение: Создание из двумерного массива bitmap-а в оттенках серого #4
Выполнена замена SetPixel(...) на SetPixelV(...). Что-то жизнь лучше не стала; ну, может, самую малость... Однако всё одно - не то, что надо!
vikkey
0 / 0 / 0
Регистрация: 01.12.2011
Сообщений: 8
05.12.2011, 11:00  [ТС]     Мучение: Создание из двумерного массива bitmap-а в оттенках серого #5
Попробую расширить формулировку проблемы наглядными "примерами".
Добавлю скриншоты окна программы:
1. левое верхнее изображение - работа этого самого кода, который выложил BRcr;
2. если записать RusFlag[i]=(unsigned char *)h, то выводит то, что отображено вверху справа;
3. пример замены 8 -> 32 в BITMAPINFOHEADER bmi={sizeof(bmi),FLAGZOOM,-FLAGZOOM,1,32,BI_RGB,0,0,0,0,0} и RusFlag[i]=(unsigned char *)h показан внизу слева (только синий канал отображается);
4. внизу справа - то, что должно быть.

Ну, помогите же кто-нибудь!!!
Миниатюры
Мучение: Создание из двумерного массива bitmap-а  в оттенках серого  
BRcr
 Аватар для BRcr
4003 / 2292 / 155
Регистрация: 03.02.2011
Сообщений: 5,064
Записей в блоге: 10
05.12.2011, 17:52     Мучение: Создание из двумерного массива bitmap-а в оттенках серого #6
Цитата Сообщение от vikkey Посмотреть сообщение
Попробую расширить формулировку проблемы наглядными "примерами".
Это полезно, конечно, но вторично.
Для полного счастья лучше выложите побольше кода, например, объявления и определения переменных FLAGZOOM, ArrayWindow, RusFlag, покажите, что вы с ними делаете до этого кода.
vikkey
0 / 0 / 0
Регистрация: 01.12.2011
Сообщений: 8
06.12.2011, 03:56  [ТС]     Мучение: Создание из двумерного массива bitmap-а в оттенках серого #7
Да ничего я с ними не делаю особенного: объявляю как глобальные. В первом сообщении, когда создавалась тема, указано как это делалось.
ArrayWindow[l][m] - обыкновенный двумерный массив типа double; значения в нем меняются от 0 до 255 (всё стандартно как для 8 разр изображения). Заполнить его можно как угодно: хоть случайными числами! Главное, чтобы значения их были от 0 до 255... Объявляется тоже как глобальный в самом начале программы после перечисления всех библиотек.
...
double ArrayWindow[600][600]={0.0};
...
Это мной здесь показан пример работы с конкретным изображением, каждый пиксель которого присваивается отдельному элементу массива ArrayWindow[l][m]. Для своего примера можно заполнить массив ArrayWindowRGB каким-нибудь другим изображением или вообще синтезировать и забить случайными числами от 0 до 255.
Дело не в том, что содержит ArrayWindow[l][m], а то как его отобразить в окне программы!? А нужно, чтобы отображался он в оттенках серого, как черно-белая фотография. А у меня пока не получается, -выложенный кусок кода зачем-то его раскрашивает или еренду выводит на экран, - и связано это не с предшествующими действиями над FLAGZOOM, ArrayWindow или RusFlag, а с неправильным представлением переменной str, значения которой присваиваются RusFlag[i].

Если я правильно понимаю, чтобы все было в оттенках серого надо в маски синего, красного и зеленого каналов записать одинаковые значения.
При этом для синей маски заполняются биты:
"0x000000NN", где N -значение h в 16 разр. представлении;
для зеленой - "0x0000NN00",
и для красной - "0x00NN0000".
В итоге, чтобы активировать все каналы цветов и получить именно в оттенках серого, а не цветное, надо записать так:
"0x00NNNNNN"

Теорию я понимаю, но реализовать программно не получается! Где-то ошибка вкралась! О_о
Подскажите, люди добрые!
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
06.12.2011, 06:12     Мучение: Создание из двумерного массива bitmap-а в оттенках серого #8
Для изображения в градациях серого, тебе нужно либо задавать одинаковые компоненты RGB, то приведёт к увеличению размера картинки, либо использовать индексированное изображение с чёрно-белой палитрой.
Самый быстрый способ это не SetPixel, разумеется, а непосредственное редактирование массива битов (массив всегда одномерный). При этом строки могут быть расположены не подряд, а с некоторым интервалом, необходимым для выравнивания. Кроме того, они могут располагаться в обратном порядке, т.е. первая строка будет не верхней, а нижней в изображении.
Больше писать не хочу - MSDN, RTFM.
vikkey
0 / 0 / 0
Регистрация: 01.12.2011
Сообщений: 8
06.12.2011, 07:06  [ТС]     Мучение: Создание из двумерного массива bitmap-а в оттенках серого #9
Цитата Сообщение от Deviaphan Посмотреть сообщение
нужно либо задавать одинаковые компоненты RGB
Всё верно. Именно это и пытаюсь сделать, когда заполняю переменную str.

Цитата Сообщение от Deviaphan Посмотреть сообщение
Самый быстрый способ это не SetPixel, разумеется
Именно так! С SetPixel идет медленная отрисовка по столбцам изображения/массива ArrayWindow.

Цитата Сообщение от Deviaphan Посмотреть сообщение
непосредственное редактирование массива битов (массив всегда одномерный)
Да, так и есть, массив битов RusFlag у меня одномерный, но где-то в коде ошибка и, возможно, очень простая. Однако я ее не нахожу.
BRcr
 Аватар для BRcr
4003 / 2292 / 155
Регистрация: 03.02.2011
Сообщений: 5,064
Записей в блоге: 10
06.12.2011, 17:16     Мучение: Создание из двумерного массива bitmap-а в оттенках серого #10
C++
1
2
3
char str[10] = "0x00";
//...
RusFlag[i] = ( unsigned char * ) str;
str объявлена в теле цикла for, соответственно по завершении этого цикла она будет уничтожена и память, ею занимаемая, будет освобождена. После этого указатели в массиве будут указывать на участки памяти, которые системой считаются свободными, и которые уже могут быть перезаписаны, по идее.

Если вам надо забить массив указателей на строчки, делайте эти строчки в цикле динамически :
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
unsigned char * str;
 
for ( m = 0; m < FLAGZOOM; m++ ) {
  //...
  str = new char[10];
  strcpy(str, "0x00");
  //...
  strcat( str, "0" );
  //...
  RusFlag[i] = str;
}
  //...
  //...
delete[] RusFlag;
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
06.12.2011, 19:26     Мучение: Создание из двумерного массива bitmap-а в оттенках серого #11
Цитата Сообщение от vikkey Посмотреть сообщение
у меня одномерный
Ширина строки байт, описывающих изображение почти наверняка не равна ширине изображения в пикселах. Из-за этого изображение рисуется скошенным (на второй картинке на это похоже).
vikkey
0 / 0 / 0
Регистрация: 01.12.2011
Сообщений: 8
08.12.2011, 11:16  [ТС]     Мучение: Создание из двумерного массива bitmap-а в оттенках серого #12
Всё оказалось действительно просто, как и предполагалось!
str надо действительно заполнять по-другому и код сократился! Посмеюсь над собой
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//________________________________________
        HDC hdc,hdcm;
        HBITMAP hBitmap;
 
        BITMAPINFOHEADER bmi={sizeof(bmi),FLAGZOOM,-FLAGZOOM,1,24,BI_RGB,0,0,0,0,0};
        int i=0,m,l;//,jj;
        do {
    for (l=0;l<FLAGZOOM;l++) {
      for (m=0;m<FLAGZOOM;m++) {
                unsigned char str = floor(ArrayWindow[l][m]);
        RusFlag[i] = str;
        RusFlag[i+1] = str;
        RusFlag[i+2] = str;
        i += 3;
       }
    }
        }while (i<FLAGZOOM*FLAGZOOM);
 
        hdc=GetDC(hWnd);
        hdcm=CreateCompatibleDC(hdc);
        hBitmap=CreateCompatibleBitmap(hdc,FLAGZOOM,FLAGZOOM);
        SetDIBits(hdcm,hBitmap,0,600,RusFlag,(LPBITMAPINFO)&bmi,DIB_RGB_COLORS);
        SelectObject(hdcm,hBitmap);
        BitBlt(hdc,0,0,FLAGZOOM,FLAGZOOM,hdcm,0,0,SRCCOPY);
        DeleteObject(hBitmap);
        DeleteDC(hdcm);
        ReleaseDC(hWnd,hdc);
//____________________________________________
При этом массив RusFlag объявить надо следующим образом:
C++
1
2
3
//...
unsigned char RusFlag[3*FLAGZOOM*FLAGZOOM];
//...
Тему можно закрывать! Хотя ... не удалять ... чтобы другие новички не наступали на те же грабли...
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
08.12.2011, 11:41     Мучение: Создание из двумерного массива bitmap-а в оттенках серого #13
Цитата Сообщение от vikkey Посмотреть сообщение
BITMAPINFOHEADER bmi={sizeof(bmi),FLAGZOOM,-FLAGZOOM,1,24,BI_RGB,0,0,0,0,0};
Можно высоту положительной задавать, но тогда строки снизу вверх заполнять придётся.

Ну и теперь, когда ты уже разобрался, я бы посоветовал реализовать то же самое, но с индексированной картинкой.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.12.2011, 11:53     Мучение: Создание из двумерного массива bitmap-а в оттенках серого
Еще ссылки по теме:

Создание двумерного массива C++
C++ Создание двумерного массива
C++ Создание динамического двумерного массива

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
vikkey
0 / 0 / 0
Регистрация: 01.12.2011
Сообщений: 8
08.12.2011, 11:53  [ТС]     Мучение: Создание из двумерного массива bitmap-а в оттенках серого #14
Цитата Сообщение от Deviaphan Посмотреть сообщение
посоветовал реализовать то же самое, но с индексированной картинкой
... О_о
Ой, нет спасибо... У меня из-за этого куска итак простой в работе! Столько уже всего накопилось... Пусть кто-нибудь другой попробует. А я буду просто заглядывать и посматривать... и копировать...
Yandex
Объявления
08.12.2011, 11:53     Мучение: Создание из двумерного массива bitmap-а в оттенках серого
Ответ Создать тему
Опции темы

Текущее время: 10:17. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru