Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.64/11: Рейтинг темы: голосов - 11, средняя оценка - 4.64
-2 / 1 / 0
Регистрация: 18.07.2018
Сообщений: 84

.bmp файл загрузить а массив

19.01.2019, 23:38. Показов 2490. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте форумчане. Крайне важный вопрос.

Есть некий .bmp файл, его необходимо загрузить в двумерный массив. Можно ли это сделать так, чтоб в дальнейшем при работе с картинкой не возникло проблем с ее ориентацией относительно осей "x" и "y".
Изначально я пробовал пойти самым распространенным путем - считать данные в динамический массив, а затем переписать данные из динамического массива в двумерный, но картинка приобретает сильнейшие искажения, которые я уже просто не в силах исправить, хотя наверное я перепробовал уже все что только можно.

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

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

Добавлено через 13 минут
Цитата Сообщение от txtbit Посмотреть сообщение
где искать решения подобной ситуации
Имеется ввиду литература, книги, примеры кодов на эту тематику, любая информация относящаяся к этой проблеме....
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
19.01.2019, 23:38
Ответы с готовыми решениями:

Загрузить изображение формата bmp и работать с ним побитово
Мне нужно загрузить изображение формата bmp, чтоб потом работать с его битами. Пробовал так. #define _CRT_SECURE_NO_WARNINGS ...

[Win API] Загрузить и вывести BMP - изображение по клику ЛКМ
Здравствуйте! Подскажите каким образом можно вывести изображение по клику Левой кнопки мыши Загружаю и вывожу так LRESULT...

Сохранить файл в .bmp
Всем здравствуйте и с наступающим Новым Годом. Возникла следующая ситуация: после многих операцтй файл с разрешением .bmp создается...

11
2736 / 891 / 331
Регистрация: 10.02.2018
Сообщений: 2,116
20.01.2019, 00:42
Тут, на форуме, уже было пару тем с кодом для чтения и записи bmp-файлов. Поискать их нужно. Есть две наиболее вероятные проблемы. Первая - чтение/запись в текстовом режиме, в результате добавляются лишние символы, что создаёт видимость хаотичного сдвига строк. Вторая - отсутствие учёта выравнивания строк картинки, если цвет у неё не 32х битный и чтение выполняется единым блоком, то наблюдается равномерный сдвиг строк.
0
Software Developer
 Аватар для fastb1t
315 / 229 / 113
Регистрация: 03.05.2017
Сообщений: 1,336
20.01.2019, 13:55
Кликните здесь для просмотра всего текста
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#define BTV_FROM_FILE 0x01
#define BTV_FROM_RESOURCE 0x02
 
struct DC {
    HDC hDC;
    HBITMAP hBitmap;
    HBITMAP hOldBitmap;
};
 
BOOL DC_Create(struct DC *dc, HBITMAP hBitmap)
{
    if (!dc || !hBitmap)
        return FALSE;
 
    HDC hDC = GetDC(NULL);
    if (hDC)
    {
        dc->hDC = CreateCompatibleDC(hDC);
        dc->hBitmap = hBitmap;
        dc->hOldBitmap = (HBITMAP)SelectObject(dc->hDC, hBitmap);
        ReleaseDC(NULL, hDC);
        return TRUE;
    }
    return FALSE;
}
 
void DC_Clear(struct DC *dc)
{
    if (dc)
    {
        if (dc->hDC && dc->hOldBitmap)
            SelectObject(dc->hDC, dc->hOldBitmap);
        if (dc->hBitmap)
            DeleteObject(dc->hBitmap);
        if (dc->hDC)
            DeleteDC(dc->hDC);
    }
}
 
DWORD **BitmapToArray(LPCSTR lpszName, DWORD iResID, SIZE *size, DWORD dwMode, HINSTANCE hInstance)
{
    if (!size || (dwMode != BTV_FROM_FILE && dwMode != BTV_FROM_RESOURCE) || !hInstance)
        return NULL;
 
    if (dwMode == BTV_FROM_FILE && (!lpszName || !(*lpszName)))
        return NULL;
 
    if (dwMode == BTV_FROM_RESOURCE && !iResID)
        return NULL;
 
    HBITMAP hBitmap;
    DWORD **arr;
    struct DC dc;
 
    hBitmap = NULL;
    arr = NULL;
    RtlZeroMemory(&dc, sizeof(struct DC));
 
    if (dwMode == BTV_FROM_FILE)
    {
        hBitmap = (HBITMAP)LoadImage(hInstance, lpszName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
    }
    else if (dwMode == BTV_FROM_RESOURCE)
    {
        hBitmap = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(iResID), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
    }
 
    if (!hBitmap || !DC_Create(&dc, hBitmap))
    {
        if (hBitmap)
            DeleteObject(hBitmap);
        return NULL;
    }
 
 
    BITMAP bm;
    GetObject(hBitmap, sizeof(BITMAP), &bm);
 
    size->cx = bm.bmWidth;
    size->cy = bm.bmHeight;
 
    BITMAPINFO bi = { 0 };
    bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
    GetDIBits(dc.hDC, dc.hBitmap, 0, 0, NULL, &bi, DIB_RGB_COLORS);
    bi.bmiHeader.biCompression = BI_RGB;
    WORD wColorBits = bi.bmiHeader.biBitCount >> 3;
    if (!wColorBits)
    {
        DC_Clear(&dc);
        return NULL;
    }
 
    BYTE *bytes = (BYTE *)GlobalAlloc(GPTR, bi.bmiHeader.biSizeImage * wColorBits);
    if (bytes)
    {
        GetDIBits(dc.hDC, dc.hBitmap, 0, bi.bmiHeader.biHeight, (LPVOID)bytes, &bi, DIB_RGB_COLORS);
 
        int i, j;
        arr = (DWORD **)malloc((bm.bmHeight + 1) * sizeof(DWORD));
        if (arr)
        {
            for (i = 0; i < bm.bmHeight; i++)
            {
                arr[i] = (DWORD *)malloc((bm.bmWidth + 1) * sizeof(DWORD));
                if (!arr[i])
                {
                    for (j = i - 1; j >= 0; j--)
                    {
                        free(arr[j]);
                    }
                    free(arr);
                    GlobalFree(bytes);
                    DC_Clear(&dc);
                    return NULL;
                }
            }
        }
        else
        {
            GlobalFree(bytes);
            DC_Clear(&dc);
            return NULL;
        }
 
        int x, y;
        for (y = 0; y < bm.bmHeight; y++)
        {
            for (x = 0; x < bm.bmWidth; x++)
            {
                arr[y][x] = RGB(
                    bytes[wColorBits * ((bm.bmHeight - y - 1) * bm.bmWidth + x) + 2],
                    bytes[wColorBits * ((bm.bmHeight - y - 1) * bm.bmWidth + x) + 1],
                    bytes[wColorBits * ((bm.bmHeight - y - 1) * bm.bmWidth + x)]
                );
            }
        }
        GlobalFree(bytes);
    }
    else
    {
        DC_Clear(&dc);
        return NULL;
    }
    DC_Clear(&dc);
    return arr;
}


Тестирование
Кликните здесь для просмотра всего текста
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
DWORD **img;
SIZE size;
 
...
 
// WM_CREATE
    img = BitmapToArray("C:\\Users\\111\\Desktop\\1.bmp", 0, &size, BTV_FROM_FILE, hInstance); // из файла
    //img = BitmapToArray(NULL, 1000, &size, BTV_FROM_RESOURCE, hInstance); // из ресурсов
    if (!img)
    {
        MessageBox(NULL, _T("image not found!"), _T("Error!"), MB_OK | MB_ICONERROR | MB_TOPMOST);
        return FALSE;
    }
 
// WM_PAINT
    if (img)
    {
        int x, y;
        for (y = 0; y < size.cy; y++)
        {
            for (x = 0; x < size.cx; x++)
            {
                SetPixel(hMemDC, x, y, img[y][x]);
            }
        }
    }
 
// WM_DESTROY
    if (img)
    {
        int i;
        for (i = 0; i < size.cy; i++)
            free(img[i]);
        free(img);
    }
 
// Ресурсы:
// 1000 BITMAP DISCARDABLE "C:\\Users\\111\\Desktop\\1.bmp"


Думаю общий смысл будет понятен.
0
-2 / 1 / 0
Регистрация: 18.07.2018
Сообщений: 84
22.01.2019, 11:16  [ТС]
Цитата Сообщение от fastb1t Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
int x, y;
    for (y = 0; y < bm.bmHeight; y++)
        {
             for (x = 0; x < bm.bmWidth; x++)
                 {
                       arr[y][x] = RGB(
                                          bytes[wColorBits * ((bm.bmHeight - y - 1) * bm.bmWidth + x) + 2],
                                          bytes[wColorBits * ((bm.bmHeight - y - 1) * bm.bmWidth + x) + 1],
                                          bytes[wColorBits * ((bm.bmHeight - y - 1) * bm.bmWidth + x)];
                 }
       };
Я могу задавать глупые вопросы, поэтому наберитесь терпения)))

На сколько я понял в этом цикле каждому элементу массива arr[y][x], присваивается цвет из созданного ранее битмапа, в который загружено изображение из файла?

Добавлено через 7 минут
Ygg, в моем случае изображение загружается в массив следующим кодом
C++
1
inpFile.read((char*)ColorsOfBitMap, LoadedImageSize);
ColorsOfBitMap это тот самый массив, а LoadedImageSize это его размер.
Размер определен следующим кодом:
C++
1
2
bytes = ((width * 24 + 31) / 32) * 4;
LoadedImageSize = bytes * height;
Скорее всего вы правы, где то идет
Цитата Сообщение от Ygg Посмотреть сообщение
равномерный сдвиг строк
за счет того что
Цитата Сообщение от Ygg Посмотреть сообщение
добавляются лишние символы
0
-2 / 1 / 0
Регистрация: 18.07.2018
Сообщений: 84
22.01.2019, 11:27  [ТС]
Ygg, Если интерсен результат того что получается, то посмотрите картинку...
Миниатюры
.bmp файл загрузить а массив  
0
-2 / 1 / 0
Регистрация: 18.07.2018
Сообщений: 84
22.01.2019, 14:35  [ТС]
Цитата Сообщение от txtbit Посмотреть сообщение
картинку...
То что она черно белая, это так задумано, конечно она должна быть цветная, но для анализа ошибок мне было проще сделать ее черно-белой, так хоть видно направление ориентацию изображения))))
В норме Марио должен был быть один, на весь размер изображения, и само собой его положение должно было быть повернуто на 90 градусов влево.

Добавлено через 8 минут
Цитата Сообщение от txtbit Посмотреть сообщение
созданного ранее битмапа, в который загружено изображение из файла
Еще вопрос, если изображение больше чем экран, будет работать этот код, или изображение должно быть равным размерам экрана, или чуть меньше?
Например создать DC размерами(2928*4400) превышающими размеры экрана(1366*768) в пикселях, и затем выбрать битмап в этот DC и дальше уже работать с ним по вышеописанному коду.

Добавлено через 2 часа 57 минут
fastb1t, попытался использовать код в своих интересах, адаптировал под себя (просто подставил свои переменные), но в результате просто черный цвет сохранчется, вместо изображения. В чем может быть проблема? Все переписалкак положено...
0
Software Developer
 Аватар для fastb1t
315 / 229 / 113
Регистрация: 03.05.2017
Сообщений: 1,336
22.01.2019, 14:54
Цитата Сообщение от txtbit Посмотреть сообщение
попытался использовать код в своих интересах, адаптировал под себя (просто подставил свои переменные), но в результате просто черный цвет сохранчется, вместо изображения. В чем может быть проблема? Все переписалкак положено...
а до адаптации под себя код работал?
0
-2 / 1 / 0
Регистрация: 18.07.2018
Сообщений: 84
22.01.2019, 15:53  [ТС]
а до адаптации под себя код работал?
Если честно не пробовал. Я его сразу под свои нужды переписал. Но изменений почти нет. Некоторые переменные я так и оставил не переименовывал. По логике все складно написано у Вас, должно работать, но на практике не хочет...

Добавлено через 5 минут
Вопрос.... А структуры обязательно здесь нужны? Я просто без структур все написал.... Может в этом ошибка? Если необходимо я скину позже те части кода, которые я взял и может быть я что то упустил важное, подумав, что в моем случае это не обязательно...
0
Software Developer
 Аватар для fastb1t
315 / 229 / 113
Регистрация: 03.05.2017
Сообщений: 1,336
22.01.2019, 15:58
Цитата Сообщение от txtbit Посмотреть сообщение
Если честно не пробовал. Я его сразу под свои нужды переписал. Но изменений почти нет. Некоторые переменные я так и оставил не переименовывал. По логике все складно написано у Вас, должно работать, но на практике не хочет...
Ну мой код работает...
Вы в любом случае где-то сделали ошибку.
Ну и можно ещё посмотреть в сторону замены функций для выделения памяти malloc/free на операторы new/delete, это в том случае если Вам нужен С++.
Цитата Сообщение от txtbit Посмотреть сообщение
Вопрос.... А структуры обязательно здесь нужны?
Нет. Но так код короче и легче читаемый.
0
-2 / 1 / 0
Регистрация: 18.07.2018
Сообщений: 84
22.01.2019, 16:06  [ТС]
Ну и можно ещё посмотреть в сторону замены функций для выделения памяти malloc/free на операторы new/delete, это в том случае если Вам нужен С++
Вот эти функции я заменил на new и delete. В частности фунцию GlobalAlloc. Это может повлиять на результат?

Добавлено через 1 минуту
Вы в любом случае где-то сделали ошибку.
Знать бы где....

Добавлено через 56 секунд
Буду искать. Уже столько всего пробовал, и это буду до конца бить...

Добавлено через 1 минуту
Ну мой код работает
Это получается код из какого-то проекта?
0
Software Developer
 Аватар для fastb1t
315 / 229 / 113
Регистрация: 03.05.2017
Сообщений: 1,336
22.01.2019, 16:08
txtbit, код покажите...

Добавлено через 43 секунды
Цитата Сообщение от txtbit Посмотреть сообщение
Это получается код из какого-то проекта?
Нет, делал для Вас.
0
-2 / 1 / 0
Регистрация: 18.07.2018
Сообщений: 84
22.01.2019, 23:19  [ТС]
Нет, делал для Вас.
Спасибо.

Код смогу показать позже, сейчас не за компом.

Добавлено через 5 часов 10 минут
Просмотрел внимательно код, прогнал через отладчик. В общем проблем в том, что функция
C++
1
GetDIBits(hDC, LoadPicture, 0, bmInfo.bmiHeader.biHeight, (LPVOID)ColorsOfBitMap, &bmInfo, DIB_RGB_COLORS);
не получает растровые биты как положено. После того как функция отрабатывает, массив ColorsOfBitMap инициализируется один и тем же значением, с которым в последующем работает программа и выдает некорректные результаты.

Добавлено через 1 минуту
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
HBITMAP LoadPicture;
WORD wColorBits;
BITMAPINFO bmInfo;
BYTE *ColorsOfBitMap;
HDC hDC;
 
hDC = CreateCompatibleDC(hDC);
    LoadPicture = (HBITMAP)LoadImageW(NULL, FILE_NAME, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
    hOldBITMAP = (HBITMAP)SelectObject(hDC, LoadPicture);
    GetObject(LoadPicture, sizeof(BITMAP), &hBITMAP);
 
    bmInfo = { 0 };
    bmInfo.bmiHeader.biSize = sizeof(bmInfo.bmiHeader);
    GetDIBits(hDC, LoadPicture, 0, 0, NULL, &bmInfo, DIB_RGB_COLORS);
    bmInfo.bmiHeader.biCompression = BI_RGB;
    wColorBits = bmInfo.bmiHeader.biBitCount >> 3;
 
    ColorsOfBitMap = new BYTE[bmInfo.bmiHeader.biSizeImage * wColorBits];
    memset(ColorsOfBitMap, 0, bmInfo.bmiHeader.biSizeImage * wColorBits);
 
    GetDIBits(hDC, LoadPicture, 0, bmInfo.bmiHeader.biHeight, (LPVOID)ColorsOfBitMap, &bmInfo, DIB_RGB_COLORS);
Это тот участок кода, который я переписал с Вашего примера...

Добавлено через 20 минут
Почему я берусь утверждать что проблема именно в этом месте, потому что сама по себе моя программа рабочая, так как считывая пиксели не с массива, а предположим, с экрана - все отрабатывает очень корректно и правильно. Но мне необходимо научить программу считывать пиксели именно из массива, а не с экрана, потому что в массив я могу загрузить изображение почти любого размера и работать с ним, как мне казалось до этого без проблем, а считывать пиксели с экрана можно только те, которые помещаются на экране, в результате приходиться постоянно резать картинку на части и работать с каждой частью отдельно, что значительно, затрачивает время.

Надеюсь на Вашу помощь в решении этой проблемы...

Добавлено через 1 час 31 минуту
fastb1t, с Вашей помощью, я решил проблему с поставленной задачей. Программа загружает изображение в массив и работает с ним корректно. Загрузку изображения оставил прежнюю, которая была:
C++
1
inpFile.read((char*)ColorsOfBitMap, LoadedImageSize);
только считывание данных из массива ColorsOfBitMap в статический двумерный массив я реализовал по Вашей методике:
C++
1
2
3
4
5
6
7
for (y = 0; y != height; y++)
    {
        for (x = 0; x != width; x++)
        {
            LoadedBitMap[x][y] = RGB(ColorsOfBitMap[3 * ((height - y - 1) * width + x) + 2], ColorsOfBitMap[3 * ((height - y - 1) * width + x) + 1], ColorsOfBitMap[3 * ((height - y - 1) * width + x)]);
        };
    };
заменив переменную wColorBits простой цифрой 3, потому что инициализировать ее и использовать в моем коде просто не представляется возможным.

В общем результат меня радует. Программа делает то что мне надо, и и делает это быстро. Спасибо большое за помощь.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
22.01.2019, 23:19
Помогаю со студенческими работами здесь

Как сохранить картинку из буфера обмена в файл bmp
Ребята, как с помощью WinAPI сохранить картинку из буфера обмена CF_DIB, в файл .bmp Совсем запутался.

Как получить массив из BMP файла
Пишу на c++ Winapi в VisualSudio2013. Мне нужно получить массив с значениями rgb из bmp средствами winapi. Если я не на правильном...

Как можно загрузить файл на хостинг?
Всем привет!!! Может кто подскажет как загрузить файл на хостинг используя WinApi.

Возможно ли конвертировать массив изображений bmp в GIF файл?
Возможно ли конвертировать массив изображений bmp в GIF файл? Также установив скорость

PaintBox, загрузить bmp картинку
имеется форма 1 с scrollbox в котором paintbox, и форма 2 в которой нужно через if открыть форму 1 и paintbox загрузить bmp картинку.


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
Сумматор с применением элементов трёх состояний.
Hrethgir 26.03.2026
Тут. https:/ / fips. ru/ EGD/ ab3c85c8-836d-4866-871b-c2f0c5d77fbc Первый документ красиво выглядит, но без схемы. Это конечно не даёт никаких плюсов автору, но тем не менее. . . всё может быть. . .
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Программный код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере". Алгоритм проверки заполнения реализован для исключения перезаписи значения реквизита,. . .
Команды формы и диалоговое окно
Maks 26.03.2026
1. Команда формы "ЗаполнитьЗапчасти". Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. В качестве источника данных. . .
Кому нужен AOT?
DevAlt 26.03.2026
Решил сделать простой ланчер Написал заготовку: dotnet new console --aot -o UrlHandler var items = args. Split(":"); var tag = items; var id = items; var executable = args;. . .
Отправка уведомления на почту при изменении наименования справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере изменения наименования типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной. . .
модель ЗдравоСохранения 5. Меньше увольнений- больше дохода!
anaschu 24.03.2026
Теперь система здравосохранения уменьшает количество увольнений. 9TO2GP2bpX4 a42b81fb172ffc12ca589c7898261ccb/ https:/ / rutube. ru/ video/ a42b81fb172ffc12ca589c7898261ccb/ Слева синяя линия -. . .
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru