Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Чтение BMP файла

4.7K
26 января 2004 года
Gscom
11 / / 26.01.2004
Помогите пожалйста с чтением bmp фала, не используя функции LoadFromFile. Следующая функция записи является моей модернизацией майкрософтовского варианта:


#include <fstream.h>
#include <math.h>


void SaveBMP(char *name,TCanvas *im2, int W, int H,unsigned long bitpixel)
{
bitpixel=exp(log(2)*bitpixel);
HDC hdcScreen; // DC for entire screen
HDC hdcScreenCompat; // memory DC for screen
HBITMAP hbmpCompat; // bitmap handle for old DC
BITMAP bmp; // bitmap data structure

HDC MBM , MDC,CDC;


hdcScreenCompat = CreateCompatibleDC(im2->Handle);

bmp.bmBitsPixel = (BYTE) GetDeviceCaps(im2->Handle, BITSPIXEL);
bmp.bmPlanes = (BYTE) GetDeviceCaps(im2->Handle, PLANES);
bmp.bmWidth =W;
bmp.bmHeight =H;

// The width must be byte-aligned.

bmp.bmWidthBytes = ((bmp.bmWidth + 15) & ~15) / 8;

// Create a bitmap for the compatible DC.
hbmpCompat = ::CreateCompatibleBitmap(im2->Handle,bmp.bmWidth ,bmp.bmHeight);


// Select the bitmap for the compatible DC.
HGDIOBJ oldObj = ::SelectObject(hdcScreenCompat, hbmpCompat);
::BitBlt(hdcScreenCompat, 0, 0, bmp.bmWidth, bmp.bmHeight, im2->Handle, 0, 0, SRCCOPY);
::SelectObject(hdcScreenCompat, oldObj);

// Write BMP to file
// 256 - is a maximum. We alloc so much just in case
DWORD dwHeaderSize = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD);
BITMAPINFO * pBmpInfo = (BITMAPINFO*)calloc(dwHeaderSize, 1);
BYTE * pData;

pBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pBmpInfo->bmiHeader.biWidth = bmp.bmWidth;
pBmpInfo->bmiHeader.biHeight = bmp.bmHeight;
pBmpInfo->bmiHeader.biPlanes = 1;

int nSize = 0;
switch(bitpixel)
{
case 2:
pBmpInfo->bmiHeader.biBitCount = 1;
nSize = bmp.bmWidth * bmp.bmHeight / 8;
break;
case 16:
pBmpInfo->bmiHeader.biBitCount = 4;
nSize = bmp.bmWidth * bmp.bmHeight / 2;
break;
case 256:
pBmpInfo->bmiHeader.biBitCount = 8;
nSize = bmp.bmWidth * bmp.bmHeight;
break;
case 65535:
pBmpInfo->bmiHeader.biBitCount = 16;
nSize = bmp.bmWidth * bmp.bmHeight * 2;
break;
case 16777215:
pBmpInfo->bmiHeader.biBitCount = 24;
nSize = bmp.bmWidth * bmp.bmHeight * 3;
break;
case 4294967295:
pBmpInfo->bmiHeader.biBitCount = 32;
nSize = bmp.bmWidth * bmp.bmHeight * 4;
break;
}

pBmpInfo->bmiHeader.biClrUsed = bitpixel;

pData = (BYTE*)calloc(nSize, 1);

::GetDIBits(hdcScreenCompat, hbmpCompat, 0, bmp.bmHeight, pData, pBmpInfo, DIB_RGB_COLORS);

//pBmpInfo->bmiHeader.biClrUsed = g_nColors;

::DeleteDC(hdcScreenCompat);
::DeleteDC(hdcScreen);
ofstream op;
op.open(name,ios::out | ios::binary);
if (op.is_open())
{
BITMAPFILEHEADER hdr;

hdr.bfType = 0x4d42;
hdr.bfSize = (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + nSize);
hdr.bfReserved1 = 0;
hdr.bfReserved2 = 0;
hdr.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

if (pBmpInfo->bmiHeader.biClrUsed > 0 && pBmpInfo->bmiHeader.biClrUsed <= 256)
{
hdr.bfSize += sizeof(RGBQUAD) * pBmpInfo->bmiHeader.biClrUsed;
hdr.bfOffBits += sizeof(RGBQUAD) * pBmpInfo->bmiHeader.biClrUsed;
}


op.write((const char*)&hdr, sizeof(hdr));
op.write((const char*)&pBmpInfo->bmiHeader, sizeof(BITMAPINFOHEADER));

if (pBmpInfo->bmiHeader.biClrUsed > 0 && pBmpInfo->bmiHeader.biClrUsed <= 256)
{
op.write((const char*)&pBmpInfo->bmiColors, sizeof(RGBQUAD) * pBmpInfo->bmiHeader.biClrUsed);
}


op.write((const char*)pData, nSize);

op.close();
}

free(pBmpInfo);
free(pData);

}
У меня при чтении возникают проблемы с палитрой.
Если кто может помогите с исходным кодом записи BMP.
:(
1.9K
27 января 2004 года
ILS
100 / / 28.01.2003
Цитата:
Originally posted by Gscom

case 256:
pBmpInfo->bmiHeader.biBitCount = 8;
nSize = bmp.bmWidth * bmp.bmHeight;
break;
case 65535:
pBmpInfo->bmiHeader.biBitCount = 16;
nSize = bmp.bmWidth * bmp.bmHeight * 2;
break;
case 16777215:
pBmpInfo->bmiHeader.biBitCount = 24;
nSize = bmp.bmWidth * bmp.bmHeight * 3;
break;
case 4294967295:
pBmpInfo->bmiHeader.biBitCount = 32;
nSize = bmp.bmWidth * bmp.bmHeight * 4;
break;
}

pBmpInfo->bmiHeader.biClrUsed = bitpixel;

У меня при чтении возникают проблемы с палитрой.
:(


На сколько я понимаю, ошибка в величине biClrUsed - она используется для определения длины палитры в форматах реально ее имеющих (в твоем случае до 256 включительно - но не более!)
Вот кусок кода "нормального" определения длины палитры
...
i=BMPInfoHead->biClrUsed;
if(!i) { i=BMPInfoHead->biClrImportant;
if(!i) { switch(BMPInfoHead->biBitCount)
{ case 1: i=2; break;
case 4: i=16; break;
case 8: i=256; break;
case 16:
case 32: Application->MessageBox("Извините, но данная версия не поддерживает\n"
"16-ти и 32-х битовые форматы BMP-файлов.",
"ошибка загрузки кадра",MB_OK|MB_ICONSTOP);
return (false);// Close();
// break;
}
}
}
PalSize=i;
if(PalSize) { Len=PalSize*4;//реальная длина палитры
adrFrame=adrPalet+Len;//BMPFileHead->bfOffBits;не всегда верно !!!
... }

Как видишь, PalSize определяется только для 2,16 и 256- цветных изображений - у "более крутых" палитра просто отсутствует

4.7K
27 января 2004 года
Gscom
11 / / 26.01.2004
Цитата:
Originally posted by ILS

На сколько я понимаю, ошибка в величине biClrUsed - она используется для определения длины палитры в форматах реально ее имеющих (в твоем случае до 256 включительно - но не более!)
Вот кусок кода "нормального" определения длины палитры
...
i=BMPInfoHead->biClrUsed;
if(!i) { i=BMPInfoHead->biClrImportant;
if(!i) { switch(BMPInfoHead->biBitCount)
{ case 1: i=2; break;
case 4: i=16; break;
case 8: i=256; break;
case 16:
case 32: Application->MessageBox("Извините, но данная версия не поддерживает\n"
"16-ти и 32-х битовые форматы BMP-файлов.",
"ошибка загрузки кадра",MB_OK|MB_ICONSTOP);
return (false);// Close();
// break;
}
}
}
PalSize=i;
if(PalSize) { Len=PalSize*4;//реальная длина палитры
adrFrame=adrPalet+Len;//BMPFileHead->bfOffBits;не всегда верно !!!
... }

Как видишь, PalSize определяется только для 2,16 и 256- цветных изображений - у "более крутых" палитра просто отсутствует


Спасибо большое буду дальше разбираться :)

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог