Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.76/41: Рейтинг темы: голосов - 41, средняя оценка - 4.76
0 / 0 / 0
Регистрация: 09.04.2011
Сообщений: 16
1

Конвертация BMP в свой формат

28.10.2012, 01:03. Показов 7748. Ответов 31
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Стоит задача сделать собственный формат изображения. Собственный формат предполагает создание собственной структуры заголовка (отличающейся от BMP), запись этого заголовка в файл и запись растровых данных с глубиной цвета 24 бита.

Программа должна открывать BMP сохранять в свой формат и наоборот (открывать свой формат и сохранять в 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
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
if (OpenPictureDialog1->Execute())  {
Memo1->Clear();
ptrOnBmpFile=fopen(OpenPictureDialog1->FileName.c_str(),"r");
fseek(ptrOnBmpFile, 0, SEEK_SET);
 
fread(&c, 1, 1, ptrOnBmpFile); // определяем что за файл
 
if (c=='B') /*если BMP*/
{
fread(&c, 1, 1, ptrOnBmpFile);
if (c!='M') f=False;
if (f) {
/*тут читаем BMP*/
 
// читаем инфу
Memo1->Lines->Add("Это BMP");
fread(&dwData, 4, 1, ptrOnBmpFile);
Memo1->Lines->Add("Размер файла "+IntToStr(dwData)+" byte");
fread(&dwData, 4, 1, ptrOnBmpFile);
fread(&dwData, 4, 1, ptrOnBmpFile);
fread(&dwData, 4, 1, ptrOnBmpFile);
Memo1->Lines->Add("Начало данных изображения "+IntToStr(dwData));
fread(&h, 4, 1, ptrOnBmpFile);
fread(&w, 4, 1, ptrOnBmpFile);
Memo1->Lines->Add("Разрешение "+IntToStr(h)+" x "+IntToStr(w));
fread(&wData, 2, 1, ptrOnBmpFile);
Memo1->Lines->Add("Кол-во плоскостей "+IntToStr(wData));
fread(&size, 2, 1, ptrOnBmpFile);
Memo1->Lines->Add("Кол-во битов на пиксель "+IntToStr(size));
fread(&dwData, 4, 1, ptrOnBmpFile);
Memo1->Lines->Add("Сжатие "+IntToStr(dwData));
fread(&dwData, 4, 1, ptrOnBmpFile);
Memo1->Lines->Add("Размер растра в байтах "+IntToStr(dwData));
fread(&dwData, 4, 1, ptrOnBmpFile);
Memo1->Lines->Add("Гор разреш (пик/метр) "+IntToStr(dwData));
fread(&dwData, 4, 1, ptrOnBmpFile);
Memo1->Lines->Add("Вер разреш (пик/метр) "+IntToStr(dwData));
fread(&dwData, 4, 1, ptrOnBmpFile);
Memo1->Lines->Add("Кол-во цветов "+IntToStr(dwData));
fread(&dwData, 4, 1, ptrOnBmpFile);
Memo1->Lines->Add("Кол-во важных цветов "+IntToStr(dwData));
// подгоняем окошко
Image1->Width=h;
Image1->Height=w;
Form1->Width=200+h+24;
if (Image1->Height<Memo1->Height)
{Form1->Height=380;}
else   {Form1->Height=w+73;}
// читаем растр
 
if (size==8)
 {
 Memo1->Lines->Add(IntToStr(ftell(ptrOnBmpFile)));
 fread(pal, 4, 256, ptrOnBmpFile);
 
 Memo1->Lines->Add(IntToStr(ftell(ptrOnBmpFile)));
 
 for (i=w-1;i>=0;i--)
 for (j=0;j<h;j++)
  {
  fread(&ptr,1, 1, ptrOnBmpFile);
  Image1->Canvas->Pixels[j][i]=RGB(pal[ptr].red,pal[ptr].green,pal[ptr].blue);
  }
 Memo1->Lines->Add(IntToStr(ftell(ptrOnBmpFile)));
 }
 else //обработка 24 битных изображений
 {
 Image1->Picture->LoadFromFile(OpenPictureDialog1->FileName);
  };
   // прочитали )
}

Структура заголовка:

1. Идентификатор типа файла (2 байта)
2. Автор формата (20 байт)
3. Название программы (8 байт)
4. Размер заголовка в байтах (2 байта)
5. Размер изображения в пикселах (4 байта)
6. Глубина цвета (1 байт) - глубина постоянная 24 байта
7. Ширина изображения (4 байта)
8. Размер файла в байтах (8 байт)
9. Размер растра в байтах (8 байт)
10. Смещение растровых данных (4 байта)
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
28.10.2012, 01:03
Ответы с готовыми решениями:

Конвертация bmp в png
есть изображение созданое путём Graphics::TBitmap *Bitmap=new Graphics::TBitmap; надо...

Формат PCX. Конвертация в BMP
Приветствую. Возникла задача для курсового - написать конвертер 256-цветных PCX изображений в...

Кодирование Хаффмана (bmp в свой формат)
Дообры день! Подскажите как реализовать следующее: Есть программа кодирования/декодирования...

Конвертация из bmp в png
Всем здравствуйте.:senor: Возник вопрос по поводу использования библиотек gdiplus.h. В MSDN есть...

31
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
28.10.2012, 01:27 2
Используйте класс TMemoryStream
0
0 / 0 / 0
Регистрация: 09.04.2011
Сообщений: 16
30.10.2012, 21:58  [ТС] 3
Цитата Сообщение от Avazart Посмотреть сообщение
Используйте класс TMemoryStream
Вот подразобрался я чуть с этим классом... написал такое:

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
TMemoryStream * pstream = new TMemoryStream;
pstream->Position = 0;
pstream->Write(pId, 2);
pstream->Write(pName, 20);
pstream->Write(pProgname, 8);
pstream->Write(&pTitleSize, 2);
pstream->Write(&pPixCount, 4);
pstream->Write(&pPixRate, 1);
pstream->Write(&pWidth, 4);
pstream->Write(&pFileSize, 8);
pstream->Write(&pRastrSize, 8);
pstream->Write(&pOffset, 4);
// тут всё виснет =(
for (j=0;j<pHeight-1;j++){
for (z=0;z<pWidth-1;h++){
int pOnePixR = GetRValue(Image1->Canvas->Pixels[j][z]);
int pOnePixG = GetGValue(Image1->Canvas->Pixels[j][z]);
int pOnePixB = GetBValue(Image1->Canvas->Pixels[j][z]);
pstream->Write(&pOnePixB, 1);
pstream->Write(&pOnePixG, 1);
pstream->Write(&pOnePixR, 1);
}
}
 
pstream->SaveToFile("D:\myfile.dat");
delete pstream;
и там на цикле по записи пикселей... у меня всё виснет =(
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
30.10.2012, 22:39 4
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
TMemoryStream * MS = new TMemoryStream;
Graphics::TBitmap *Bmp = new Graphics::TBitmap;
Bmp->LoadFromFile("1.bmp");
 
MS->Position= 0;
MS->Write( /*...*/ );
//...
MS->Write( /*...*/ );
 
Bmp->SaveToStream(MS);
 
MS->SaveToFile("1.mybmp");
delete Bmp,MS;
0
0 / 0 / 0
Регистрация: 09.04.2011
Сообщений: 16
30.10.2012, 22:42  [ТС] 5
Цитата Сообщение от Avazart Посмотреть сообщение
Bmp->SaveToStream(MS);
он переписывает не только биты изображения, но и заголовок BMP а он мне в моём формате не нужен =\
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
30.10.2012, 22:44 6
Ну тогда надо просто его срезать, но для этого надо знать сколько с стандартный заголовок занимает
0
0 / 0 / 0
Регистрация: 09.04.2011
Сообщений: 16
30.10.2012, 23:04  [ТС] 7
Цитата Сообщение от Avazart Посмотреть сообщение
Ну тогда надо просто его срезать, но для этого надо знать сколько с стандартный заголовок занимает
а как бы мне его так скопировать если я знаю смещение данных растра в TBitmap ?
есть какая нибудь функция копирования но только не с начала? =\
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
30.10.2012, 23:24 8
Лучший ответ Сообщение было отмечено как решение

Решение

Ну с TMemoryStream рыть надо, но почему бы не решить задачу стандартными средствами например с помощью fstream.

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

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const size_t offset= 10;
 
TMemoryStream * MS1 = new TMemoryStream;
TMemoryStream * MS2 = new TMemoryStream;
 
MS1->LoadFromFile("1.bmp");
 
//MS2->Write( /.../ );
 
MS1->Position= offset;
MS1->SaveToStream(MS2);
 
MS2->SaveToFile("1.mybmp");
 
delete MS1,MS2;
1
0 / 0 / 0
Регистрация: 09.04.2011
Сообщений: 16
31.10.2012, 00:08  [ТС] 9
Цитата Сообщение от Avazart Посмотреть сообщение
Ну с TMemoryStream рыть надо, но почему бы не решить задачу стандартными средствами например с помощью fstream.

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

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const size_t offset= 10;
 
TMemoryStream * MS1 = new TMemoryStream;
TMemoryStream * MS2 = new TMemoryStream;
 
MS1->LoadFromFile("1.bmp");
 
//MS2->Write( /.../ );
 
MS1->Position= offset;
MS1->SaveToStream(MS2);
 
MS2->SaveToFile("1.mybmp");
 
delete MS1,MS2;
не, не проканало.... всёравно заголовок копируется =\


как то не очень много информации по TMemoryStream =/

Добавлено через 34 минуты
а что делает TMemoryStream -> Seek ()

я так понимаю что внутри Seek надо указать смещение и место откуда смещать... типо того:

C++
1
pstream -> Seek (offset, )
0
Практикантроп
4827 / 2719 / 526
Регистрация: 23.09.2011
Сообщений: 5,778
31.10.2012, 00:17 10
попробуй так__
C++
1
2
3
4
5
6
7
8
9
10
11
 const size_t offset= 10;
 TMemoryStream * MS1 = new TMemoryStream;
 TFileStream *FD = new TFileStream("2.mybmp",fmCreate|fmOpenWrite) ;
 MS1->LoadFromFile("1.bmp");
  int dl = MS1->Size ;
  UCHAR *buuf = new UCHAR[dl+8];
  MS1->Seek(0,0);
  MS1->ReadBuffer( buuf,dl);
  FD->WriteBuffer( buuf+offset,dl-offset);
 delete MS1 ;
 delete FD ;
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
31.10.2012, 00:25 11
Ну тогда легче всего
решить задачу стандартными средствами например с помощью fstream.
1
0 / 0 / 0
Регистрация: 09.04.2011
Сообщений: 16
31.10.2012, 00:31  [ТС] 12
Цитата Сообщение от nick42 Посмотреть сообщение
попробуй так__
C++
1
2
3
4
5
6
7
8
9
10
11
 const size_t offset= 10;
 TMemoryStream * MS1 = new TMemoryStream;
 TFileStream *FD = new TFileStream("2.mybmp",fmCreate|fmOpenWrite) ;
 MS1->LoadFromFile("1.bmp");
  int dl = MS1->Size ;
  UCHAR *buuf = new UCHAR[dl+8];
  MS1->Seek(0,0);
  MS1->ReadBuffer( buuf,dl);
  FD->WriteBuffer( buuf+offset,dl-offset);
 delete MS1 ;
 delete FD ;
Компилятор запускает.. но когда дело доходит до создания 2.mybmp ошибка на
строку: TFileStream *FD = new TFileStream("2.mybmp",fmCreate|fmOpenWrite) ;


Победил!!

я кароче сделал как ты... только из буфера писал не в файловый поток а в поток памяти дописывал после своего заголовка... а потом весь его сохранил в файл... Сэнкъю вери матч!
0
Практикантроп
4827 / 2719 / 526
Регистрация: 23.09.2011
Сообщений: 5,778
31.10.2012, 00:40 13
Возможно с "правами" не так что-то... . У меня Win 7, Builder v.5.3, режим Release без Use Package и Dinamic Link. Работает без ошибок.
1
0 / 0 / 0
Регистрация: 09.04.2011
Сообщений: 16
31.10.2012, 00:41  [ТС] 14
Пасиб Ребята за помощ...
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
31.10.2012, 01:32 15
Кстати тут http://ru.wikipedia.org/wiki/BMP и заголовки есть и программа на Си

Добавлено через 47 минут
Думаю можно было бы как то так:
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
#include <windows.h>
#include <iostream>
#include <fstream>
//---------------------------------------------------------------------------
struct
{
 char somefield[64];
 
} my_header;
//---------------------------------------------------------------------------
int main()
{
system("chcp 1251");
using namespace std;
 
ifstream ifs("1.bmp");
ofstream ofs("1.mybmp");
 
BITMAPFILEHEADER bmp_header;
 
if( ifs && ofs )
 {
    ifs.read( (char*)&bmp_header,sizeof(bmp_header));
 
    cout<< bmp_header.bfSize <<endl;
    cout<< bmp_header.bfOffBits<<endl;
 
    strcpy(my_header.somefield,"My Bitmap Format");
 
        ifs.seekg(bmp_header.bfOffBits,ios::cur);
 
    ofs.write((char*)&my_header,sizeof(my_header));
    ofs<<ifs.rdbuf();
 }
else cerr<<"error!!!"<<endl;
 
system("pause");
return 0;
}
0
0 / 0 / 0
Регистрация: 09.04.2011
Сообщений: 16
02.11.2012, 21:00  [ТС] 16
Цитата Сообщение от Avazart Посмотреть сообщение
Кстати тут http://ru.wikipedia.org/wiki/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
char *pId, *pName,*pProgname;
DWORD pOffset, pTitleSize, pPixCount, pPixRate, pWidth, pFileSize, pHeight, pRastrSize,z;
 
pId = "PA";
pName = "Alexander Parphenuyk";
pProgname = "GiMS";
pTitleSize = 61;
pPixCount = Image1->Picture->Width*Image1->Picture->Height;
pPixRate = 24;
pWidth =  Image1->Picture->Width;
pHeight =  Image1->Picture->Height;
pFileSize = pPixCount * pPixRate + pTitleSize;
pRastrSize = pPixCount * pPixRate;
pOffset = pTitleSize + 1;
 
ptrOnPaiFile=fopen(SavePictureDialog1->FileName.c_str(),"wb");
 
fwrite(pId,2,1,ptrOnPaiFile);
fwrite(pName,20,1,ptrOnPaiFile);
fwrite(pProgname,8,1,ptrOnPaiFile);
fwrite(&pTitleSize,2,1,ptrOnPaiFile);
fwrite(&pPixCount,4,1,ptrOnPaiFile);
fwrite(&pPixRate,1,1,ptrOnPaiFile);
fwrite(&pWidth,4,1,ptrOnPaiFile);
fwrite(&pFileSize,8,1,ptrOnPaiFile);
fwrite(&pRastrSize,8,1,ptrOnPaiFile);
fwrite(&pOffset,4,1,ptrOnPaiFile);
 
int paipix;
int paiWidth = pWidth;
int paiHeight = pHeight;
 
 for (i=paiHeight-1;i>=0;i--)
 for (j=0;j<paiWidth;j++)
  {
  paipix = Image1->Canvas->Pixels[j][i];
  fwrite(&paipix, 3, 1, ptrOnPaiFile);
  }
 }
Всё стало гуд. Только одна проблема....

Если в BMPфайле допустим один пиксел описывается так: 27 1F ED то у меня он сохраняется так: EB 1F 27. Как бы мне так переделать сохранение чтобы он сохранял биты как в BMP файле? =\
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
02.11.2012, 21:16 17
C++
1
2
3
4
5
fwrite(pId,2,1,ptrOnPaiFile);
fwrite(pName,20,1,ptrOnPaiFile);
fwrite(pProgname,8,1,ptrOnPaiFile);
fwrite(&pTitleSize,2,1,ptrOnPaiFile);
fwrite(&pPixCount,4,1,ptrOnPaiFile)
Почему не в структуре ?

C++
1
2
 paipix = Image1->Canvas->Pixels[j][i];
  fwrite(&paipix, 3, 1, ptrOnPaiFile);
Ну так вы TColor сохраняете его представление...
Раскладывайте его на составляющие и собирайте в обратном порядке

Ну и все же мой пример короче,логичнее,без привлечения VCL-классов ну и нарушения порядка байт
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
02.11.2012, 21:28 18
А зачем писать свою читалку bmp? Есть готовый класс TBitmap с методом LoadFromFile. Бери все параметры заголовка из полей объекта, а пикселы из ->Canvas->Pixels и сохраняй в свой.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
02.11.2012, 21:32 19
А зачем писать свою читалку bmp? Есть готовый класс TBitmap с методом LoadFromFile. Бери все параметры заголовка из полей объекта, а пикселы из ->Canvas->Pixels и сохраняй в свой.
Ну как бы думаю будет проигрыш в скорости работы.
0
0 / 0 / 0
Регистрация: 09.04.2011
Сообщений: 16
03.11.2012, 11:53  [ТС] 20
Мне ребят контрольную просто здать свою )))) Я на скорость не соревнуюсь... мне бы попроще.. ) к тому же не особо шарю в программировании... (
0
03.11.2012, 11:53
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
03.11.2012, 11:53
Помогаю со студенческими работами здесь

Конвертация bmp изображения в матрицу
StreamWriter steamWriter = new StreamWriter(&quot;c:\1.txt&quot;); for (int y = 0; y &lt; bmp.Height; y++) {...

Конвертация BMP в массив и обратно
Добрый день. Есть проблема с конвертацией Ч/Б bmp изображения в массив и обратным получением...

Конвертация *.BMP в 3 файла *.ТХТ
Народ помогите. Нужен код на VB для конвертации файла формата BMP, ну то бишь изображения, в три...

Конвертация bmp-файла в jpg
Все привет!!! Как с помощью WinApi файл .bmp преобразовать в файл .jpg?


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

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