Tworzenie pliku bmp

0

Dzień dobry. Od kilku dni męczę się z tworzeniem pliku bmp w c++. Napisałem taki kod:


#include <fstream>
#include <iostream>

struct BMPHeader
{
	char bitmapSignatureBytes[2] = { 'B','M' };
	uint32_t sizeOfBitmapFile = 54 + 786432;
	uint32_t reservedBytes = 0;
	uint32_t pixelDataOffset = 54;
} bmpHeader;

struct BMPInfoHeader
{
	uint32_t sizeOfHeader = 40;
	uint32_t width = 512;
	uint32_t height = 512;
	uint16_t numberofColorPlanes = 1;
	uint16_t  colorDepth = 24;
	uint32_t compressionMethod = 0;
	uint32_t rawBitmapSize = 0;
	int32_t horizontalResolution = 3780; 
	int32_t verticalResolution = 3780;
	uint32_t colorTableEntries = 0;
	uint32_t importantColors = 0;
} bmpInfoHeader;

struct Pixel
{
	uint8_t red = 0;
	uint8_t green = 255;
	uint8_t blue = 255;
} pixel;

int main()
{
	std::ofstream file("image.bmp", std::ios::binary);

	file.write((char*)&bmpHeader, 14);
	file.write((char*)&bmpInfoHeader, 40);

	
	size_t numberOfPixels = bmpInfoHeader.width * bmpInfoHeader.height;
	for (int i = 0; i < numberOfPixels; i++) {
		file.write((char*)&pixel, 3);
	}
	file.close();
}



Niestety pomimo tego, że plik jest tworzony to nie można go wyświetlić. Nie mogę znaleźć błędu. Oprócz tego chciałem dodać do niego jakiś kształt (okrąg, kwadrat). Zakładam, że błąd znajduję się w nagłówku, ale nie wiem gdzie. Jeśli ktoś ma pomysł jak pozbyć się tego błędu, będę bardzo wdzięczny.

Z góry dziękuję i pozdrawiam

4

Dawno, dawno temu, na Windows 98, bawiłem się plikami BMP w QBasicu dla DOS. Proponuje postąpić w następujący sposób (jest to podobny sposób, w jaki postąpiłem w tamtych czasach):

  1. W programie Paint lub innym zrób pusty obraz o wymiarach, które chcesz wygenerować w swoim programie (czyli w tym przypadku 512x512), zapisz jako plik BMP w takim formacie, jaki próbujesz wytworzyć, w tym przypadku 24-bitowy.
  2. Uruchom swój program.
  3. Porównaj oba pliki w jakimś hex-edytorze. Zwróć uwagę na długość pliku i identyczność nagłówka. Od razu będziesz widzieć, co jest nie tak.
  4. Jeżeli spróbujesz wytworzyć całą białą lub całą czarną bitmapę, a potem zrobisz taką w Pincie, to oba pliki powinny być identyczne.

Format BMP jest tak prosty, że można bez znajomości struktury ustalić znaczenie poszczególnych bajtów dla standardowych przypadków, czyli plik Windows Bitmap bez kompresji.

0

@_13th_Dragon: Po dodaniu #pragma pack(push,1) i #pragma pack (pop) wszystko działa prawidłowo :)

@andrzejlisek: Spróbowałem twojej techniki i muszę przyznać, że bardzo mi pomogła.

Serdecznie dziękuję wszystkim za pomoc. Mam jeszcze jedno pytanko. Aktualnie moja bitmapa jest 24 bit, jak wygenerować 32 bit? Wystarczy zmienić colorDepth na 32?

1

Po dodaniu #pragma pack(push,1) i #pragma pack (pop) wszystko działa prawidłowo

Padding jest stosowany nie bez powodu. Upewnij się, że jego brak nie przysporzy Ci kłopotów w Twoim przypadku.

1 użytkowników online, w tym zalogowanych: 0, gości: 1