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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 75, средняя оценка - 4.64
Ortistx
1 / 1 / 0
Регистрация: 19.02.2011
Сообщений: 39
#1

Открытие и запись bmp-файла - C++

19.02.2011, 22:32. Просмотров 11255. Ответов 8
Метки нет (Все метки)

Здравствуйте уважаемые участники форума.

Прошу помощи, т.к. не могу найти ошибку в программе. Задача - прочитать побайтно файл bmp и записать его в другой bmp файл. Использую следующий код:

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
int main()
{   
 
     // Объявляем структуры
     BITMAPFILEHEADER bfh_l;
     BITMAPINFOHEADER bih_l;
     RGBTRIPLE rgb_l;
    
    FILE * f1, * f2;
 
    f1 = fopen("1.bmp", "r+b");
    f2 = fopen("2.bmp", "w+b");
 
 
    fread(&bfh_l,sizeof(bfh_l),1,f1);       //Запихиваем файловый заголовок в структуру BITMAPFILEHEADER
    fwrite(&bfh_l, sizeof(bfh_l), 1, f2);   //
    fread(&bih_l,sizeof(bih_l),1,f1);       //Запихиваем заголовок изображения в структуру BITMAPINFOHEADER
    fwrite(&bih_l, sizeof(bih_l), 1, f2);   //
 
    for(int i=0;i< bih_l.biHeight;i++)
    {
        for (int j = 0; j < bih_l.biWidth; j++)
        {
 
            fread(&rgb_l, sizeof(rgb_l),1, f1);
            fwrite(&rgb_l, sizeof(rgb_l), 1, f2);
        }
        
    }
        
    fcloseall();
    getch();
   return 0;
}
Исходная картинка: 1.bmp
То, что получилось: 2.bmp
(на качество не обращайте внимание - пересохранял в jpeg чтобы выложить на форум. Главное отличие, что во 2ой картинке присутствует горизонтальная черная полоса сверху)

В целом файл копируется, но сверху почему-то полоса получается черная.
Прошу указать ошибку. Заранее спасибо.
0
Изображения
  
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.02.2011, 22:32
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Открытие и запись bmp-файла (C++):

Открытие и запись файла bmp. Что здесь не так ? - C++
Имеется программа, копирующая содержимое из указанного bmp в файл result. Проблема: файл stars копируется нормально, а вместо...

Создание/открытие файлов, чтение из файла и запись в файл через наследование - C++
Имеется следующая иерархия классов: Файл, Типизированный файл, Текстовый файл Методы: Создать/Открыть файл, Чение из файла, Запись в...

Открытие .bmp - C++
Как открыть .bmp в VS 2012?

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

Запись bitset в bmp - C++
Всем доброго времени суток, такая проблемка, не могу записать bitset в bmp вроде нашел пример и структуру файла, но рук не хватает ещё)). ...

Считывание и запись .bmp файлов - C++
Здравствуйте. Помогите, пожалуйста, разобраться почему не работает сохранение bmp файла. Открываю 1 файл, загружаю его и все данные...

8
ping_rulezzz
26 / 26 / 4
Регистрация: 18.02.2011
Сообщений: 51
19.02.2011, 23:50 #2
Добавлено через 25 минут
совсем забыл про выравнивающие биты - было всё норм, т.к. случайно угадал с размерами изображения) да и вы походу тоже забыли)

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
// find_error.cpp : Defines the entry point for the console application.
//
 
#include "stdafx.h"
#include<iostream>
#include "Windows.h";
 
int main()
{       
 
     // Объявляем структуры
     BITMAPFILEHEADER bfh_l;
     BITMAPINFOHEADER bih_l;
         RGBTRIPLE rgb_l;
        
        FILE * f1, * f2;
        
        f1 = fopen("1.bmp", "r+b");
        f2 = fopen("3.bmp", "w+b");
 
 
        fread(&bfh_l,sizeof(bfh_l),1,f1);               //Запихиваем файловый заголовок в структуру BITMAPFILEHEADER
        fwrite(&bfh_l, sizeof(bfh_l), 1, f2);   //
        fread(&bih_l,sizeof(bih_l),1,f1);               //Запихиваем заголовок изображения в структуру BITMAPINFOHEADER
        fwrite(&bih_l, sizeof(bih_l), 1, f2);   //
 
    size_t padding = 0;
    if ((bih_l.biWidth * 3) % 4) padding = 4 - (bih_l.biWidth * 3) % 4;
 
        for(int i=0;i< bih_l.biHeight;i++)
        {
                for (int j = 0; j < bih_l.biWidth; j++)
        {
 
                        fread(&rgb_l, sizeof(rgb_l),1, f1);
                        fwrite(&rgb_l, sizeof(rgb_l), 1, f2);
 
                        
                }
            for (size_t t = 0; t < padding; ++t) {
                fread(&rgb_l, sizeof(rgb_l),1, f1);
                fwrite(&rgb_l, sizeof(rgb_l), 1, f2);
            }
                
        }
                
        fcloseall();
    
   return 0;
}
Добавлено через 14 минут
поправочка - заменить это
C++
1
2
3
4
for (size_t t = 0; t < padding; ++t) {
          fread(&rgb_l, sizeof(rgb_l),1, f1);
           fwrite(&rgb_l, sizeof(rgb_l), 1, f2);
}
на это
C++
1
2
3
4
if(padding != 0) {
    fread(&rgb_l, padding,1, f1);
    fwrite(&rgb_l, padding, 1, f2);
}
0
Ortistx
1 / 1 / 0
Регистрация: 19.02.2011
Сообщений: 39
19.02.2011, 23:59  [ТС] #3
Спасибо, но немного не понял:
1) Кто такие выравнивающие биты, откуда берутся?
2) Что такое тип size_t?
3) Что Вы здесь проверяете?:
C++
1
 if ((bih_l.biWidth * 3) % 4) padding = 4 - (bih_l.biWidth * 3) % 4;
0
ping_rulezzz
26 / 26 / 4
Регистрация: 18.02.2011
Сообщений: 51
20.02.2011, 10:38 #4
1) Кто такие выравнивающие биты, откуда берутся?
я немного неправильно сказал, не биты, байты. Почитать можно тут http://en.wikipedia.org/wiki/BMP_file_format
Каждая строка должна быть кратна 4 байтам, т.е. у нас 24битный bmp с длиной 5 пикселя, тогда 5 * 3(кол-во байт цвета - RGB) = 15. соотвественно, нам нужен ещё 1 пустой байт, чтобы выровнять до 16. Этот код как раз и высчитывает количество пустых байтов
C++
1
if ((bih_l.biWidth * 3) % 4) padding = 4 - (bih_l.biWidth * 3) % 4;
size_t
Если не углубляться, то это просто без знаковый тип.
0
Ortistx
1 / 1 / 0
Регистрация: 19.02.2011
Сообщений: 39
20.02.2011, 14:52  [ТС] #5
Почему длина 5 пикселя?
Насколько я понимаю, 1 пиксель занимает 3 байта. Соответственно выравнивание зависит от ширины картинки в пикселях. Т.е. если ширина*3 кратна 4, то выравнивания не нужно. Если не кратна, то добавляем столько байт, сколько не хватает для кратности 4м. Я прав?
0
ping_rulezzz
26 / 26 / 4
Регистрация: 18.02.2011
Сообщений: 51
20.02.2011, 14:57 #6
абсолютно правы. Имелась ввиду ширина (5 было взято для примера)
0
Ortistx
1 / 1 / 0
Регистрация: 19.02.2011
Сообщений: 39
22.02.2011, 00:42  [ТС] #7
Спасибо за помощь, разобрался, все получилось
0
Авега
Сообщений: n/a
25.10.2013, 18:53 #8
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
/*ПОМОГИТЕ ПОАЛУЙСТА!!!
         открыли файл. записали в матрицу (трёхмерный массив) RGB. закрыли файл. открыли другой. записываем в           другой из матрицы. если выравнивать не требуется - все хорошо. если требуется - то танцы с бубном. как с этим бороться? заранее спасибо.      
*/
 
 
 
 
 
 #include<iostream>
#include "Windows.h";
using namespace std;
void image_in_txt(void);
int main()
{       
 
     
     BITMAPFILEHEADER BMP_FILE_HEADER;
     BITMAPINFOHEADER BMP_IMAGE_HEADER;
     RGBTRIPLE RGB;
        char***BMP_MATRIX_MAP=NULL;
        FILE * f1, * f2,* f3;
     /////////////////////////////////////////////   
        f1 = fopen("1.bmp", "r+b");
        f2 = fopen("2.bmp", "w+b");
        f3 = fopen("2.bmp", "w+b");
 
        fread(&BMP_FILE_HEADER,sizeof(BMP_FILE_HEADER),1,f1);               //Г‡Г*ïèõèâГ*ГҐГ¬ ГґГ*éëîâûé Г§Г*ãîëîâîê Гў ñòðóêòóðó BITMAPFILEHEADER
        fwrite(&BMP_FILE_HEADER, sizeof(BMP_FILE_HEADER), 1, f2);   //
        fread(&BMP_IMAGE_HEADER,sizeof(BMP_IMAGE_HEADER),1,f1);               //Г‡Г*ïèõèâГ*ГҐГ¬ Г§Г*ãîëîâîê èçîáðГ*æåГ*ГЁГї Гў ñòðóêòóðó BITMAPINFOHEADER
        fwrite(&BMP_IMAGE_HEADER, sizeof(BMP_IMAGE_HEADER), 1, f2);   //
         ///////////////////////////////////////////////////////////////
        BMP_MATRIX_MAP=new char**[BMP_IMAGE_HEADER.biHeight];
        for(int i=0;i<BMP_IMAGE_HEADER.biHeight;i++)
        {
            BMP_MATRIX_MAP[i]=new char*[BMP_IMAGE_HEADER.biWidth];
            for(int j=0;j<BMP_IMAGE_HEADER.biWidth;j++)
            {
                BMP_MATRIX_MAP[i][j]=new char[3];
            }
        }
    ///////////////////////////////////////////////////////////////
    size_t padding = 0;
    if ((BMP_IMAGE_HEADER.biWidth * 3) % 4) padding = 4 - (BMP_IMAGE_HEADER.biWidth * 3) % 4;
 
        for(int i=0;i< BMP_IMAGE_HEADER.biHeight;i++)
        {
                for (int j = 0; j < BMP_IMAGE_HEADER.biWidth; j++)
                {
 
                        fread(&RGB, sizeof(RGB),1, f1);
                        
                        
                        printf("blue  : %d\n",RGB.rgbtBlue);
                        printf("Green : %d\n",RGB.rgbtGreen);
                        printf("Red   : %d\n",RGB.rgbtRed);
                        printf("\n");
                        
                        BMP_MATRIX_MAP[i][j][0]   = RGB.rgbtBlue;
                        BMP_MATRIX_MAP[i][j][1] = RGB.rgbtGreen;
                        BMP_MATRIX_MAP[i][j][2] = RGB.rgbtRed;
                        
                        fwrite(&RGB, sizeof(RGB), 1, f2);
 
                        
                }
                printf("\n");
                if(padding != 0) 
                {
                    fread(&RGB, padding,1, f1);
                                printf("        blue  : %d\n",RGB.rgbtBlue);
                                printf("        Green : %d\n",RGB.rgbtGreen);
                                printf("        Red   : %d\n",RGB.rgbtRed);
                                printf("\n");
                    fwrite(&RGB, padding, 1, f2);
                }
                
        }
                
        fclose(f1);
        fclose(f2);
        
    /////////////////////////////////////////////////   
        for(int i=0;i< BMP_IMAGE_HEADER.biHeight;i++)
        {
                for (int j = 0; j < BMP_IMAGE_HEADER.biWidth; j++)
                {
     
                           
                        RGB.rgbtBlue   =    BMP_MATRIX_MAP[i][j][0] ;
                         RGB.rgbtGreen  =   BMP_MATRIX_MAP[i][j][1] ;
                         RGB.rgbtRed    =   BMP_MATRIX_MAP[i][j][2] ;
                                                
                            printf("Matrix_map: [%d] [%d] = { ",i,j);
                            printf("<<Blue  : %d>> ",RGB.rgbtBlue);
                            printf("<<green : %d>> ",RGB.rgbtGreen);
                            printf("<<red   : %d>> }\n ",RGB.rgbtRed);
                            cout<<"================="<<endl;
                }
                cout<<"================="<<endl;
        }
        ///////////////////////////////////////////////////////////////
        
        
        fwrite(&BMP_FILE_HEADER, sizeof(BMP_FILE_HEADER), 1, f3);   
        fwrite(&BMP_IMAGE_HEADER, sizeof(BMP_IMAGE_HEADER), 1, f3);
        
        padding = 0;
        char c =0;
    if ((BMP_IMAGE_HEADER.biWidth * 3) % 4) padding = 4 - (BMP_IMAGE_HEADER.biWidth * 3) % 4;
 
        for(int i=0;i< BMP_IMAGE_HEADER.biHeight;i++)
        {
                for (int j = 0; j < BMP_IMAGE_HEADER.biWidth; j++)
                {
 
                       /// fread(&RGB, sizeof(RGB),1, f1);
                        
                        
                        /*printf("blue  : %d\n",RGB.rgbtBlue);
                        printf("Green : %d\n",RGB.rgbtGreen);
                        printf("Red   : %d\n",RGB.rgbtRed);
                        printf("\n");*/
                        
                        RGB.rgbtBlue = BMP_MATRIX_MAP[i][j][0];
                         RGB.rgbtGreen =BMP_MATRIX_MAP[i][j][1];
                         RGB.rgbtRed =BMP_MATRIX_MAP[i][j][2];
                        
                        fwrite(&RGB, sizeof(RGB), 1, f2);
 
                        
                }
                printf("\n");
                if(padding != 0) 
                {
                    c=255;
                    fwrite(&c, sizeof(char), 1, f2);
                    
                }
                
        }
                
        fclose(f3);
        
        image_in_txt();
        
   return 0;
}
Добавлено через 14 минут
вопрос снят разобрался спасибо =)
ninja2
231 / 187 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
28.08.2015, 13:30 #9
А как записать в файл CBitmap???
есть переменная CBitmap
C++
1
CBitmap* m_pBitmap=(CBitmap*)hGlob;
и ее нужно сохранить в файл???
0
28.08.2015, 13:30
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.08.2015, 13:30
Привет! Вот еще темы с ответами:

Создание bmp файла - C++
Как создать новый bmp файл 8 бит, например 50*50 пикселей?

Загрузка bmp файла - C++
установил RAD 2010, auxDIBImageLoad перестал работать(символ не найден пишет мне студия). можете пожалуйста скинуть замену этой функции,...

Чтение BMP файла - C++
Пишу программу в которой необходимо считать заголовок BMP файла. Файл безпалитровый, глубина цвета 24, то есть по 8 бит каждой составляющей...

Показывать bmp из файла - C++
Пытаюсь заставить показать в окне картинку bmp из указанного файла. Есть полностью работоспособная программа, которая из ресурсов...


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru