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

BMP 8bit odczyt/zapis

Object Storage Arubacloud
0 głosów
551 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 (194,920 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ź 339 wizyt
pytanie zadane 16 stycznia 2020 w C i C++ przez Igor Użytkownik (740 p.)
0 głosów
2 odpowiedzi 284 wizyt
pytanie zadane 25 sierpnia 2020 w C# przez Comparion Obywatel (1,810 p.)
0 głosów
2 odpowiedzi 1,332 wizyt
pytanie zadane 1 stycznia 2019 w C i C++ przez nooblike Nowicjusz (120 p.)

92,615 zapytań

141,465 odpowiedzi

319,781 komentarzy

61,997 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.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...