Форум программистов, компьютерный форум, киберфорум
C++/CLI Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.76/21: Рейтинг темы: голосов - 21, средняя оценка - 4.76
1 / 1 / 0
Регистрация: 28.04.2013
Сообщений: 65

Работа с BMP файлом

18.06.2014, 08:59. Показов 4318. Ответов 34
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
считывание с файла в масив
Кликните здесь для просмотра всего текста
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
public:      int *loadBMP( const char *fname, int &mx, int &my )
{ int *v;
   mx = my = -1;
    FILE *f = fopen( fname, "rb" );
    if( !f ) return NULL;
    BMPheader bh;    // File header sizeof(BMPheader) = 56
    size_t res;
 
    // читаем заголовок
    res = fread( &bh, 1, sizeof(BMPheader), f );
    if( res != sizeof(BMPheader) ) { fclose(f); return NULL; }
 
    // проверяем сигнатуру
    if( bh.bfType!=0x4d42 && bh.bfType!=0x4349 && bh.bfType!=0x5450 ) { fclose(f); return NULL; }
 
    // проверка размера файла
    fseek( f, 0, SEEK_END);
    int filesize = ftell(f);
    // восстановим указатель в файле:
    fseek( f, sizeof(BMPheader), SEEK_SET);
    // проверим условия
    if( bh.bfSize != filesize ||
        bh.bfReserved != 0    ||
        bh.biPlanes   != 1    ||
       (bh.biSize!=40 && bh.biSize!=108 && bh.biSize!=124)||
        bh.bfOffBits != 14+bh.biSize ||
 
        bh.biWidth <1 || bh.biWidth >10000 ||
        bh.biHeight<1 || bh.biHeight>10000 ||
        bh.biBitCount    != 24 ||             // пока рассматриваем только полноцветные изображения
        bh.biCompression !=  0                // пока рассматриваем только несжатие изображения
        ) 
    { 
            fclose(f); 
            return NULL; 
    }
    // Заголовок прочитан и проверен, тип - верный (BGR-24), размеры (mx,my) найдены
     mx = bh.biWidth;
     my = bh.biHeight;
    int mx3 = (3*mx+3) & (-4);    // Compute row width in file, including padding to 4-byte boundary
    unsigned char *tmp_buf = new unsigned  char[mx3*my];    // читаем данные
    res = fread( tmp_buf, 1, mx3*my, f);
    if( (int)res != mx3*my ) { delete []tmp_buf; fclose(f); return NULL; }
    // данные прочитаны
    fclose(f); 
 
    // выделим память для результата
  v = new int[mx*my];
 
    // Перенос данных (не забудем про BGR->RGB)
    unsigned char *ptr = (unsigned char *) v;
    for(int y = my-1; y >= 0; y--) {
        unsigned char *pRow = tmp_buf + mx3*y;
        for(int x=0; x< mx; x++) {
            *ptr++ = *(pRow + 2);
            *ptr++ = *(pRow + 1);
            *ptr++ = *pRow; 
            pRow+=3;
            ptr ++;
        }
    }
    delete []tmp_buf;
    return v;    // OK
}

запись файл
Кликните здесь для просмотра всего текста
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
public:   int  saveBMP( const char *fname, int *v, int mx, int my ) // В каждом элементе упаковано все три RGB-байта
{
    BMPheader bh;   // Заголовок файла, sizeof(BMPheader) = 56
    memset( &bh, 0, sizeof(bh) );
    bh.bfType =0x4d42;  // 'BM'
    // Найдем длину строки в файле, включая округление вверх до кратного 4:
    int mx3 = (3*mx+3) & (-4);
    int filesize = 54 + my*mx3;
    bh.bfSize = filesize;
    bh.bfReserved =  0;
    bh.biPlanes   =  1;
    bh.biSize     = 40;
    bh.bfOffBits  = 14 + bh.biSize;
    bh.biWidth    = mx;
    bh.biHeight   = my;
    bh.biBitCount = 24;
    bh.biCompression= 0;
 
    FILE *f = fopen( fname, "wb" );
    if( !f ) return -1;
    size_t res;
 
    // пишем заголовок
    res = fwrite( &bh, 1, sizeof(BMPheader), f );
    if( res != sizeof(BMPheader) ) { fclose(f); return -1; }
 
    // приготовим временный буфер
    unsigned char *tmp_buf = new unsigned char[mx3*my];
    // Перенос данных (не забудем про RGB->BGR)
    unsigned char *ptr = (unsigned char *) v;
    for(int y = my-1; y >= 0; y--) {
        unsigned char *pRow = tmp_buf + mx3*y;
        for(int x=0; x< mx; x++) {
            *(pRow + 2) = *ptr++;
            *(pRow + 1) = *ptr++;
            *pRow       = *ptr++; 
            pRow+=3;
            ptr++;
        }
    }
    // сбросим в файл
    fwrite( tmp_buf, 1, mx3*my, f );
    fclose(f);
    delete []tmp_buf;
    return 0;   // OK
}

вызов функций
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
        int mx, my;                              // для размеров изображения
    int *v = loadBMP("picture.bmp", mx, my); // выделяем память и читаем туда файл
    //System::Windows::Forms::MessageBox::Show("Load ok");
    
 //   pictureBox1->Image=Image::FromFile("picture.bmp");
    delete [] v; 
             }
        
    private: System::Void button2_Click(System::Object^  sender, System::EventArgs^  e) {
                
                int* v=new int;
             char t1[] ="picture.bmp";
     int  mx=Matrix_mx(t1);
    int   my=Matrix_my(t1);
            
           // для размеров изображения
           if   (saveBMP(t1,  v ,   mx, my)   ==0)    MessageBox::Show("Saved ok") ; else MessageBox::Show("ERROR");
             delete  v; 
         }


по идее с массива должен записываться тот же файл, но создается пустой файл bmp(только заголовок файла)
1)В чем проблема? где я чтото не так делаю?
2)как лучше использовать етот массив для обработки битов цветов
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
18.06.2014, 08:59
Ответы с готовыми решениями:

Работа с BMP файлом
Доброго всем дня. Мне нужно сделать приложение которое будет работать с BMP рисунком. То есть суть программки приблизительно такая: 1....

Работа с BMP файлом.
Помогите, с чего начать? Требуется написать программу, которая открывает файл bmp и заменяет в нём каждый 10 байт на байты из текстового...

Простейшая работа с BMP-файлом
Добрый день! Только начал работать с Python, версия 3.4,разбираюсь. Пробую для начала окрасить пиксель в bmp-файле, но возникают проблемы...

34
106 / 87 / 13
Регистрация: 29.08.2012
Сообщений: 538
18.06.2014, 09:42
что говорит отладчик? сколько байтов записано/прочитано?
0
327 / 230 / 55
Регистрация: 30.05.2014
Сообщений: 682
18.06.2014, 10:01
А декларацию BMPheader можно?
Это Managed C++? У него есть классы для этой цели, зачем руками-то?
1
1 / 1 / 0
Регистрация: 28.04.2013
Сообщений: 65
18.06.2014, 11:28  [ТС]
А декларацию BMPheader можно?
Кликните здесь для просмотра всего текста
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
typedef struct {
      unsigned __int16   bfType;         // 0x4d42 | 0x4349 | 0x5450
      int                bfSize;         // размер файла
      int                bfReserved;     // 0
      int                bfOffBits;      // смещение до поля данных,
                             // обычно 54 = 16 + biSize
      int                biSize;         // размер струкуры в байтах:
                             // 40(BITMAPINFOHEADER) или 108(BITMAPV4HEADER)
                             // или 124(BITMAPV5HEADER)
      int                biWidth;        // ширина в точках
      int                biHeight;       // высота в точках
      unsigned __int16   biPlanes;       // всегда должно быть 1
      unsigned __int16   biBitCount;     // 0 | 1 | 4 | 8 | 16 | 24 | 32
      int                biCompression;  // BI_RGB | BI_RLE8 | BI_RLE4 |
                             // BI_BITFIELDS | BI_JPEG | BI_PNG
                             // реально используется лишь BI_RGB
      int                biSizeImage;    // Количество байт в поле данных
                             // Обычно устанавливается в 0
      int                biXPelsPerMeter;// горизонтальное разрешение, точек на дюйм
      int                biYPelsPerMeter;// вертикальное разрешение, точек на дюйм
      int                biClrUsed;      // Количество используемых цветов
                             // (если есть таблица цветов)
      int                biClrImportant; // Количество существенных цветов.
                             // Можно считать, просто 0
} BMPheader;


работаю в VS 2010
сколько байтов записано/прочитано?
а можно спросить где ето можно посмотреть?
0
327 / 230 / 55
Регистрация: 30.05.2014
Сообщений: 682
18.06.2014, 12:05
Цитата Сообщение от voldkost Посмотреть сообщение
работаю в VS 2010
C++
1
System::Void button1_Click(System::Object^  sender, System::EventArgs^  e)
Вот это Managed C++, в его библиотеке есть класс System::Drawing::Bitmap, которым формирование графического файла из растра делается строк в 30-40 со всеми выравниваниями и перестановками.

Цитата Сообщение от voldkost Посмотреть сообщение
а можно спросить где ето можно посмотреть?
C
1
res = fwrite( &bh, 1, sizeof(BMPheader), f );
вот это запись по одному байту до sizeof(BMPheader), res будет количество реально записанных байт.

Добавлено через 20 минут
Оно работает, 54 байта пишется, когда не прочитан исходный файл.

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
147
148
149
150
#include <stdio.h>
#include <string.h>
 
#pragma pack(push,1)
typedef struct {
      unsigned __int16   bfType;         // 0x4d42 | 0x4349 | 0x5450
      int                bfSize;         // размер файла
      int                bfReserved;     // 0
      int                bfOffBits;      // смещение до поля данных,
                             // обычно 54 = 16 + biSize
      int                biSize;         // размер струкуры в байтах:
                             // 40(BITMAPINFOHEADER) или 108(BITMAPV4HEADER)
                             // или 124(BITMAPV5HEADER)
      int                biWidth;        // ширина в точках
      int                biHeight;       // высота в точках
      unsigned __int16   biPlanes;       // всегда должно быть 1
      unsigned __int16   biBitCount;     // 0 | 1 | 4 | 8 | 16 | 24 | 32
      int                biCompression;  // BI_RGB | BI_RLE8 | BI_RLE4 |
                             // BI_BITFIELDS | BI_JPEG | BI_PNG
                             // реально используется лишь BI_RGB
      int                biSizeImage;    // Количество байт в поле данных
                             // Обычно устанавливается в 0
      int                biXPelsPerMeter;// горизонтальное разрешение, точек на дюйм
      int                biYPelsPerMeter;// вертикальное разрешение, точек на дюйм
      int                biClrUsed;      // Количество используемых цветов
                             // (если есть таблица цветов)
      int                biClrImportant; // Количество существенных цветов.
                             // Можно считать, просто 0
} BMPheader; 
#pragma pack(pop)
 
int *loadBMP( const char *fname, int &mx, int &my )
{  
   int *v;
   mx = my = -1;
   FILE *f = fopen( fname, "rb" );
   if( !f ) return NULL;
   BMPheader bh;    // File header sizeof(BMPheader) = 56
   size_t res;
 
   // читаем заголовок
   res = fread( &bh, 1, sizeof(BMPheader), f );
   if( res != sizeof(BMPheader) ) { fclose(f); return NULL; }
 
   // проверяем сигнатуру
   if( bh.bfType!=0x4d42 && bh.bfType!=0x4349 && bh.bfType!=0x5450 ) { fclose(f); return NULL; }
 
   // проверка размера файла
   fseek( f, 0, SEEK_END);
   int filesize = ftell(f);
   // восстановим указатель в файле:
   fseek( f, sizeof(BMPheader), SEEK_SET);
   // проверим условия
   if( bh.bfSize != filesize ||
        bh.bfReserved != 0    ||
        bh.biPlanes   != 1    ||
       (bh.biSize!=40 && bh.biSize!=108 && bh.biSize!=124)||
        bh.bfOffBits != 14+bh.biSize ||
 
        bh.biWidth <1 || bh.biWidth >10000 ||
        bh.biHeight<1 || bh.biHeight>10000 ||
        bh.biBitCount    != 24 ||             // пока рассматриваем только полноцветные изображения
        bh.biCompression !=  0                // пока рассматриваем только несжатие изображения
        ) 
   { 
      fclose(f); 
      return NULL; 
   }
   // Заголовок прочитан и проверен, тип - верный (BGR-24), размеры (mx,my) найдены
   mx = bh.biWidth;
   my = bh.biHeight;
   int mx3 = (3*mx+3) & (-4);    // Compute row width in file, including padding to 4-byte boundary
   unsigned char *tmp_buf = new unsigned  char[mx3*my];    // читаем данные
   res = fread( tmp_buf, 1, mx3*my, f);
   if( (int)res != mx3*my ) { delete []tmp_buf; fclose(f); return NULL; }
   // данные прочитаны
   fclose(f); 
 
   // выделим память для результата
   v = new int[mx*my];
 
   // Перенос данных (не забудем про BGR->RGB)
   unsigned char *ptr = (unsigned char *) v;
   for(int y = my-1; y >= 0; y--) {
        unsigned char *pRow = tmp_buf + mx3*y;
        for(int x=0; x< mx; x++) {
            *ptr++ = *(pRow + 2);
            *ptr++ = *(pRow + 1);
            *ptr++ = *pRow; 
            pRow+=3;
            ptr ++;
        }
   }
   delete []tmp_buf;
   return v;    // OK
}
 
int  saveBMP( const char *fname, int *v, int mx, int my ) // В каждом элементе упаковано все три RGB-байта
{
    BMPheader bh;   // Заголовок файла, sizeof(BMPheader) = 56
    memset( &bh, 0, sizeof(bh) );
    bh.bfType =0x4d42;  // 'BM'
    // Найдем длину строки в файле, включая округление вверх до кратного 4:
    int mx3 = (3*mx+3) & (-4);
    int filesize = 54 + my*mx3;
    bh.bfSize = filesize;
    bh.bfReserved =  0;
    bh.biPlanes   =  1;
    bh.biSize     = 40;
    bh.bfOffBits  = 14 + bh.biSize;
    bh.biWidth    = mx;
    bh.biHeight   = my;
    bh.biBitCount = 24;
    bh.biCompression= 0;
 
    FILE *f = fopen( fname, "wb" );
    if( !f ) return -1;
    size_t res;
 
    // пишем заголовок
    res = fwrite( &bh, 1, sizeof(BMPheader), f );
    if( res != sizeof(BMPheader) ) { fclose(f); return -1; }
 
    // приготовим временный буфер
    unsigned char *tmp_buf = new unsigned char[mx3*my];
    // Перенос данных (не забудем про RGB->BGR)
    unsigned char *ptr = (unsigned char *) v;
    for(int y = my-1; y >= 0; y--) {
        unsigned char *pRow = tmp_buf + mx3*y;
        for(int x=0; x< mx; x++) {
            *(pRow + 2) = *ptr++;
            *(pRow + 1) = *ptr++;
            *pRow       = *ptr++; 
            pRow+=3;
            ptr++;
        }
    }
    // сбросим в файл
    fwrite( tmp_buf, 1, mx3*my, f );
    fclose(f);
    delete []tmp_buf;
    return 0;   // OK
}
 
int main()
{
   int mx, my;
   int *v = loadBMP("picture.bmp", mx, my); // выделяем память и читаем туда файл   
   saveBMP("saved.bmp",  v ,   mx, my);
}
UP. Уточним - 24 битных оно работает
1
1 / 1 / 0
Регистрация: 28.04.2013
Сообщений: 65
18.06.2014, 12:10  [ТС]
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
Оно работает, 54 байта пишется, когда не прочитан исходный файл.
ну вот как раз ето я знаю что заголовок пишется, потомучто создается бмп файл с заголовком но без самого изображения
вот я хочу узнать правильно ли я передаю массив пикселей? а то чтото есть неправильно если оно просто "чистит" файл
0
327 / 230 / 55
Регистрация: 30.05.2014
Сообщений: 682
18.06.2014, 12:20
если picture.bmp - 24 битный, этот код работает, хотя я и не очень понимаю, зачем было изобретать свою структуру вместо BITMAPFILEHEADER и BITMAPINFOHEADER.

Для любой другой глубины его надо переделывать, потому что 24 бита забито гвоздями уже вот тут:

C++
1
int mx3 = (3*mx+3) & (-4);
Если он у Вас в приложении не работает, скорее всего читается не 24-х битный битмап.
1
1 / 1 / 0
Регистрация: 28.04.2013
Сообщений: 65
18.06.2014, 12:26  [ТС]
ну я не знаю
только что перепроверил
сохранил в пейнте в 24розр - ситуация не меняется

до и после
Миниатюры
Работа с BMP файлом  
0
327 / 230 / 55
Регистрация: 30.05.2014
Сообщений: 682
18.06.2014, 12:31
Работает в моем тесте. У Вас:


C++
1
2
3
4
5
private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
        int mx, my;                              // для размеров изображения
    int *v = loadBMP("picture.bmp", mx, my); // выделяем память и читаем туда файл
    delete [] v; 
    }
Растр грузится и тут же удаляется.

C++
1
2
3
4
5
6
7
8
9
10
11
private: System::Void button2_Click(System::Object^  sender, System::EventArgs^  e) {
                
                int* v=new int;
             char t1[] ="picture.bmp";
     int  mx=Matrix_mx(t1);
    int   my=Matrix_my(t1);
            
           // для размеров изображения
           if   (saveBMP(t1,  v ,   mx, my)   ==0)    MessageBox::Show("Saved ok") ; else MessageBox::Show("ERROR");
             delete  v; 
         }
Создается один int и делается попытка его сохранить.
1
1 / 1 / 0
Регистрация: 28.04.2013
Сообщений: 65
18.06.2014, 12:33  [ТС]
ну вот я насчет етого и хотел посоветоваться))))
что там изменить?
0
327 / 230 / 55
Регистрация: 30.05.2014
Сообщений: 682
18.06.2014, 12:40
Цитата Сообщение от voldkost Посмотреть сообщение
что там изменить?
Ну я откуда знаю? . Мне отсюда не видно, что должно в итоге делать приложение и что такое Matrix_mx.

Как минимум -

C++
1
2
int mx, my; 
int *v
Нужно перенести в класс формы, если они нужны в двух методах.
0
1 / 1 / 0
Регистрация: 28.04.2013
Сообщений: 65
18.06.2014, 13:00  [ТС]
C++
1
2
3
4
5
6
7
8
9
10
11
int Matrix_mx(const char *fname)
 
{int mx=1;
    return mx;
}
 
int Matrix_my(const char *fname)
{
    int my=1;
    return my;
}

что должно в итоге делать приложение
ну работать с массивами бит...))
например найти в массиве определенный цвет по его "коду" и заменить на значения из другого массива)) ну ето так примерно

Добавлено через 14 минут
C++
1
2
3
4
5
6
7
8
9
10
11
private: System::Void button2_Click(System::Object^  sender, System::EventArgs^  e) {
        
        //      int* v=new int;
             char t1[] ="picture.bmp";
    // int  mx=Matrix_mx(t1);
//  int   my=Matrix_my(t1);
            
           // для размеров изображения
           if   (saveBMP(t1,  v ,   mx, my)   ==0)    MessageBox::Show("Saved ok") ; else MessageBox::Show("ERROR");
            
         }
изменил как вы посоветовали объявив
C++
1
2
3
    public ref class Form1 : public System::Windows::Forms::Form
    {int mx, my; 
            int *v;
ошибка 1>LINK : fatal error LNK1123: сбой при преобразовании в COFF: файл недопустим или поврежден
0
327 / 230 / 55
Регистрация: 30.05.2014
Сообщений: 682
18.06.2014, 13:07
Цитата Сообщение от voldkost Посмотреть сообщение
LINK : fatal error LNK1123: сбой при преобразовании в COFF: файл недопустим или поврежден
Никак не может быть связано, это сообщение линкера.
0
1 / 1 / 0
Регистрация: 28.04.2013
Сообщений: 65
18.06.2014, 14:24  [ТС]
ах да и другие программы не работают с етой ошибкой)))

Добавлено через 8 минут
блин а как избавится от етой ошибки

Добавлено через 8 минут
а все теперь нормально)

Добавлено через 7 минут
54 байта пишется, когда не прочитан исходный файл.
у меня пишется 56 байт))
но все равно результата нужного нету (не создается копия исходного изображения)
0
327 / 230 / 55
Регистрация: 30.05.2014
Сообщений: 682
18.06.2014, 15:33
Цитата Сообщение от voldkost Посмотреть сообщение
у меня пишется 56 байт))
Пишется 56 скорее всего из-за того, что структура не выравнивается на байт.

Цитата Сообщение от voldkost Посмотреть сообщение
не создается копия исходного изображения
Вот этот кусок сейчас так выглядит?

C++
1
2
private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
    v = loadBMP("picture.bmp", mx, my); // выделяем память и читаем туда файл
Файл picture.bmp существует? Укажите имя файла с полным путем.
1
1 / 1 / 0
Регистрация: 28.04.2013
Сообщений: 65
18.06.2014, 15:42  [ТС]
Файл picture.bmp существует
я навставлял етих picture во все папки
кусок
C++
1
2
3
4
5
6
7
8
private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
        int mx, my;                              // для размеров изображения
    v = loadBMP("picture.bmp", mx, my); // выделяем память и читаем туда файл
    MessageBox::Show("Load ok");
  pictureBox1->Load("picture.bmp");
   
 
             }
0
327 / 230 / 55
Регистрация: 30.05.2014
Сообщений: 682
18.06.2014, 15:46
C++
1
int mx, my;
Уберите.
0
1 / 1 / 0
Регистрация: 28.04.2013
Сообщений: 65
18.06.2014, 15:48  [ТС]
просит объявлять))
C++
1
error C2664: My1::Form1::loadBMP: невозможно преобразовать параметр 2 из "int" в "int &"
0
327 / 230 / 55
Регистрация: 30.05.2014
Сообщений: 682
18.06.2014, 17:17
Кликните здесь для просмотра всего текста
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
#pragma once
 
#include <stdio.h>
#include <memory.h>
 
#pragma pack(push,1) 
typedef struct {
   unsigned __int16   bfType;         // 0x4d42 | 0x4349 | 0x5450
   int                bfSize;         // размер файла
   int                bfReserved;     // 0
   int                bfOffBits;      // смещение до поля данных,
   // обычно 54 = 16 + biSize
   int                biSize;         // размер струкуры в байтах:
   // 40(BITMAPINFOHEADER) или 108(BITMAPV4HEADER)
   // или 124(BITMAPV5HEADER)
   int                biWidth;        // ширина в точках
   int                biHeight;       // высота в точках
   unsigned __int16   biPlanes;       // всегда должно быть 1
   unsigned __int16   biBitCount;     // 0 | 1 | 4 | 8 | 16 | 24 | 32
   int                biCompression;  // BI_RGB | BI_RLE8 | BI_RLE4 |
   // BI_BITFIELDS | BI_JPEG | BI_PNG
   // реально используется лишь BI_RGB
   int                biSizeImage;    // Количество байт в поле данных
   // Обычно устанавливается в 0
   int                biXPelsPerMeter;// горизонтальное разрешение, точек на дюйм
   int                biYPelsPerMeter;// вертикальное разрешение, точек на дюйм
   int                biClrUsed;      // Количество используемых цветов
   // (если есть таблица цветов)
   int                biClrImportant; // Количество существенных цветов.
   // Можно считать, просто 0
} BMPheader; 
#pragma pack(pop) 
 
namespace test {
 
   using namespace System;
   using namespace System::ComponentModel;
   using namespace System::Collections;
   using namespace System::Windows::Forms;
   using namespace System::Data;
   using namespace System::Drawing;
 
   /// <summary>
   /// Summary for Form1
   /// </summary>
   public ref class Form1 : public System::Windows::Forms::Form
   {
   public:
      Form1(void)
      {
         v=0;
         mx=0;
         my=0;
         InitializeComponent();
         //
         //TODO: Add the constructor code here
         //
      }
 
   public: int *loadBMP(const char *fname)
           { 
              if(v)
              {
                 delete []v;
                 v = 0;
              }
              mx = my = 0;
 
              FILE *f = fopen( fname, "rb" );
              if( !f ) return NULL;
              BMPheader bh;    // File header sizeof(BMPheader) = 56
              size_t res;
 
              // читаем заголовок
              res = fread( &bh, 1, sizeof(BMPheader), f );
              if( res != sizeof(BMPheader) ) { fclose(f); return NULL; }
 
              // проверяем сигнатуру
              if( bh.bfType!=0x4d42 && bh.bfType!=0x4349 && bh.bfType!=0x5450 ) { fclose(f); return NULL; }
 
              // проверка размера файла
              fseek( f, 0, SEEK_END);
              int filesize = ftell(f);
              // восстановим указатель в файле:
              fseek( f, sizeof(BMPheader), SEEK_SET);
              // проверим условия
              if( bh.bfSize != filesize ||
                 bh.bfReserved != 0    ||
                 bh.biPlanes   != 1    ||
                 (bh.biSize!=40 && bh.biSize!=108 && bh.biSize!=124)||
                 bh.bfOffBits != 14+bh.biSize ||
 
                 bh.biWidth <1 || bh.biWidth >10000 ||
                 bh.biHeight<1 || bh.biHeight>10000 ||
                 bh.biBitCount    != 24 ||             // пока рассматриваем только полноцветные изображения
                 bh.biCompression !=  0                // пока рассматриваем только несжатие изображения
                 ) 
              { 
                 fclose(f); 
                 return NULL; 
              }
              // Заголовок прочитан и проверен, тип - верный (BGR-24), размеры (mx,my) найдены
              mx = bh.biWidth;
              my = bh.biHeight;
              int mx3 = (3*mx+3) & (-4);    // Compute row width in file, including padding to 4-byte boundary
              unsigned char *tmp_buf = new unsigned  char[mx3*my];    // читаем данные
              res = fread( tmp_buf, 1, mx3*my, f);
              if( (int)res != mx3*my ) { delete []tmp_buf; fclose(f); return NULL; }
              // данные прочитаны
              fclose(f); 
 
              // выделим память для результата
              v = new int[mx*my];
 
              // Перенос данных (не забудем про BGR->RGB)
              unsigned char *ptr = (unsigned char *) v;
              for(int y = my-1; y >= 0; y--) {
                 unsigned char *pRow = tmp_buf + mx3*y;
                 for(int x=0; x< mx; x++) {
                    *ptr++ = *(pRow + 2);
                    *ptr++ = *(pRow + 1);
                    *ptr++ = *pRow; 
                    pRow+=3;
                    ptr ++;
                 }
              }
              delete []tmp_buf;
              return v;    // OK
           }
   public: int saveBMP( const char *fname) // В каждом элементе упаковано все три RGB-байта
           {
              BMPheader bh;   // Заголовок файла, sizeof(BMPheader) = 56
              memset( &bh, 0, sizeof(bh) );
              bh.bfType =0x4d42;  // 'BM'
              // Найдем длину строки в файле, включая округление вверх до кратного 4:
              int mx3 = (3*mx+3) & (-4);
              int filesize = 54 + my*mx3;
              bh.bfSize = filesize;
              bh.bfReserved =  0;
              bh.biPlanes   =  1;
              bh.biSize     = 40;
              bh.bfOffBits  = 14 + bh.biSize;
              bh.biWidth    = mx;
              bh.biHeight   = my;
              bh.biBitCount = 24;
              bh.biCompression= 0;
 
              FILE *f = fopen( fname, "wb" );
              if( !f ) return -1;
              size_t res;
 
              // пишем заголовок
              res = fwrite( &bh, 1, sizeof(BMPheader), f );
              if( res != sizeof(BMPheader) ) { fclose(f); return -1; }
 
              // приготовим временный буфер
              unsigned char *tmp_buf = new unsigned char[mx3*my];
              // Перенос данных (не забудем про RGB->BGR)
              unsigned char *ptr = (unsigned char *) v;
              for(int y = my-1; y >= 0; y--) {
                 unsigned char *pRow = tmp_buf + mx3*y;
                 for(int x=0; x< mx; x++) {
                    *(pRow + 2) = *ptr++;
                    *(pRow + 1) = *ptr++;
                    *pRow       = *ptr++; 
                    pRow+=3;
                    ptr++;
                 }
              }
              // сбросим в файл
              fwrite( tmp_buf, 1, mx3*my, f );
              fclose(f);
              delete []tmp_buf;
              return 0;   // OK
           }
   protected:
      /// <summary>
      /// Clean up any resources being used.
      /// </summary>
      ~Form1()
      {
         if (components)
         {
            delete components;
         }
      }
   private: System::Windows::Forms::Button^  button1;
   protected: 
   private: System::Windows::Forms::Button^  button2;
 
   private:
      int* v;
      int mx;
      int my;
      /// <summary>
      /// Required designer variable.
      /// </summary>
      System::ComponentModel::Container ^components;
 
#pragma region Windows Form Designer generated code
      /// <summary>
      /// Required method for Designer support - do not modify
      /// the contents of this method with the code editor.
      /// </summary>
      void InitializeComponent(void)
      {
         this->button1 = (gcnew System::Windows::Forms::Button());
         this->button2 = (gcnew System::Windows::Forms::Button());
         this->SuspendLayout();
         // 
         // button1
         // 
         this->button1->Location = System::Drawing::Point(615, 476);
         this->button1->Name = L"button1";
         this->button1->Size = System::Drawing::Size(75, 23);
         this->button1->TabIndex = 0;
         this->button1->Text = L"button1";
         this->button1->UseVisualStyleBackColor = true;
         this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
         // 
         // button2
         // 
         this->button2->Location = System::Drawing::Point(696, 476);
         this->button2->Name = L"button2";
         this->button2->Size = System::Drawing::Size(75, 23);
         this->button2->TabIndex = 1;
         this->button2->Text = L"button2";
         this->button2->UseVisualStyleBackColor = true;
         this->button2->Click += gcnew System::EventHandler(this, &Form1::button2_Click);
         // 
         // Form1
         // 
         this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
         this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
         this->ClientSize = System::Drawing::Size(838, 511);
         this->Controls->Add(this->button2);
         this->Controls->Add(this->button1);
         this->Name = L"Form1";
         this->Text = L"Form1";
         this->ResumeLayout(false);
 
      }
#pragma endregion
   private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) 
            {
               loadBMP( "picture.bmp" );
            }
   private: System::Void button2_Click(System::Object^  sender, System::EventArgs^  e) {
               saveBMP( "picture_copy.bmp" );
            }
};
}


Я очень надеюсь, что Вы знаете что делать дальше .
1
1 / 1 / 0
Регистрация: 28.04.2013
Сообщений: 65
18.06.2014, 17:46  [ТС]
нет ну конечно спасибо за проделанное)) но результат тотже))
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
18.06.2014, 17:46
Помогаю со студенческими работами здесь

Работа с нетипизированным BMP файлом
Здравствуйте, хотел бы попросить помощи по заданию, так как не понимаю как сделать его через нетипизированный без использования GraphABC. ...

Работа с bmp файлом не получается найти ошибку
Добрый день, знаю что существуют разные способы считывания bmp файла, мне нужно считать таким образом что бы заголовок лежал в одном...

Работа с bmp файлом. Считывание значение пикселей в массив
Здравствуйте. Необходимо написать код который считывает из bmp картинки значение пикселей RGB в массив. Спасибо за внимание!

Работа с BMP-файлами (класс "8 битное BMP изображение)
Написать класс &quot;8 битное BMP изображение&quot;.Класс должен содержать 3 конструктора: конструктор по умолчанию, конструктор с параметрами и...

Приложение, которое работает с bmp Файлом
Пожалуйста помогите!!! Нужно написать программу, которая читает с диска *.bmp файл и выводит его в окно приложения. При помощи потока...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru