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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.64
Sahon
10 / 10 / 1
Регистрация: 09.04.2010
Сообщений: 141
#1

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

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

Программа не хочет кодировать 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
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.01.2012, 23:21
Здравствуйте! Я подобрал для вас темы с ответами на вопрос [C++] 24-битные BMP (C++):

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

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

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

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

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

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

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
retmas
Жарю без масла
859 / 741 / 164
Регистрация: 13.01.2012
Сообщений: 1,694
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
easybudda
Модератор
Эксперт CЭксперт С++
9627 / 5575 / 947
Регистрация: 25.07.2009
Сообщений: 10,710
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
NoMasters
Псевдослучайный
1754 / 1097 / 72
Регистрация: 13.09.2011
Сообщений: 3,134
18.01.2012, 01:24 #18
Цитата Сообщение от easybudda Посмотреть сообщение
sizeof(char) - единица
Не факт... Да и character и тип char не одно и тоже. Хотя на абсолютном большинстве систем _сегодня_ проблем возникнуть не должно.
0
retmas
Жарю без масла
859 / 741 / 164
Регистрация: 13.01.2012
Сообщений: 1,694
18.01.2012, 01:35 #19
полезное чтиво
0
easybudda
Модератор
Эксперт CЭксперт С++
9627 / 5575 / 947
Регистрация: 25.07.2009
Сообщений: 10,710
18.01.2012, 01:52 #20
Цитата Сообщение от NoMasters Посмотреть сообщение
Да и character и тип char не одно и тоже.
Ну так функции-то указатели на char принимают.
Цитата Сообщение от NoMasters Посмотреть сообщение
Хотя на абсолютном большинстве систем _сегодня_ проблем возникнуть не должно.
Да и _завтра_ не должно бы. Многобайтовые символы вряд ли когда char назовут, для них уже wchar_t есть... Это в си-диез char 16-ти битный, так у мелкомягких всё по-своему... Короче, пока ничем не обосновано утверждение на счёт read/write...

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

Не по теме:

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

0
retmas
Жарю без масла
859 / 741 / 164
Регистрация: 13.01.2012
Сообщений: 1,694
18.01.2012, 01:58 #21
Цитата Сообщение от easybudda Посмотреть сообщение
Ну так функции-то указатели на char принимают
вот именно, то есть в указанную область памяти будут записываться characters

Добавлено через 4 минуты

Не по теме:

Цитата Сообщение от easybudda Посмотреть сообщение
Да и _завтра_ не должно бы
говорят, что все новое - хорошо забытое старое.
а ведь были (а может и сейчас есть?) архитектуры, где тип char состоял из 2х байт.
а вы знаете, что были (а может и сейчас есть?) архитектуры, где байт состоял не из 8 бит, а 9
а вы знаете...

0
easybudda
Модератор
Эксперт CЭксперт С++
9627 / 5575 / 947
Регистрация: 25.07.2009
Сообщений: 10,710
18.01.2012, 02:26 #22
Цитата Сообщение от retmas Посмотреть сообщение
а вы знаете, что были (а может и сейчас есть?) архитектуры, где байт состоял не из 8 бит, а 9
Знаю - из 10 были... когда-то на заре человечества... А ещё (тоже по историческим причинам) функция gethostbyaddr() первым параметром const char* принимает, а передаётся в нём приведённый struct in_addr*, которая (структура) в свою очередь (и снова по историческим причинам) содержит единственное поле типа in_addr_t. Да мало ли ещё чудес на свете, к проблеме-то (напомню - чтение содержимого bmp-файла) это каким боком относится?
0
retmas
Жарю без масла
859 / 741 / 164
Регистрация: 13.01.2012
Сообщений: 1,694
18.01.2012, 02:54 #23
к тому, что
Цитата Сообщение от easybudda Посмотреть сообщение
sizeof(char) - единица
- непереносимо в общем случае

Добавлено через 9 минут
а если вернуться к 1му посту, то увидим там следущее:
C++
1
2
3
4
5
        BITMAPFILEHEADER bmpFileHeader; //Создание bmpFileHeader
        BITMAPINFOHEADER bmpInfoHeader; //Создание bmpInfoHeader
        
        in.read( (char*)&bmpFileHeader, sizeof( bmpFileHeader ) ); //Считывание данных 
        in.read( (char*)&bmpInfoHeader, sizeof( bmpInfoHeader ) ); //в структуры
скажите чему равен sizeof(BITMAPFILEHEADER) или sizeof(BITMAPINFOHEADER)
вот вам из msdn
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
typedef struct tagBITMAPINFOHEADER { 
  DWORD biSize; 
  LONG biWidth; 
  LONG biHeight; 
  WORD biPlanes; 
  WORD biBitCount 
  DWORD biCompression; 
  DWORD biSizeImage; 
  LONG biXPelsPerMeter; 
  LONG biYPelsPerMeter; 
  DWORD biClrUsed; 
  DWORD biClrImportant; 
} BITMAPINFOHEADER;
C++
1
2
3
4
5
6
7
typedef struct tagBITMAPFILEHEADER {
  WORD bfType; 
  DWORD bfSize; 
  WORD bfReserved1; 
  WORD bfReserved2; 
  DWORD bfOffBits; 
} BITMAPFILEHEADER
0
easybudda
Модератор
Эксперт CЭксперт С++
9627 / 5575 / 947
Регистрация: 25.07.2009
Сообщений: 10,710
18.01.2012, 02:55 #24
Цитата Сообщение от retmas Посмотреть сообщение
- непереносимо в общем случае
Так тут-то случай не общий, а вполне конкретный. И размер char на машине ТС с вероятностью 99.(9) равен одному байту. Так и за чем воду мутить?
Я думаю - тут проблема совсем не в чтении данных из файла (раз уж заголовки по словам ТС читаются нормально), а в самом формате 24-битного bmp...
0
retmas
Жарю без масла
859 / 741 / 164
Регистрация: 13.01.2012
Сообщений: 1,694
18.01.2012, 02:58 #25
я остановлюсь в обсуждении этой темы, так и до китая дойти можно
0
easybudda
Модератор
Эксперт CЭксперт С++
9627 / 5575 / 947
Регистрация: 25.07.2009
Сообщений: 10,710
18.01.2012, 03:02 #26
retmas, тогда последний вопрос, и тот скорее риторический - при наличии включённого windows.h о какой переносимости вообще речь?
0
retmas
Жарю без масла
859 / 741 / 164
Регистрация: 13.01.2012
Сообщений: 1,694
18.01.2012, 17:14 #27
easybudda, хоть я и не собирался возвращаться к этой теме, но всплыла тема и я не удержался. вы хотели пример? думаю он там
п.с. хотя я не уверен, что вы именно это хотели - не разбирался в творчестве
0
easybudda
Модератор
Эксперт CЭксперт С++
9627 / 5575 / 947
Регистрация: 25.07.2009
Сообщений: 10,710
18.01.2012, 19:41 #28
Цитата Сообщение от retmas Посмотреть сообщение
вы хотели пример?
Ну там-то проблему Вы и сами определили... Нет, я понял (из вашей же ссылки в 19 посте этой темы), чем не кошерно так читать двоичные данные из файлов, но тут всё-таки другой случай...

Sahon, а не вариант сторонние библиотеки использовать? Вот несколько:
http://easybmp.sourceforge.net/
http://cimg.sourceforge.net/
http://freeimage.sourceforge.net/
Вроде все не сложные...
0
Sahon
10 / 10 / 1
Регистрация: 09.04.2010
Сообщений: 141
18.01.2012, 22:13  [ТС] #29
Цитата Сообщение от easybudda Посмотреть сообщение
Ну там-то проблему Вы и сами определили... Нет, я понял (из вашей же ссылки в 19 посте этой темы), чем не кошерно так читать двоичные данные из файлов, но тут всё-таки другой случай...

Sahon, а не вариант сторонние библиотеки использовать? Вот несколько:
http://easybmp.sourceforge.net/
http://cimg.sourceforge.net/
http://freeimage.sourceforge.net/
Вроде все не сложные...
Спасибо, попробуем эти библиотеки заюзать.

Не по теме:

Я просто создавал эту программу с помощью средств Windows и своих собственных только для того, чтобы разобраться во вводе/выводе файлов на примере изображений и для того, чтобы этим самым опыта набратся.

0
DU
1483 / 1059 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
18.01.2012, 22:41 #30
Небольшое уточнение:
Сообщение от easybudda
sizeof(char) - единица
Не факт... Да и character и тип char не одно и тоже. Хотя на абсолютном большинстве систем _сегодня_ проблем возникнуть не должно.
Вот это как раз таки факт. В страуструпе написано:
Размеры объектов в с++ выражаются в еденицах размера char. Таким образом, размер char по определению равен 1.
Правда стоит заметить, что из этого не следует, что char в памяти занимает один байт.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.01.2012, 22:41
Привет! Вот еще темы с ответами:

Как преобразовать текст на 64-битные блоки - C++
Хочу разобраться в DES шифре. Помогите понять. Не могу разобраться, как представить текст в виде 64-битных блоках, для дальнейшего...

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

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

bmp в C++ - C++
Помогите пожалуйста написать программу на C++ которая уменьшает разрешение bmp картинки в 2 раза. Можно использовать только библиотеку ...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
18.01.2012, 22:41
Ответ Создать тему
Опции темы

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