Заголовок BMP — MSDN расплывчато, мой порядок байтов неправильный?

Я пишу программу для создания изображения для некоторых данных из моей химической лаборатории. Мы работаем над излучениями от элементов и тому подобного, а также над записью данных, чтобы включить примеры того, как полосы частот выглядели в спектроскопе. Я думал, что было бы неплохо создать программу, которая будет делать это для меня, в отличие от цветных карандашей, так что все чисто и прочее. Кроме того, у меня нет цветных карандашей.

Я сохраняю данные изображения в виде значений RGB в массиве int: длина ширина * высота нужного мне изображения, ширина 320, высота 50. В конце я записываю их в файл как 24-битный BGR-упорядоченный пиксели.

Прежде чем записать данные в файл, я, конечно, пытаюсь записать заголовок BMP. У MSDN была диаграмма, показывающая общий порядок секций файла, который включал кое-что о RBGQuads, но в объяснениях параграфа не описывалось, как их использовать. Я думаю, что они необязательны? Я нахожу этот график, показывающий, что я ожидал, была единственной обязательной частью заголовка:
http://www.fastgraph.com/help/bmp_header_format.html, так что я думаю, что я на правильном пути.

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

Все источники говорят, что заголовки BMP имеют порядок байтов. Я пытался поменять порядок байтов в обоих направлениях, когда я пишу, а файлы все еще не могут быть открыты. Существуют ли другие распространенные виновники поврежденных файлов домашнего приготовления?

Вот где я храню мою информацию заголовка:

typedef struct
{
char type[2];
unsigned int fsize;
unsigned short res1;
unsigned short res2;
unsigned int data_offset;
} BMPFILEHEADER;

typedef struct
{
unsigned int sizebytes;
int  width_pix;
int  height_pix;                   // negative for top down.
unsigned short  planes;            // must be 1
unsigned short  bits_per_pix;
unsigned int compression;          // zero for BI_RGB (uncompressed)
unsigned int SizeImage;            // may be set to 0 for BI_RGB images.
int  pix_per_meter_x;
int  pix_per_meter_y;
unsigned int color_used;           // set to 0
unsigned int color_important;      // set to 0
} BMPINFOHEADER;

И конечно я пишу их в таком порядке. — type is char [], потому что в любом случае это должны быть значения ‘B’ ‘M’.

Сначала я попытался написать их с помощью fwrite ():

  fwrite ( &header , 1 , 14 , fhandle );
fwrite ( &headerext , 1 , 40 , fhandle );

И тогда я попытался написать их так:

  fputc ( 'B' , fhandle );
fputc ( 'M' , fhandle );
fw_little_end ( fhandle , &header.fsize , 4 );
fw_little_end ( fhandle , &header.res1 , 2);
fw_little_end ( fhandle , &header.res2 , 2);
fw_little_end ( fhandle , &header.data_offset , 4);

где fw_little_end () выглядит так:

void fw_little_end ( FILE * fhandle , void * data , int size )
{
int i;
char * cdata = data;
for ( i = size; i > 0; i-- )
{
fputc ( *(cdata+i-1) , fhandle );
}
}

Вполне возможно, что изначально он был записан в файл с прямым порядком байтов и что мой fw_() функция имеет неправильное имя, но я также пробовал ее с размера 0 и с 0 размера, чтобы быть уверенным.

Если это звучит актуально, вот где данные записываются:

  int shift1 = 256;
int shift2 = 256*256;
for ( i = 0; i < img_size; i++)
{
fputc ( (unsigned char) (data[i]%256) , fhandle ); // B
fputc ( (unsigned char) (data[i]/shift1)%256 , fhandle ); // G
fputc ( (unsigned char) (data[i]/shift2)%256 , fhandle ); // R
} // theoretically B only needs the typecast, not the %256 but oh well lol.

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

И так, я благодарю вас за любой вклад.

0

Решение

Я публикую прямой ответ:

/* ======================================================================================== */
BOOL SaveBitmap24(LPCTSTR pszFilename, LPBYTE pPixelColorTriplets, INT nWidth, INT nHeight)
{
BOOL bState = FALSE;
// sizes
INT nOfsetToPixel = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPCOREHEADER);
INT nPixelSize = nWidth * nHeight * 3;
INT nFileSize = nOfsetToPixel + nPixelSize;
// setup bitmap file header --------------
BITMAPFILEHEADER bmFileHeader = { 0 };
// "BM" signature
bmFileHeader.bfType = 0x4D42;
bmFileHeader.bfOffBits = nOfsetToPixel;
bmFileHeader.bfSize = nFileSize;
// setup bitmap info header --------------
BITMAPCOREHEADER bmCoreHeader = { 0 };
bmCoreHeader.bcSize = sizeof(BITMAPCOREHEADER);
bmCoreHeader.bcWidth = nWidth;
bmCoreHeader.bcHeight = nHeight;
bmCoreHeader.bcBitCount = 24;
bmCoreHeader.bcPlanes = 1;
// write file -----------------------
FILE *fileBitmap = fopen(pszFilename, _T("wb"));
if (fileBitmap)
{   fwrite(&bmFileHeader, sizeof(BITMAPFILEHEADER), 1, fileBitmap);
fwrite(&bmCoreHeader, sizeof(bmCoreHeader), 1, fileBitmap);
fwrite(pPixelColorTriplets, nPixelSize, 1, fileBitmap);
fclose(fileBitmap);
bState = TRUE;
}
return bState;
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector