Форум программистов и сисадминов CyberForum.ru
Вернуться   Форум программистов и сисадминов CyberForum.ru > Форум Форум программистов > Форум C++ > Форум С++ для начинающих
Восстановить пароль Регистрация

Ответ Создать новую тему
 
Старый 30.07.2011, 19:11   #1
Sahon
Форумчанин
 
Регистрация: 09.04.2010
Сообщений: 139
Репутация: 9 (9)
BMP в массив и обратно (на чистом С++) / С++ для начинающих

Надо загнать изображение BMP, допустим, 100x200 пикселей, в двухмерный массив 100x200 (то-есть 20 000 ячеек). Чтобы потом можно было изображение обратно вогнать в файл из массива. Как лучше всего это осуществить?

P.S. Все это мне надо сделать на чистом C++.

P.P.S. На сколько я знаю, файл *.bmp состоит не только из самого изображение, но и его информационной части (количество цветов, размер и т.д.)
Старый 31.07.2011, 18:01   #11
alexcoder
Форумчанин
 
Регистрация: 03.06.2009
Сообщений: 1,619
Репутация: 961 (439)
Лучшие ответы: 24
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
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
//Открытие БМП-файла, возвращает массив битовых данных и через указатель структуру BITMAPINFOHEADER с параметрами битовых данных
unsigned char *OpenBitmap(char name[],BITMAPINFOHEADER *retbih)
{
HANDLE hbmp,mapfile;    //Хэндлы открытых файлов
BITMAPFILEHEADER *bfh;          //Файловый заголовок
BITMAPINFOHEADER *bih;       //Информационный заголовок файла
BITMAPINFO *bi;                 //BITMAPINFO
unsigned char *mf,*bits,*newbits;//указатели на блоки памяти
unsigned int size;              //Зазмер файла
unsigned int index;             //используется для преобразования индексного цвета в truecolor
unsigned int newsts,oldsts; //размер новой и старой строки битовой карты в байтах
hbmp=CreateFile(name,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);//открываем файл из командной строки
if(hbmp==INVALID_HANDLE_VALUE)  //Если не открылся
    {
   return 0;                            //возвращаем ошибку
   }
size=GetFileSize(hbmp,NULL);    //получаем его размер
mapfile = CreateFileMapping(hbmp,NULL,PAGE_READWRITE,0,size,"MyFileMappingObject"); //получаем хэндл маппирования
mf = (unsigned char*)MapViewOfFile(mapfile,FILE_MAP_ALL_ACCESS ,0,0,size);//Маппируем файл на участок памяти (то есть теперь файл представляет собой массим из байт в памяти)
bfh=(BITMAPFILEHEADER*)mf;//инициализируем указатель на файловый заголовок файла
if(bfh->bfType!=0x4d42)     //Если сигнатура файла не равна BM
    {
   return 0;                               //возвращаем ошибку
   }
bih=(BITMAPINFOHEADER*)(mf+0xe);            //инициализируем указатель на информационный заголовок файла
bi=(BITMAPINFO*)(mf+0xe);                   //инициализируем указатель на структуру BITMAPINFO
bits=mf+bfh->bfOffBits;                     //массив с растровыми данными
oldsts=(bfh->bfSize-bfh->bfOffBits)/bih->biHeight;  //длина строки растра в байтах старого файла
newsts=bih->biWidth*3;                              //длина строки растра в байтах нового файла
if((newsts&3)!=0)newsts=newsts&0xfffffffc+4;  //если размер стртки не кратен 4, то дополняем его до 4
newbits=new unsigned char[newsts*bih->biHeight];    //Массив нового растра
memset(newbits,0,newsts*bih->biHeight);
for(int i=0;i!=bih->biHeight;i++)        //Идем по каждому пикселю
  for(int j=0;j!=bih->biWidth;j++)
    {
    switch(bih->biBitCount)     //и в зависимости от глубины цвета преобразовываем при помощи разных алгоритмов
      {
      case 1:                           //для 1 бита на пиксель
         {
            index=(bits[i*oldsts+j/8]>>(7-j&7))&1;          //получаем цвет пикселя, как индекс в палитре файла
         newbits[i*newsts+j*3]=bi->bmiColors[index].rgbBlue;       //Заполняем массив битовых данных соответствующим цветом из палитры
         newbits[i*newsts+j*3+1]=bi->bmiColors[index].rgbGreen;
         newbits[i*newsts+j*3+2]=bi->bmiColors[index].rgbRed;
         break;
         }
      case 4:                    //для 4 бит на пиксель
         {
            index=(bits[i*oldsts+j/2]>>((1-j%2)*4))&0xf; //получаем цвет пикселя, как индекс в палитре файла
         newbits[i*newsts+j*3]=bi->bmiColors[index].rgbBlue;       //Заполняем массив битовых данных соответствующим цветом из палитры
         newbits[i*newsts+j*3+1]=bi->bmiColors[index].rgbGreen;
         newbits[i*newsts+j*3+2]=bi->bmiColors[index].rgbRed;
         break;
         }
      case 8:                   //для 8 бит на пиксель
         {
            index=bits[i*oldsts+j];                     //получаем цвет пикселя, как индекс в палитре файла
         newbits[i*newsts+j*3]=bi->bmiColors[index].rgbBlue;       //Заполняем массив битовых данных соответствующим цветом из палитры
         newbits[i*newsts+j*3+1]=bi->bmiColors[index].rgbGreen;
         newbits[i*newsts+j*3+2]=bi->bmiColors[index].rgbRed;
         break;
         }
      case 16:                  //для 16 бит на пиксель
         {
            index=bits[i*oldsts+j*2]+(bits[i*oldsts+j*2+1]<<8);      //берем 16 бит цвета
         newbits[i*newsts+j*3]=(index&0x1f)<<3;                     //разлагаем на составляющие (красный, зеленый, синий)
         newbits[i*newsts+j*3+1]=(index&0x3e0)>>2;                  //и преобразуем каждую 5-битную составляющую в 8-битную
         newbits[i*newsts+j*3+2]=(index&0x7c00)>>7;
         break;
         }
      case 24:                 //для 24 бит на пиксель
         {
         newbits[i*newsts+j*3]=bits[i*oldsts+j*3];              //копируем цветовые составляющие из старого файла в новый
         newbits[i*newsts+j*3+1]=bits[i*oldsts+j*3+1];
         newbits[i*newsts+j*3+2]=bits[i*oldsts+j*3+2];
         break;
         }
      }
    }
 
retbih->biBitCount=24;          //количество бит на пиксель
retbih->biCompression=BI_RGB;   //без компрессии
retbih->biSizeImage=newsts*bih->biHeight;   //размер изображения
retbih->biSize=sizeof(BITMAPINFOHEADER);    //размер заголовка
retbih->biWidth=bih->biWidth;       //ширина растра
retbih->biHeight=bih->biHeight;   //высота растра
retbih->biPlanes=1;                 //количестао плоскостей, должно быть 1
retbih->biXPelsPerMeter=bih->biXPelsPerMeter;//разрешение пикселей на метр
retbih->biYPelsPerMeter=bih->biYPelsPerMeter;
 
UnmapViewOfFile(mf);                 //Закрываем маппирование
CloseHandle(mapfile);                //закрываем файл
CloseHandle(hbmp);                   //закрываем файл
return newbits;                     //возвращаем битовые данные
}
Возвращается массив глубиной 24 бита.
Старый 31.07.2011, 18:01
Yandex
Объявления
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Ответ Создать новую тему

Похожие темы
Тема Автор
Visual C++ Конвертация из jpg в bmp и обратно
И так, ребят, мне срочно нужна помощь! нужно при помощи MS Visual C++ переконвертировать jpg в bmp а потом обратно если кто делал, помогите пожалуйста! срочно надо! в инете копал, но особо много не раскопал...
jackair
С++ для начинающих Вывод информации о *.bmp на чистом C++
Собственно вот: #include <iostream> #include <fstream> #include <cmath> using namespace std; int main(int argc, char *argv) { char ch;
Sahon
C++ Builder Загрузка файла в массив и обратно
Есть текстовый файл с целыми числами: 1 5 56 3 456 и т.д. нужно загрузить эти числа в массив и наоборот: сохранить массив в файл, чтобы числа шли так же через пробел.
Storm54
C# для начинающих .NET 2.x dataGridView в массив и обратно
Добрый день, уважаемые форумчане, перейду сразу к делу. -Существует контрол dataGridView с 3 столбцами: name(название), rating(рейтинг), top_list(место в списке) -Заданы значения name и rating, и по рейтингу необходимо определить какое место в списке занимает элемент, и вывести в dataGridView уже...
zOnk
Java Массив Image в поток и обратно
Помогите, плиз! Нужно: на сервере запихать массив Image в выходной поток, а потом в клиентском апп. их вытащить из потока. Клиентское приложение на J2ME.
monastyr
Опции темы

Текущее время: 09:40. Часовой пояс GMT +4.

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.7 PL3
Copyright ©2000 - 2014, vBulletin Solutions, Inc.