Monochrome Bitmap erstellen

HolgerX

Mitglied
Mal wieder eine Rookie Frage. :rolleyes:

Ich will eine monochrome Bitmap erstellen, der ich die Werte einer 8Bit DIB zuweise.
Dabei hat die 8Bit Bitmap nur noch die Werte 0, bzw. 255 für RGB stehen.

D.h. ich weiss, welches Pixel schwarz, bzw. weiß ist, aber wie kann ich der monochromen Bitmap diese Werte zuweisen?

Ich denke mal SetBitmapBits() könnte da funktionieren, aber wieviel Bytes brauche ich da?
Kann mir mal jemand dazu einen einfachen Quelltext schreiben?!

Was bedeutet übrigens das Scan in der Hilfe von Visual Studio:
Code:
The monochrome bitmap uses a 1-bit, 1-plane format. Each Scan is multiple of 16 bits.
Scans are organized as follows for a monochrome bitmap of height n:

Scan 0
Scan 1
.
.
.
Scan n-2
Scan n-1
 
Also nochmal meine Frage:

Wie kann ich eine einfache Monochrome (also schwarz/weiß) Bitmap erstellen und ihr Werte zuweisen?
 
Du hattest schonmal nach Grauwertbildern gefragt. Das machst du genauso. Der Unterschied ist nur, dass du das Grauwertbild dann auf 2 Werte (0 oder 1) mappst. Wenn also die Grauabstufung in einem Umfang von 256 Farben definiert ist, legst du bspw. fest, dass im Bereich von 0 bis 127 der Wert 0 und im Bereich von 128 bis 255 der Wert 1 gesetzt wird. Die Bits setzt du dann relativ einfach, indem du bspw. eine char-Variable als Grundtyp nimmst und ihr dann 0 oder 1 addierst und danach um 1 nach links shiftest (mit <<). Das ganze 8 mal und die Variable kann gespeichert werden (weil Datenumfang erschöpft).
 
Das habe ich auch alles wunderbar gemacht.

Das Problem ist nur, dass ich eine 8Bit-Grafik eingelesen habe, die ich jetzt in eine 1Bit-Grafik wandeln will.
Jetzt habe ich versucht den ursprünglichen BITMAPINFOHEADER anzupassen, d.h.:
Code:
	m_pPalette[0].rgbRed = 0;
	m_pPalette[0].rgbGreen = 0;
	m_pPalette[0].rgbBlue = 0;
	m_pPalette[1].rgbRed = 255;
	m_pPalette[1].rgbGreen = 255;
	m_pPalette[1].rgbBlue = 255;

	m_pBIH->biBitCount = 1;
	m_pBIH->biClrUsed = 0;
Wobei m_pBIH der Zeiger auf den BITMAPINFOHEADER ist, und m_pPalette auf die Palette zeigt.
Unter m_pDibBits ist der Zeiger gespeichert, der auf die Datenbits (hinter den ganzen Headerdaten) zeigt.
Die Daten habe ich folgendermassen extrahiert, und wieder neu zugewiesen:
Code:
	// Pixel zuweisen
	for(int zeile= 0; zeile< m_iHeight; zeile ++)
	{
		for (int spalte=0; spalte < m_iWidth; spalte ++)
		{			
			int grauwert = m_pDibBits[zeile * m_iWidth + spalte];
			if( grauwert < 255)
			{
				uc = uc + 0;
			}
			else if(grauwert == 255)
			{
				uc = uc + 1;
			}						
			if(counterIntern<7)
			{
				 uc <<= 1;
				counterIntern ++;
			}


			// falls das Byte voll ist, ins nächste gehen
			else if (counterIntern == 7)
			{
				counterIntern = 0;		
				m_pDibBits[counter] = uc;
				uc = 0;			
				counter ++;
			}
			// falls eine Zeile zu Ende ist, aber das Byte noch nicht voll
			if(counterIntern !=7 && spalte == m_iWidth-1)
			{
				while(counterIntern !=7)
				{
					uc<<=1;
					counterIntern++;
				}
				m_pDibBits[counter];
				counter ++;
			}			
		}
	}
Aber das Resultat beim Zeichnen ist ein einziges Rauschen.

Muss ich da jetzt noch irgendwo nen zusätzliches Byte reinbringen, dass zum Auffüllen dient, oder so?
 
Zuletzt bearbeitet:
Punkt 1, die Logik mit dem Zeilenende ist Unsinn. Bitmaps arbeiten so nicht. Am besten ist es sogar, wenn man ein Bitmap für diese Zwecke als eindimensionales Array parst. Dann sehe ich noch ein Problem in der Bitzuweisung. Eigentlich müsste das Bild schwarz sein oder überwiegend. Wenn du sagst, dass nur der Wert 255 weiß ist, bedeutet dass, dass nur 0,4% aller Pixel im Durchschnitt weiß werden.
Wenn das nicht hinhaut, experimentiere mal damit. Speichere mal nur Nullen und dann mal nur Einsen und dann mal mit einer Zählschleife (so lassen sich gut vorhersehbare Ergebnisse produzieren).
 
Original geschrieben von Dudadida
Punkt 1, die Logik mit dem Zeilenende ist Unsinn. Bitmaps arbeiten so nicht.
Das weiss ich ja gerade nicht, deshalb frage ich. :(


Am besten ist es sogar, wenn man ein Bitmap für diese Zwecke als eindimensionales Array parst.
Das habe ich doch gemacht, m_pDibBits ist doch ein eindimensionales Array, bzw. ein Zeiger darauf.


Dann sehe ich noch ein Problem in der Bitzuweisung. Eigentlich müsste das Bild schwarz sein oder überwiegend. Wenn du sagst, dass nur der Wert 255 weiß ist, bedeutet dass, dass nur 0,4% aller Pixel im Durchschnitt weiß werden.
Ich habe vorher eine Binarisierung durchgeführt, so dass alle Pixel entweder den Wert 0 oder 255 haben.

Wenn das nicht hinhaut, experimentiere mal damit. Speichere mal nur Nullen und dann mal nur Einsen und dann mal mit einer Zählschleife (so lassen sich gut vorhersehbare Ergebnisse produzieren).
Rumprobieren tue ich schon die ganze Zeit, ein konstruktiverer Vorschlag wäre mir lieber!

btw: Bei manchen 8Bit Images kommt sogar ein halbwegs vernünftiges 1Bit Ergebnis raus, so wie ich das mache. - Aber halt nur halbwegs und nur bei einigen . :(
 
Gibts denn nirgendwo eine Anleitung, wie man eine Monochrome Device Independent Bitmap (1Bit-DIB) selbst erstellen kann?

Soweit ich jetzt weiss, muss jede Zeile ein vielfaches von 16Bit an Daten enthalten. - D.h. falls die Zeile die Bedingung erfüllt: 8 > #Spalten%16 >0 muss das letzte Byte mit 0-en aufgefüllt werden.
Falls die Zeile folgende Bedingung erfüllt:#Spalten%16 >7 muss das letzte Byte mit 0-en aufgefüllt werden, sowie ein zusätzliches allerletztes 0-Byte für die Zeile geschrieben werden.

Was muss ich alles im BITMAPINFHOHEADER oder der BITMAPINFO Structure angeben? - Muss ich sonst noch irgendwelche Strukturen berücksichtigen? :(

Ich will mittels StretchDIBits das Image zeichnen.
Leider schmiert mir dann immer das Programm mit Ausnahmefehler ab. :mad:
 

Neue Beiträge

Zurück