Probleme mit der Umwandlung eines Bildes in ein monochromes Bild



  • Wenn ich ein normales Bild monochrom anzeigen will, wobei ich eine Farbe als Hintergrund definiere, während alle anderen Farben den Vordergrund darstellen, muß ich ja folgendes machen:

    CClientDC clientDC (this);
    CBitmap bmp, bmpMono;
    CDC dc, dcMono;
    BITMAP bm;
    
    bmp.LoadBitmap (IDB_BITMAP);
    dc.CreateCompatibleDC (&clientDC);
    dc.SelectObject (&bmp);
    
    bmp.GetBitmap (&bm);
    
    bmpMono.CreateBitmap (bm.bmWidth, bm.bmHeight, 1, 1, NULL);
    dcMono.CreateCompatibleDC (&clientDC);
    dcMono.SelectObject (&bmpMono);
    
    /*Übertragen des normalen Bildes in das monochrome,
      wobei die Farbe Rot als Hintergrundfarbe gilt.*/
    dc.SetBkColor (0xff);
    dcMono.BitBlt (0, 0, bm.bmWidth, bm.bmHeight, &dc, 0, 0, SRCCOPY);
    
    //Anzeigen des monochromen Bildes
    clientDC.BitBlt (0, 0, bm.bmWidth, bm.bmHeight, &dcMono, 0, 0, SRCCOPY);
    

    Jetzt ist es allerdings so, daß der Vordergrundbereich schwarz ist, während der Hintergrung weiß ist. Ich hätte es aber gern genau umgedreht: Das, was ursprünglich rot (Hintergrund) war, soll schwarz sein, während alles andere weiß ist. Und das bitte, ohne jeden Pixel mit SetPixel umzudrehen. Wer kann mir da helfen?

    Für alle die, die es interessiert, wieso ich das will:
    Wenn man Kollisionsabfrage von zwei Sprites überprüft, packt man ja den Bereich des Sprites, der sich mit dem anderen überschneidet, monochrom in ein Feld vom Typ BYTE, der dann pro Feldeintrag acht Pixel speichert. Und dann überprüft man die Feldeinträge per AND- oder OR-Verknüpfung. Wenn nun aber die Pixelanzahl nicht durch acht teilbar ist, schätze ich mal, daß er den Rest mit Nullen, die ja für schwarz stehen, auffüllt. Wenn nun schwarz für den Vordergrund steht, wird in dem Fall durch diese Rest-Bits eine Kollision erkannt, obwohl gar keine stattgefunden hat. Außerdem: Wenn ich auf Kollision überprüfe, wenn weiß (1) der Vordergrund ist, kann ich folgendes schreiben:

    for (i=0; i<Feldlänge (feld1) /*wie auch immer*/; i++)
        if (feld1 [i]&feld2 [i]!=0)
            return true;
    

    Wäre jetzt schwarz (0) der Vordergrund, müßte ich es ja so schreiben:

    for (i=0; i<Feldlänge (feld1); i++)
        if (feld1 [i]|feld2 [i]!=255)
            return true;
    

    Und da ist die erste Version natürlich wesentlich eleganter.



  • P.S.: Mir ist natürlich klar, daß ich mal schnell durch das Feld durchrattern und jeden Eintrag mit

    feld [i]=~feld [i]
    

    umwandeln könnte. Aber ich würd gern wissen, ob es da etwas gibt, das das gleich innerhalb der Grafik so darstellt, wie ich es haben will.



  • Hat sich erledigt.

    Die Lösung:
    Um das monochrome Bild entsprechend andersherum zu erstellen, muß man einfach

    dcMono.BitBlt (0, 0, bm.bmWidth, bm.bmHeight, &dc, 0, 0, NOTSRCCOPY);
    

    schreiben.


Anmelden zum Antworten