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

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

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 75, средняя оценка - 4.64
Ortistx
1 / 1 / 0
Регистрация: 19.02.2011
Сообщений: 39
19.02.2011, 22:32     Открытие и запись bmp-файла #1
Здравствуйте уважаемые участники форума.

Прошу помощи, т.к. не могу найти ошибку в программе. Задача - прочитать побайтно файл 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ой картинке присутствует горизонтальная черная полоса сверху)

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

Показывать bmp из файла C++
Запись в файл BMP C++
C++ Создание bmp файла
C++ загрузка bmp файла
C++ Открытие .bmp
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ping_rulezzz
26 / 26 / 4
Регистрация: 18.02.2011
Сообщений: 51
19.02.2011, 23:50     Открытие и запись bmp-файла #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);
}
Ortistx
1 / 1 / 0
Регистрация: 19.02.2011
Сообщений: 39
19.02.2011, 23:59  [ТС]     Открытие и запись bmp-файла #3
Спасибо, но немного не понял:
1) Кто такие выравнивающие биты, откуда берутся?
2) Что такое тип size_t?
3) Что Вы здесь проверяете?:
C++
1
 if ((bih_l.biWidth * 3) % 4) padding = 4 - (bih_l.biWidth * 3) % 4;
ping_rulezzz
26 / 26 / 4
Регистрация: 18.02.2011
Сообщений: 51
20.02.2011, 10:38     Открытие и запись bmp-файла #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
Если не углубляться, то это просто без знаковый тип.
Ortistx
1 / 1 / 0
Регистрация: 19.02.2011
Сообщений: 39
20.02.2011, 14:52  [ТС]     Открытие и запись bmp-файла #5
Почему длина 5 пикселя?
Насколько я понимаю, 1 пиксель занимает 3 байта. Соответственно выравнивание зависит от ширины картинки в пикселях. Т.е. если ширина*3 кратна 4, то выравнивания не нужно. Если не кратна, то добавляем столько байт, сколько не хватает для кратности 4м. Я прав?
ping_rulezzz
26 / 26 / 4
Регистрация: 18.02.2011
Сообщений: 51
20.02.2011, 14:57     Открытие и запись bmp-файла #6
абсолютно правы. Имелась ввиду ширина (5 было взято для примера)
Ortistx
1 / 1 / 0
Регистрация: 19.02.2011
Сообщений: 39
22.02.2011, 00:42  [ТС]     Открытие и запись bmp-файла #7
Спасибо за помощь, разобрался, все получилось
Авега
Сообщений: n/a
25.10.2013, 18:53     Открытие и запись bmp-файла #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 минут
вопрос снят разобрался спасибо =)
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.08.2015, 13:30     Открытие и запись bmp-файла
Еще ссылки по теме:

C++ Открытие и запись файла bmp. Что здесь не так ?
Считывание и запись .bmp файлов C++
Запись bitset в bmp C++

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

Или воспользуйтесь поиском по форуму:
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
28.08.2015, 13:30     Открытие и запись bmp-файла #9
А как записать в файл CBitmap???
есть переменная CBitmap
C++
1
CBitmap* m_pBitmap=(CBitmap*)hGlob;
и ее нужно сохранить в файл???
Yandex
Объявления
28.08.2015, 13:30     Открытие и запись bmp-файла
Ответ Создать тему
Опции темы

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