GetDIBits, falsche zeilenzahl?



  • Hi,.. ich will mittels GetDIBits mir die pixel informationen holen bearbeiten und unter einem seperaten handle ablegen.

    Das problem ist, das wenn ich die Anzahl der zeilen (von bmHeight) verwende returned die GetDIBits func mir ein 0 zurück,.. bei bmHeight-1 funktioniert dieses.

    Mir scheint dadurch eine Zeile verloren zu gehen??!!

    Hier der Komplette source:

    BOOL DrawMask(HDC hDC,INT x,INT y,HBITMAP hBitmap,HBITMAP *hMask,HWND hWnd, COLORREF color)
    {
    
    BYTE *data=NULL;
    DWORD sizeX;
    DWORD sizeY;
    bool NoErrors;	
    BITMAPINFO BMInfo; 
    HDC gldc = hDC; 
    NoErrors = false; 
    if(data != NULL) delete data; 
    BMInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 
    BMInfo.bmiHeader.biBitCount = 0; 
    int ret=GetLastError();
    GetDIBits(gldc, (HBITMAP)hBitmap, 0,0, NULL, &BMInfo, DIB_RGB_COLORS);
    int err=GetLastError();
    sizeX = BMInfo.bmiHeader.biWidth;
    sizeY = BMInfo.bmiHeader.biHeight; 
    BMInfo.bmiHeader.biBitCount = 24; 
    BMInfo.bmiHeader.biCompression = BI_RGB;
    const DWORD BitmapLength = sizeX * sizeY * 3; // 3 bytes (BGR) per pixel (24bp)
    data = new BYTE[BitmapLength]; 
    
    // hier ist die stelle
    int lines=GetDIBits(gldc, (HBITMAP)hBitmap, 0, sizeY-1, data, &BMInfo, DIB_RGB_COLORS);
    if(lines>0)
    
    {
    NoErrors = true;
    const DWORD BitmapLength = sizeX * sizeY * 3;
    BYTE Temp; // not quick but it works
    
    //wechsel BGR to RGB
    for(DWORD i=0; i< BitmapLength; i += 3)
    {
    Temp = data[i];
    data[i] = data[i+2];
    data[i+2] = Temp;
    }
    }
    
    COLORREF TempColor=0x00;
    BYTE Red=0x00;
    BYTE Blue=0x00;
    BYTE Green=0x00;
    for(DWORD i=0; i< BitmapLength; i+=3)
    {
    Red=data[i+2];
    Green=data[i+1];
    Blue=data[i];
    TempColor=RGB(Red,Green,Blue);
    
    BYTE gRValue=GetRValue(color);
    BYTE gGValue=GetGValue(color);
    BYTE gBValue=GetBValue(color);
    //plus 10%~25
    BYTE MinRed=0x00;
    BYTE MinGreen=0x00;
    BYTE MinBlue=0x00;
    if(gRValue>25){MinRed=gRValue-25;}else{MinRed=0x00;}
    if(gGValue>25){MinGreen=gGValue-25;}else{MinGreen=0x00;}
    if(gBValue>25){MinBlue=gBValue-25;}else{MinBlue=0x00;}
    
    BYTE MaxRed=0x00;
    BYTE MaxGreen=0x00;
    BYTE MaxBlue=0x00;
    if(gRValue<230){MaxRed=gRValue+25;}else{MaxRed=0xff;}
    if(gGValue<230){MaxGreen=gGValue+25;}else{MaxGreen=0xff;}
    if(gBValue<230){MaxBlue=gBValue+25;}else{MaxBlue=0xff;}
    
    if(((MaxRed>=Red)&&(MaxGreen>=Green)&&(MaxBlue>=Blue))&&((MinRed<=Red)&&(MinGreen<=Green)&&(MinBlue<=Blue)))
    {
    data[i]=0xff;
    data[i+1]=0xff;
    data[i+2]=0xff;
    }
    else
    {
    data[i]=0x00;
    data[i+1]=0x00;
    data[i+2]=0x00;
    }
    
    }}
    
    int error=GetLastError();
    *hMask=CreateCompatibleBitmap(gldc,BMInfo.bmiHeader.biWidth,BMInfo.bmiHeader.biHeight);
    SetDIBits(gldc,*hMask,0,sizeY-1,data,&BMInfo,DIB_RGB_COLORS);
    //DeleteObject(DIBHandle); // don't need the BMP Object anymore
    
    //DeleteObject(hDCBits);
    //DeleteObject(hDCMask);
    //ReleaseDC(hWnd,hDCBits);
    //ReleaseDC(hWnd,hDCMask);
    //ReleaseDC(hWnd,hDC);
    InvalidateRect(hWnd,NULL,TRUE);
    return NoErrors;
    

    Verbesserungsvorschläge sind gerne willkommen,... grüüüße



  • Hoi,.. das problem lag an der speicherallozierung 😃
    Habe also etwas mehr speicher der data var allociert und alles war bestens.

    Jetzt habe ich aber immer noch das problem, das die erzeugte Maske nicht wie gewünscht nur schwarz weiß ist sondern auch am rand von schwarz zu weiß häufig farbige pixel zu erkennen sind. Woher kommt das????

    grüüüße



  • Ohne mir den Code angesehen zu haben (was ist mit deiner Formatierung passiert? Rückst du gar nicht ein??), würde ich vermuten, dass deine farbigen Übergangspixel daher kommen, dass du beim schreiben irgendwie verrutscht bist. Wenn du also eben noch schwarz (0x00000000) geschrieben hast, und dann weiß (0x00ffffff) schreiben willst, entstehen da vermutlich Pixel wie 0x000000ff, weil du an der falschen Stelle aufsetzt. Könnte das sein?



  • Hi _matze,

    Wegen dem einrücken, naja,... noch ist es lesbar 😃

    ich habe mir mal die gespeicherten farbwerte (die masken bmp als file gespeichert) nochmal angeschaut,.. es sind insgesammt 4 verschiedene Farbwerte die entlang der grenzflächen entstehen,...

    Du scheinst damit recht zu haben das diese sich ein stück zu verschieben,...

    hier nochmal der entscheidene source:

    for(DWORD i=0; i< BitmapLength; i += 3){
    .
    .
    .
    if(((MaxRed>=Red)&&(MaxGreen>=Green)&&(MaxBlue>=Blue))&&((MinRed<=Red)&&(MinGreen<=Green)&&(MinBlue<=Blue)))
    {
    data[i]=0xff;
    data[i+1]=0xff;
    data[i+2]=0xff;
    }
    else
    {
    data[i]=0x00;
    data[i+1]=0x00;
    data[i+2]=0x00;
    }
    .
    .
    .
    }
    

    Da das aber ein 24 bit bitmap ist wüsste ich gerade nicht was ich da falsch machen würde,....

    Also links der grenzflächen ist immer ein blauanteil (manchmal auch ein grünanteil zusätzlich) vorhanden, rechts dagegen entweder nur Rot oder auch grün,...

    grüüüße



  • Ich habe das gerade nocheinmal mit einem bmp mit 300x300 probiert, dort funzt dieses einwandfrei. Das 300x300ter bild nutzt aber von anfang an nur 2 farben, bei 950x500 und mehreren kommt es zu dieser verschiebung,...

    ich werde mal weiter lookie lookie machen,..

    grüüße


Log in to reply