• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

BMP 8bit odczyt/zapis

VPS Starter Arubacloud
0 głosów
632 wizyt
pytanie zadane 16 stycznia 2020 w C i C++ przez Mavannkas Bywalec (2,290 p.)

Cześć, od paru dni męczę się z pewnym problemem. Mianowicie próbuje rozgryźć to jak odczytać-zmodyfikować-zapisać obraz w formacie bitmapy... Szukam sporo w internecie i nie mogę znaleźć a sam aż tak tego nie rozumiem :(. Mam taki program napisany. Odczyt działa tylko nie wiem jak to zapisać do pliku. Wiem, że każdy element powstałej tablicy to kolejny bit obrazu więc wystarczy je zmodyfikować.

#include <iostream>
#include <Windows.h>
#include <fstream>

using namespace std;


uint8_t* datBuff[2] = { nullptr, nullptr }; 
uint8_t* pixels = nullptr; 
BITMAPFILEHEADER* bmpHeader = nullptr; 
BITMAPINFOHEADER* bmpInfo = nullptr; 
int LoadBMP(const char* location);
int SaveNewBmp(const char* location);

int main()
{



	

}



int LoadBMP(const char* location) {



	std::ifstream file(location, std::ios::binary);
	if (!file)
	{
		std::cout << "Failure to open bitmap file.\n";

		return 1;
	}



	datBuff[0] = new uint8_t[sizeof(BITMAPFILEHEADER)];
	datBuff[1] = new uint8_t[sizeof(BITMAPINFOHEADER)];

	file.read((char*)datBuff[0], sizeof(BITMAPFILEHEADER));
	file.read((char*)datBuff[1], sizeof(BITMAPINFOHEADER));


	bmpHeader = (BITMAPFILEHEADER*)datBuff[0];
	bmpInfo = (BITMAPINFOHEADER*)datBuff[1];



	if (bmpHeader->bfType != 0x4D42)
	{
		std::cout << "File \"" << location << "\" isn't a bitmap file\n";
		return 2;
	}

	pixels = new uint8_t[bmpInfo->biSizeImage];

	file.seekg(bmpHeader->bfOffBits);
	file.read((char*)pixels, bmpInfo->biSizeImage);
	


	return 0;
}

int SaveNewBmp(const char* location) {
	std::ofstream file(location, std::ios::binary);
	if (!file)
	{
		std::cout << "Failure to open bitmap file.\n";

		return 1;
	}

	file.write((char*)datBuff[0], sizeof(BITMAPFILEHEADER));
	file.write((char*)datBuff[1], sizeof(BITMAPINFOHEADER));

	file.write((char*)pixels, bmpInfo->biSizeImage);
	return 0;
}

Jakieś pomysły? Z góry dziękuję :D 

1 odpowiedź

0 głosów
odpowiedź 16 stycznia 2020 przez j23 Mędrzec (195,220 p.)
edycja 16 stycznia 2020 przez j23

Przy zapisywaniu zapomniałeś o offsecie bfOffBits i potencjalnej palecie.

--- dodane ---

Poprawiłem tę twoją funkcję czytającą (nie testowana):

BITMAPFILEHEADER bmpHeader; 
BITMAPINFOHEADER* bmpInfo = nullptr; 
std::vector<uint8_t> pixels; 
std::vector<char> bmpInfoData;
std::vector<RGBQUAD> colorTable;



int LoadBMP(const char* location) 
{
	std::ifstream file(location, std::ios::binary);
	if (!file.is_open()) { 
		std::cout << "Failure to open bitmap file.\n";
		return 1;
	}
 
	file.read(reinterpret_cast<char*>(&bmpHeader), sizeof(BITMAPFILEHEADER));

	if (bmpHeader->bfType != 0x4D42) {
		std::cout << "File \"" << location << "\" isn't a bitmap file\n";
		return 2;
	}
	
	DWORD size = 0;

	file.read(reinterpret_cast<char*>(&size), 4);
	bmpInfoData.resize(size);
	file.read(&bmpInfoData[0] + 4, size - 4);
	bmpInfo = reinterpret_cast<BITMAPINFOHEADER*>(&bmpInfoData[0]);
	bmpInfo->biSize = size;
 
	if (bmpInfo->biBitCount <= 8 && bmpInfo->biCompression == BI_RGB) {
		int maxColors = bmpInfo->biClrUsed;

		if (maxColors == 0) {
			switch (bmpInfo->biBitCount) {
				case 1: maxColors = 2; break;
				case 2: maxColors = 4; break;
				case 4: maxColors = 16; break;
				case 8: maxColors = 256; break;
			}
		}

		colorTable.resize(maxColors);
		file.read(reinterpret_cast<char*>(&colorTable[0]), colorTable.size() * sizeof(RGBQUAD));
	}

	pixels.resize(bmpInfo->biSizeImage);
 	file.seekg(bmpHeader->bfOffBits);
	file.read(reinterpret_cast<char*>(&pixels[0]), pixels.size());

	return 0;
}

Zawartość bmpInfoData może być większa od BITMAPINFOHEADER, dlatego lepiej czytać wszystko, jeśli chcesz zapisać bitmapę w tym samym formacie.

Podobne pytania

0 głosów
1 odpowiedź 380 wizyt
pytanie zadane 16 stycznia 2020 w C i C++ przez Igor Użytkownik (740 p.)
0 głosów
2 odpowiedzi 313 wizyt
pytanie zadane 25 sierpnia 2020 w C# przez Comparion Obywatel (1,810 p.)
0 głosów
2 odpowiedzi 1,460 wizyt
pytanie zadane 1 stycznia 2019 w C i C++ przez nooblike Nowicjusz (120 p.)

93,020 zapytań

141,985 odpowiedzi

321,284 komentarzy

62,366 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Wprowadzenie do ITsec, tom 2

Można już zamawiać tom 2 książki "Wprowadzenie do bezpieczeństwa IT" - będzie to około 650 stron wiedzy o ITsec (17 rozdziałów, 14 autorów, kolorowy druk).

Planowana premiera: 30.09.2024, zaś planowana wysyłka nastąpi w drugim tygodniu października 2024.

Warto preorderować, tym bardziej, iż mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy dodatkowe 15% zniżki! Dziękujemy zaprzyjaźnionej ekipie Sekuraka za kod dla naszej Społeczności!

...