Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.73/15: Рейтинг темы: голосов - 15, средняя оценка - 4.73
10 / 10 / 1
Регистрация: 09.04.2010
Сообщений: 141
1

[C++] 24-битные BMP

17.01.2012, 23:21. Показов 2979. Ответов 30
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Программа не хочет кодировать 24-битные BMP. Под кодированием я понимаю разбитие изображение на квадраты по 10 пикселей (в программе - по 10 байтов, но это не особо существенно потому, что само изображение выходное открываться не хочет), при котором сначала квадраты перемешиваются по вертикали, а потом и по горизонтали. Пример,
1 6 11 16
2 7 12 17
3 8 13 18 =>
4 9 14 19
5 10 15 20

5 6 15 16
4 7 14 17
3 8 13 18 =>
2 9 12 19
1 10 11 20

16 15 6 5
4 7 14 17
18 13 8 3
19 12 9 2
20 11 10 1

P.S. 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
#include <iostream> 
#include <fstream> 
#include <cstdio>
#include <windows.h>
#include <cstring>
 
using namespace std; 
 
int main(int argc, char *argv[]) 
{ 
    setlocale(LC_ALL, "Russian");
    
    if(argc!=2) { //Если более двух аргументов командной строки
        cout << "Используй: next <имя-файла>, будь мужиком!\n"; 
    } 
 
    fstream in(argv[1], ios::in | ios::out | ios::binary); 
    if(!in) { 
        cout << "Невозможно открыть файл.\n";
    } 
  
    BITMAPFILEHEADER bmpFileHeader; //Создание bmpFileHeader
    BITMAPINFOHEADER bmpInfoHeader; //Создание bmpInfoHeader
    
    in.read( (char*)&bmpFileHeader, sizeof( bmpFileHeader ) ); //Считывание данных 
    in.read( (char*)&bmpInfoHeader, sizeof( bmpInfoHeader ) ); //в структуры
    
    const int Height = bmpInfoHeader.biHeight, //Создание констант
              Width = bmpInfoHeader.biWidth,
              BpP = bmpInfoHeader.biBitCount,
              ImageSize = bmpFileHeader.bfSize;
    
    const int RowSize = BpP / 8 * Width ;
    int padding; //Паддинг - ненужное пространсво в массиве пикселей
    
    if (BpP == 8)
        padding = (3 * Width) % 4;
    else if (BpP == 16)
        padding = (2 * Width) % 4;
    else if (BpP == 24)
        padding = Width % 4;
        
    char pixels_orig[Height][RowSize]; //Массив пикселей
    
    in.seekg(bmpFileHeader.bfOffBits, ios::beg); //Перескакиваем в начало массива пикселей
    
    for (int i = 0; i < Height; i++) {
        in.read(pixels_orig[i], (RowSize * (BpP / 8))); //Заполнение одного рядка
        in.seekg(padding, ios::cur); //Проскакиваем паддинг
    }
    
    cout << "Данные " << argv[1] << ":\n"
                 << "\tРазмер файла: " << ImageSize << " байтов = " << (double)ImageSize / 1024 << " килобайтов;\n"
                 << "\tШирина изображения: " << Width << " пикселей;\n"
                 << "\tВысота изображения: " << Height << " пикселей;\n"
                 << "\tБитность: " << BpP << " битов на пиксель.\n";
 
    char temp;
    
    char pixels_crypted[Height][RowSize];
    
    const int code = 10;
    
    for (int i = 0; i < RowSize; i++)
        for (int j = 0; j < Height; j++)
            pixels_crypted[j][i] = pixels_orig[j][i];
    
    //////////////////////  
    //////////////////////      
    ////Новый алгоритм////
    //////////////////////
    //////////////////////
    
    char pattern_1[10][10],
         pattern_2[10][10];
    
    for (int i = 0; i < (Height - Height % 10) / 2 ; i += 10)
        for (int j = 0; j < RowSize - RowSize % 10; j += 20) {
            for (int i_mod_1 = 0; i_mod_1 < 10; i_mod_1++)
                for (int j_mod_1 = 0; j_mod_1 < 10; j_mod_1++) {
                    pattern_1[i_mod_1][j_mod_1] = pixels_crypted[i + i_mod_1][j + j_mod_1];
                    pattern_2[i_mod_1][j_mod_1] = pixels_crypted[Height - Height % 10 - 10 - i + i_mod_1][j + j_mod_1];
                }
                
            for (int i_mod_2 = 0; i_mod_2 < 10; i_mod_2++)  
                for (int j_mod_2 = 0; j_mod_2 < 10; j_mod_2++) {
                    pixels_crypted[i + i_mod_2][j + j_mod_2] = pattern_2[i_mod_2][j_mod_2];
                    pixels_crypted[Height - Height % 10 - 10 - i + i_mod_2][j + j_mod_2] = pattern_1[i_mod_2][j_mod_2];
                }
        }   
    
    for (int i = 0; i < Height - Height % 10 ; i += 20)
        for (int j = 0; j < (RowSize - RowSize % 10) / 2; j += 10) {
            for (int i_mod_1 = 0; i_mod_1 < 10; i_mod_1++)
                for (int j_mod_1 = 0; j_mod_1 < 10; j_mod_1++) {
                    pattern_1[i_mod_1][j_mod_1] = pixels_crypted[i + i_mod_1][j + j_mod_1];
                    pattern_2[i_mod_1][j_mod_1] = pixels_crypted[i + i_mod_1][RowSize - RowSize % 10 - 10 - j + j_mod_1];
                }
                
            for (int i_mod_2 = 0; i_mod_2 < 10; i_mod_2++)  
                for (int j_mod_2 = 0; j_mod_2 < 10; j_mod_2++) {
                    pixels_crypted[i + i_mod_2][j + j_mod_2] = pattern_2[i_mod_2][j_mod_2];
                    pixels_crypted[i + i_mod_2][RowSize - RowSize % 10 - 10 - j + j_mod_2] = pattern_1[i_mod_2][j_mod_2];
                }
        }   
        
    //Создаем файл out.bmp
    fstream out_create("out.bmp", ios::out); 
    out_create.close();
    fstream out("out.bmp", ios::in | ios::out | ios::binary); 
    
    //Начинается запись в файл out.bmp
     
    in.seekg(0, ios::beg);
    
    char ch;
    for (int i = 1; i <= bmpFileHeader.bfOffBits; i++) {
        in.read(&ch, 1);
        out.write(&ch, 1);
    }
    
    in.close();
    
    for (int i = 0; i < Height; i++) {
        out.write(pixels_crypted[i], RowSize); //Заполнение одного рядка
        for (int j = 1; j <= padding; j++)
            out.put(0); //Заполняем паддинг
    }
    
    out.close();
    
    return 0; 
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
17.01.2012, 23:21
Ответы с готовыми решениями:

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

64-х и 32-х битные системы
Пишу в MSVS 2012 на Windows 8... интересует вопрос, почему программа не запускается на 32-х битных...

16-битные числа
Данные два 16-битных числа A (aa. .. a) и B (bb. .. b), случайным образом выбирается точка разрыва...

Битные маски
Найти все натуральные числа k &lt;50 такие, что выражение 2 * 36n + k * 23n +1 - 1 при всех n (n &lt;5)...

30
Жарю без масла
867 / 749 / 225
Регистрация: 13.01.2012
Сообщений: 1,702
17.01.2012, 23:27 2
на каком основании вы используете методы класса fstream для доступа к бинарным файлам?

Не по теме:

мне кто то уже стучался в личку с подобным. похоже, эпидемия?

0
10 / 10 / 1
Регистрация: 09.04.2010
Сообщений: 141
17.01.2012, 23:34  [ТС] 3
Цитата Сообщение от retmas Посмотреть сообщение
на каком основании вы используете методы класса fstream для доступа к бинарным файлам?

Не по теме:

мне кто то уже стучался в личку с подобным. похоже, эпидемия?

а в чем, собственно, проблема? fstream же все-таки класс (для) файлов и я использую его
Цитата Сообщение от retmas Посмотреть сообщение
для доступа к бинарным файлам.
Или я что-то пропустил в своем обучении?
0
Жарю без масла
867 / 749 / 225
Регистрация: 13.01.2012
Сообщений: 1,702
17.01.2012, 23:38 4
в том что они не предназначены для работы с двоичными файлами
0
10 / 10 / 1
Регистрация: 09.04.2010
Сообщений: 141
17.01.2012, 23:41  [ТС] 5
Цитата Сообщение от retmas Посмотреть сообщение
в том что они не предназначены для работы с двоичными файлами
Пусть вы правы. А вот вы мне скажите где именно это проявляется в моей программе?
0
Жарю без масла
867 / 749 / 225
Регистрация: 13.01.2012
Сообщений: 1,702
17.01.2012, 23:49 6
может случится так, что после
C++
1
2
        in.read( (char*)&bmpFileHeader, sizeof( bmpFileHeader ) ); //Считывание данных 
        in.read( (char*)&bmpInfoHeader, sizeof( bmpInfoHeader ) ); //в структуры
в bmpFileHeader и bmpInfoHeader содержится совсем не то, что вы ожидаете.
дальше не смотрел
и проверять ваш алгоритм кодирования как то не горю желанием
0
10 / 10 / 1
Регистрация: 09.04.2010
Сообщений: 141
17.01.2012, 23:58  [ТС] 7
Цитата Сообщение от retmas Посмотреть сообщение
может случится так, что после
C++
1
2
        in.read( (char*)&bmpFileHeader, sizeof( bmpFileHeader ) ); //Считывание данных 
        in.read( (char*)&bmpInfoHeader, sizeof( bmpInfoHeader ) ); //в структуры
в bmpFileHeader и bmpInfoHeader содержится совсем не то, что вы ожидаете.
дальше не смотрел
и проверять ваш алгоритм кодирования как то не горю желанием
Да, но дальше идет строка
C++
1
in.seekg(bmpFileHeader.bfOffBits, ios::beg); //Перескакиваем в начало массива пикселей
0
Жарю без масла
867 / 749 / 225
Регистрация: 13.01.2012
Сообщений: 1,702
18.01.2012, 00:06 8
и что? вы похоже не поняли, что я сказал
Цитата Сообщение от Sahon Посмотреть сообщение
в bmpFileHeader и bmpInfoHeader содержится совсем не то, что вы ожидаете
означает, что там вполне может быть мусор с точки зрения вашей программы,
а значит что и в bmpFileHeader.bfOffBits может быть полная ерунда
и так далее в последущих вызовах read/write/seek* и обращениям к этим переменным
0
10 / 10 / 1
Регистрация: 09.04.2010
Сообщений: 141
18.01.2012, 00:14  [ТС] 9
Цитата Сообщение от retmas Посмотреть сообщение
и что? вы похоже не поняли, что я сказал

означает, что там вполне может быть мусор с точки зрения вашей программы
да, вы правы, не до конца понял о чем вы написали. Но я не пойму одного, с какой стати может быть мусор в bmpFileHeader, если указатель вывода стоит вначале, а структура bmpFileHeader у ВСЕХ битмапов одинакова.

----------

Только что проверил на исходном файле - bmpFileHeader считывает нормально, так что дело не в этих строках.
0
Жарю без масла
867 / 749 / 225
Регистрация: 13.01.2012
Сообщений: 1,702
18.01.2012, 00:20 10
да потому что... ох, еще раз
Цитата Сообщение от Sahon Посмотреть сообщение
они не предназначены для работы с двоичными файлами
т.е. могут считать из двоичного файла не так как вы ожидаете и не то
0
10 / 10 / 1
Регистрация: 09.04.2010
Сообщений: 141
18.01.2012, 00:22  [ТС] 11
Цитата Сообщение от retmas Посмотреть сообщение
да потому что... ох, еще раз

т.е. могут считать из двоичного файла не так как вы ожидаете
Цитата Сообщение от Sahon Посмотреть сообщение
Только что проверил на исходном файле - bmpFileHeader считывает нормально, так что дело не в этих строках.
Да и объясните мне пожалуйста, в чем проявляется эта непредназначенность?
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
12458 / 7482 / 1753
Регистрация: 25.07.2009
Сообщений: 13,762
18.01.2012, 00:22 12
Цитата Сообщение от retmas Посмотреть сообщение
в том что они не предназначены для работы с двоичными файлами
Это с какого потолка взято?
0
Жарю без масла
867 / 749 / 225
Регистрация: 13.01.2012
Сообщений: 1,702
18.01.2012, 00:30 13
и имейте ввиду, что если в один прекрасный момент у вас что то заработает, то это совсем не значит, что будет работать потом и с другими файлами или при компиляции с другой реализацией стандартной библиотеки

Добавлено через 1 минуту
Цитата Сообщение от easybudda Посмотреть сообщение
Это с какого потолка взято?
с такого что read/write символьно ориентированные ф-ии
и ios::binary этого не отменяет

Добавлено через 3 минуты
если уж вам нужно реализовать чтение/запись двоичного файла - streambuf в помощь

п.с. изучите получше STL IOStreams, дабы не возникало таких проблем
0
10 / 10 / 1
Регистрация: 09.04.2010
Сообщений: 141
18.01.2012, 00:32  [ТС] 14
Цитата Сообщение от retmas Посмотреть сообщение
с такого что read/write символьно ориентированные ф-ии
и ios::binary этого не отменяет
А ничего, что 1 символ вмещается ровно в 1 байт (ну и, ессно, наоборот) и в hex-редакторах байты показываются символами, а не, допустим, целыми чистами?

Цитата Сообщение от retmas Посмотреть сообщение
если уж вам нужно реализовать чтение/запись двоичного файла - streambuf в помощь

п.с. изучите получше STL IOStreams, дабы не возникало таких проблем
ну за этот совет спасибо.
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
12458 / 7482 / 1753
Регистрация: 25.07.2009
Сообщений: 13,762
18.01.2012, 00:43 15
Цитата Сообщение от retmas Посмотреть сообщение
с такого что read/write символьно ориентированные ф-ии
Хоть намекните, где такое пишут. read() write() - тут ни словом почему-то не обмолвились, что эти функции нельзя с двоичными файлами использовать...
0
Жарю без масла
867 / 749 / 225
Регистрация: 13.01.2012
Сообщений: 1,702
18.01.2012, 01:08 16
Цитата Сообщение от Sahon Посмотреть сообщение
А ничего, что 1 символ вмещается ровно в 1 байт
не везде и не каждый


Цитата Сообщение от Sahon Посмотреть сообщение
hex-редакторах байты показываются символами
для того они и созданы, чтобы можно было смотреть в разных представлениях, но причем тут ф-ии ввода/вывода fstream? или вы утверждаете, что считывание данных из файла этих hex-редакторов написаны с помощью этих ф-ий?

Добавлено через 10 минут
Цитата Сообщение от easybudda Посмотреть сообщение
Хоть намекните, где такое пишут. read() write() - тут ни словом почему-то не обмолвились, что эти функции нельзя с двоичными файлами использовать...
штудируем ваши ссылки
цитаты с первых строк:
>> Reads a block of data of n characters
>> Writes the block of data pointed by s, with a size of n characters
если не удовлетворены найду еще

Добавлено через 13 минут
не поленился - погуглил
нужны еще более веские доводы?
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
12458 / 7482 / 1753
Регистрация: 25.07.2009
Сообщений: 13,762
18.01.2012, 01:18 17
Цитата Сообщение от retmas Посмотреть сообщение
>> Reads a block of data of n characters
>> Writes the block of data pointed by s, with a size of n characters
Ну так а проблема-то в чём? Слово characters смущает? Если файл открыт, как двоичный, преобразования \n в \r\n не будет, sizeof(char) - единица. По большому счёту эти две функции - аналог fread/fwrite c той только разницей, что указатели на буфер принимают, как char*, а не void* - что это в корне меняет?

Добавлено через 35 секунд
Цитата Сообщение от retmas Посмотреть сообщение
нужны еще более веские доводы?
Ага... А главное - убедительные...
И было бы чудесно просто увидеть наглядный пример проблем, возникающих при чтении/записи двоичных файлов с помощью этих функций...
0
Псевдослучайный
1946 / 1145 / 98
Регистрация: 13.09.2011
Сообщений: 3,215
18.01.2012, 01:24 18
Цитата Сообщение от easybudda Посмотреть сообщение
sizeof(char) - единица
Не факт... Да и character и тип char не одно и тоже. Хотя на абсолютном большинстве систем _сегодня_ проблем возникнуть не должно.
0
Жарю без масла
867 / 749 / 225
Регистрация: 13.01.2012
Сообщений: 1,702
18.01.2012, 01:35 19
полезное чтиво
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
12458 / 7482 / 1753
Регистрация: 25.07.2009
Сообщений: 13,762
18.01.2012, 01:52 20
Цитата Сообщение от NoMasters Посмотреть сообщение
Да и character и тип char не одно и тоже.
Ну так функции-то указатели на char принимают.
Цитата Сообщение от NoMasters Посмотреть сообщение
Хотя на абсолютном большинстве систем _сегодня_ проблем возникнуть не должно.
Да и _завтра_ не должно бы. Многобайтовые символы вряд ли когда char назовут, для них уже wchar_t есть... Это в си-диез char 16-ти битный, так у мелкомягких всё по-своему... Короче, пока ничем не обосновано утверждение на счёт read/write...

Добавлено через 13 минут
Цитата Сообщение от retmas Посмотреть сообщение
полезное чтиво
Занимательно, конечно, но тем не менее очень хотелось бы увидеть пример проблемы при чтении двоичных файлов...

Не по теме:

А в прочем убедили. Стану когда-нибудь на С++ двоичные файлы обрабатывать - буду streambuf использовать... :)

0
18.01.2012, 01:52
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
18.01.2012, 01:52
Помогаю со студенческими работами здесь

32-битные регистры в Borland C++
Всем доброго времени суток! Хочу сделать программу для проигрывания мелодии через системный...

64 битные типы данных в devC++
здравствуйте уважаемые специалисты. Пишу программу на DevC++ и у меня возникла потребность в...

Встроенный asm и 64-битные регистры
Всем привет! Попробовал записать в 64-битный регистр ( R8 ) данные, на что студия ответила что...

Разделить содержимое файла на 64 битные блоки
помогите с программой на c++(задание по криптографии) ,нужно разделить содержимое файла на 64...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru