Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » VC++ / MFC » Bits per Pixel aus einem Bild auslesen

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
22.09.2005, 15:50 Uhr
Wiesenlieger



Hallo,

ich habe das Problem, daß ich, je nach Bittiefe meines geladenen Bildes, ein anderes Objekt für direkte Operationen auf dem Bild laden muß. Das Bild wird dabei einfach als Array von WORD oder DWORD (also 8 oder 16 Bit) betrachtet.
Gibt es eine Möglichkeit diese Bittiefe aus dem Header der Datei zu holen oder gibt es eine Funktion von CBitmap? Ich hab nichts gefunden.
Ich will vermeiden, daß der Nutzer das entscheiden muß.

Danke
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
22.09.2005, 16:08 Uhr
Tommix



Hallo,

C++:
//bitmap sei dein CBitmap
BITMAP bm;
bitmap.GetBitmap(&bm);
BYTE bits = bm.bmBitsPixel;



Gruß, Tommix
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
22.09.2005, 19:48 Uhr
Wiesenlieger



danke, danke,
aber, wenn ich es so versuche, wird kein bild in CBitmap geladen
und es stürzt mit einem assert ab:

C++:
    CFileDialog file(true, "bmp", m_sFileName, OFN_HIDEREADONLY |
        OFN_OVERWRITEPROMPT, "8bit-s/w-Bitmaps (*.bmp)|*.bmp|Alle Dateien (*.*)|*.*|");

    file.m_ofn.lpstrInitialDir    = m_sPath;
    file.m_ofn.lpstrTitle        = "wähle ein Bild";

    if ( file.DoModal() == IDOK)
    {
        CBitmap bitmap;
        bitmap.LoadBitmap( (LPCTSTR)file.GetPathName() );
        // Bits per pixel bestimmen
        BITMAP bm;
        bitmap.GetBitmap(&bm);
        BYTE bits = bm.bmBitsPixel;
        // noch mehr zu tun......................
    }

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
22.09.2005, 20:07 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


dann schau wo er abstürzt
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
22.09.2005, 20:48 Uhr
Wiesenlieger



stürzt ab bei:
bitmap.GetBitmap(&bm);
weil:
m_hObject = NULL

also hat er das bild nicht geladen.
obwohl file.GetPathName() den richtigen pfad zurückgibt
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
22.09.2005, 22:23 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


evtl kein gültiges Bitmap?
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
23.09.2005, 00:00 Uhr
Wiesenlieger



danke leute!

hab es letztendlich so gelöst:
...CBitmap unterstützt nur keine 16Bit Graustufen....
... muß ich mir noch was einfallen lassen


C++:
CFileDialog file(true, "bmp", m_sFileName, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
        "s/w-Bitmaps (*.bmp)|*.bmp|s/w Tagged Image File Format (*.tif)|*.tif|Alle Dateien (*.*)|*.*|");

    file.m_ofn.lpstrInitialDir    = m_sPath;
    file.m_ofn.lpstrTitle        = "wähle das 1. Bild der Sequenz";

    if ( file.DoModal() == IDOK)
    {
        CBitmap bitmap;
        // Die Bitmap-Datei laden
        HBITMAP hBitmap = (HBITMAP)::LoadImage(AfxGetInstanceHandle(),
            file.GetPathName(), IMAGE_BITMAP, 0, 0,
            LR_LOADFROMFILE | LR_CREATEDIBSECTION);
        // Das geladene Bild dem CBitmap-Objekt zuweisen
        bitmap.Attach(hBitmap);

        // Bits per pixel bestimmen
        BITMAP bm;
        bitmap.GetBitmap(&bm);
        BYTE bits = bm.bmBitsPixel;
               .........
               ...........

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
23.09.2005, 00:24 Uhr
CDW



Brauchst Du denn CBitmap noch für irgendwas? Du kannst auch bei wotsit.org die BMP Doku ziehen und relativ schnell selber den Header einlesen (und damit auch 24 bit BMPs laden ).
Hat den Vorteil dass diese Methode ungleich schneller ist, als GetPixel &Co
Ich kann auch einen Beispielcode geben (leider kein C++):


Code:
mov pBitmap,InputFile(addr skin_opt.back_path)
         mov ebx,pBitmap
         mov eax,dword ptr [ebx+12h]
         mov ecx,dword ptr [ebx+16h]
        
         mov einstellungen.background_breite,eax
         mov einstellungen.background_hoehe,ecx
        
         ;checken ob es auch ein 24 bitter ist
         add ebx,28
         .if byte ptr [ebx]!=18h
             invoke MessageBox,hWin,addr falsches_format,addr Fehler,MB_ICONERROR
             mov eax,FALSE            
             ret
         .endif
         ;jetzt Parsen um unsichbarbereiche zu erstellen:


also pBitmapt ist die in Memory (als File) gemappte Bitmap - einfach als Anfangszeiger auf den Speicher, wo sie liegt, betrachten.
In Anfangsspeicher+0x12 ist dann die Breite und im Anfagsspeicher+0x16 die Höhe.
Anfagsspeicher+28 (dezimal) die Farbtiefe.

Um die Bitmap wirlich auszulesen, muss man aber beachten, dass es so eine Art "auffülbytes" gibt.

folgendes gilt nur, wenn Du die Bitmap naitiv auslesen möchtest und nur für "bunte" (also mit mehr als 256 Farben, weil diese (256>= farbige) eine Farbpalette haben und nicht direkte Farbangaben und man hier die Doku dann doch lesen muss):
Wenn man die BMP Pixel für Pixel auslesen will, so ließt man z.B in einer Verschachtelten Forschleife die Pixels aus. Ich stelle mir das Bildlich so vor

Code:
.....X1..X2..X3
y1..23..45..2
y2..12..33..44
y3 usw


Also jeweils RGB Farbwert. Die Stellen rechnet man selber mit (bzw. wird ja in ein Array kopiert.
Die X Reihe wird dabei aufgefüllt:
Breite_der_BMP DIV 4 -> Rest==Auffüllzeichenmenge pro Zeile. Heißt im Klartext
dass man nach dem man seine Breite ausgelsenen hat (was weiß ich, bei einem BMP
von 200x100 wären das 200 Bytes) muss man dann diese Menge überspringen, bevor die
nächste Zeile beginng (sonst kommt nur mist raus).

Wo die Pixels im Speicher anfangen:
Anfagsspeicher+10 == Offset der Pixeldaten
also Anfangsspeicher+ Offset der Pixeldaten zusammenrechnen==Zeiger auf Pixeldaten.
die auszulesende größe ist dann: Breite mal Höhe + Rest(Breite/4)*Höhe
(ist aber egal, wenn man selber die zeilen zählt )
Die Bilddaten liegen übrigens in der BMP *auf dem Kopf* rum. Also nicht erschrecken, wenn das Bild andersrum angezeigt wird - einfach das Einlesen entsprechend anpassen
Ich hoffe es war nicht allzu verwirrend und erleichtert Dir vielleicht das lesen der Doku.


EDIT: warum nimmst Du für 8 Bit WORD und für 16 einen Dword? 8Bit sind ein Byte . Aber die Pixelfarbe an sich ist afiak auch 24 bit. Ein "256 Farben" BMP hat so weit ich weiß nur eine Palette mit 256 Farben - also eine Art Array. Die Farben jedoch sind "vollwertig". Bei 16-Bit auch. Also vielleicht lags daran, dass das Programm abgestürzt ist. Du brauchst auf jedenfall bei Pixelzugriff/Pixelkopie ein DWORD Array. Ich weiß es nicht mehr so genau, ob RGB jetzt wirlich nur 3 Bytes liefert - unter Windows und damit auf x86 Systemen dürfte es ein DWORD sein, weil es Architekturbediengt besseren Speicherzugriff bietet (im sinne von schnelleren)
--
EB FE

Dieser Post wurde am 23.09.2005 um 00:36 Uhr von CDW editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
23.09.2005, 18:21 Uhr
Wiesenlieger



Danke dir CDW,

das ist doch mal eine Info
Natürlich arbeite ich mit einem Byte für die 8Bit-Bilder - mein Fehler.
Das Problem ist aber, hab ich inzwischen entdeckt, dass es, afaik, kein 16Bit BMP gibt. Jedenfalls speichert das Programm, woher ich die bekomme,solche 16biter nur als Tiff.
...und da wird es wohl schwieriger.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ VC++ / MFC ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: