Pixel aus einer Bitmap auslesen



  • Hallo, ich möchte die einzelnen Pixel aus einem zu ladenden *.bmp auslesen.

    Ich habe mir auch schon was zusammengebsatelt, was leider nicht so recht funktioniert.

    HBITMAP   hBitMap;
    		hBitMap = (HBITMAP)LoadImage(0,L"1.bmp",IMAGE_BITMAP, 0, 0, 
    			LR_DEFAULTSIZE|LR_LOADFROMFILE|LR_CREATEDIBSECTION);  
    
    		BITMAP *bitmap;
    		GetObject(hBitMap, sizeof(BITMAP), &bitmap);
    
    		long groesse =(bitmap->bmBitsPixel/8) * bitmap->bmWidth * bitmap->bmHeight; 
    
    		BYTE* byte = new BYTE[groesse];
    		GetBitmapBits( hBitMap, groesse,  byte) ;
    

    Das Programm stürzt in der Zeile

    long groesse =(bitmap->bmBitsPixel/8) * bitmap->bmWidth * bitmap->bmHeight;
    

    mit den Debuggerinformationen kann ich nicht alzuviel anfangen:

    + &bitmap 0x0012f9c0 tagBITMAP * *
    + *bitmap {bmType=??? bmWidth=??? bmHeight=??? ...} tagBITMAP
    + bitmap 0xffffffff {bmType=??? bmWidth=??? bmHeight=??? ...} tagBITMAP *

    Was muß ich anders machen?



  • BITMAP *bitmap;
    

    Diese Variable initialisierst Du nicht und greifst somit auf einen ungültigen Zeiger zu. Du brauchst hier keinen Pointer, sondern einfach eine lokale Variable der Struktur 'BITMAP'; deren Adresse wird dann via Adressoperator (&) an GetObject übergeben.



  • Hallo, ich habs jetzt so:

    HBITMAP hBitMap;
    		hBitMap=NULL;
    
    		hBitMap = (HBITMAP)LoadImage( NULL, L"1.bmp", IMAGE_BITMAP, 0, 0,
                   LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE );
    
    		BITMAP bitmap;
    		GetObject(&hBitMap, sizeof(BITMAP), &bitmap);
    
    		long groesse =(bitmap.bmBitsPixel/8) * bitmap.bmWidth * bitmap.bmHeight; 
    
    		BYTE byte ;
    		GetBitmapBits( hBitMap, groesse,  &byte) ;
    
    		cout << bitmap.bmWidth << "\n";
    		cout << bitmap.bmHeight << "\n";
    		int x;
    		cin >>x;
    		return true;
    

    ich habe ein 128*128 Bitmap in diesem Ordner welches 1.bmp heißt. allerdings erhallte ich jetzt als Ausgabe

    4199396
    4206624

    Das ist ja nen bils zu viel 😉

    Ist also sonst noch was falsch?



  • Ich glaube CodeFinder hat unrecht.

    Versuch es mal so:

    int main() {
    
    	HBITMAP *phBitmap;
    	phBitmap= new HBITMAP;
    
    	BITMAP  bm;
       *phBitmap = NULL;
    
       *phBitmap = (HBITMAP)LoadImage( NULL, L"1.bmp", IMAGE_BITMAP, 0, 0,
                   LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE );
       if( *phBitmap == NULL )
       return FALSE;
    
       GetObject(*phBitmap, sizeof(BITMAP), &bm );
       cout << bm.bmHeight<< "\n";
    
       int x; 
       cin >>x; 
       return true;
    
    }
    

    Ich habe das auch nur durch rumprobieren rausgefunden.

    Was ich selbst nicht verstehe ist, warum man erst

    HBITMAP *phBitmap;
    

    und dann

    *phBitmap = NULL;
    

    schreibt.

    Lässt man das erste davon weg funktioniert es nicht, obwohl man den Zeiger dann auf NULL setzen kann 😕



  • LoadImage() gibt immer ein Handle zurück, nix mit Pointern?!

    Meine Vermutung:
    LR_CREATEDIBSECTION sorgt dafür das eine DIB erzeugt wird, demnach befüllt GetObject() keine BITMAP sondern ein DIBSECTION und wird vermutlich 0 zurückliefern weil es eine BITMAP statt DIBSECTION vorgeworfen bekommt.
    Prüf also mal den Rückgabewerte von GetObject()



  • Der erste Parameter von GetObject () ist der Wert einer Variablen und nicht seine Adresse :

    // GetObject(&hBitMap, sizeof(BITMAP), &bitmap);
    GetObject( hBitMap, sizeof(BITMAP), &bitmap);
    

    CodeFinder's Vorschlag ist völlig in Ordnung.
    🙂



  • Danke soweit.

    Der Code von Codefinder funzt leider nicht

    Der Code von Andreas XXL funzt

    Zumindest soweit, dass jetzt in bm.bmHeight der richtige Wert steht.

    Ich hbe es jetzt so:

    HBITMAP *phBitmap;
    	phBitmap= new HBITMAP;
    
    	BITMAP  bm;
       *phBitmap = NULL;
    
       *phBitmap = (HBITMAP)LoadImage( NULL, L"1.bmp", IMAGE_BITMAP, 0, 0,
                   LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE );
       if( *phBitmap == NULL )
       return FALSE;
    
       GetObject(*phBitmap, sizeof(BITMAP), &bm );
    
    		long groesse =(bm.bmBitsPixel/8) * bm.bmWidth * bm.bmHeight; 
    
    		BYTE byte ;
    		GetBitmapBits(*phBitmap, groesse,  &byte) ;
    
    		cout << byte; 
    
    		int x;
    		cin >> x;
    

    Allerdings bekomme ich jetzt als Ausgabe nen komisches Zeichen.
    Wie komme ich an die ganzen Werte in Byte?

    Oder muß ich als Byte nen Arry der groesse "groesse" angeben.



  • @CodeFinder
    @merker
    @geeky

    Hier ist es auch so gemacht wie in meiner Version.
    http://support.microsoft.com/kb/158898/de
    Die andere funktioniert wirklich nicht, nur Bill Gates weiß warum 😃



  • Sorry, falscher Post -- gelöscht



  • Alle haben recht.

    Die Version von Codefinder läuft tatsächlich nicht mit Visual c++ 6.0,
    mit dem neuen Visual c++ Express schon. (Sehr komisch)

    Mit dem neuen Visual c++ laufen beide Versionen. Ich nehme jetzt die von
    CodeFinder.

    Es sieht also so aus:

    int main() {
    
    HBITMAP phBitmap;
    
    BITMAP  bm;
    
       phBitmap = (HBITMAP)LoadImage( NULL, L"1.bmp", IMAGE_BITMAP, 0, 0,
                   LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE );
    
    		GetObject(phBitmap, sizeof(BITMAP), &bm );
    
    		long groesse =(bm.bmBitsPixel/8) * bm.bmWidth * bm.bmHeight; 
    		BYTE *pBuffer = new BYTE[bm.bmWidthBytes * bm.bmHeight];
    		GetBitmapBits(phBitmap,bm.bmWidthBytes * bm.bmHeight,  &pBuffer) ;
    
    		cout << bm.bmBitsPixel << "\n" ;
    		cout << bm.bmWidth  << "\n";
    		cout << bm.bmHeight << "\n";
    
    		int x;
    		cin >>x;
    
    		for (int i=0; i< bm.bmWidthBytes * bm.bmHeight; i++) {
    			cout  << pBuffer[i] << "\n";
    		}
    
    		cin >>x;
    		return true;
    
    }
    

    Als Ausgabe erhalte ich
    24
    512
    512

    (Das scheint zu stimmen)

    Und dann nur noch

    =

    =

    =
    ...

    Was ist noch falsch?



  • GetBitmapBits erwartet als 3. Parameter einen Zeiger auf einen Puffer. Du übergibst aber die Adresse des Pufferzeigers.

    So sollte es aussehen:

    GetBitmapBits(phBitmap,bm.bmWidthBytes * bm.bmHeight,  pBuffer);
    

    Auch solltest du folgendes ändern:

    // alt:
    // cout  << pBuffer[i] << "\n";
    // neu (nach int casten):
    cout  << (int)pBuffer[i] << endl;
    

    sonst werden nur Zeichen für die Werte dargestellt.

    Und zum guten Schluß - wo wird der Speicher mit delete wieder freigegeben???


Anmelden zum Antworten