GetPixel()



  • CreateDIBSection, da kannst du direkt auf die Pixel zugreifen, ist allerdings schwieriger zu verwenden 😉



  • wenn ich das so machen würde mit der DibSection, dann ist das genauso schnell as ob ich normal ein bitmap anzeigen will?

    denn ich habe jetzt geschaft was ich machen wollte, und merke, das ist ungefair 100x langsammer als bitmaps an zu zeigen^^

    ich werde mal ein wenig googlen und schauen was es mit CreateDibSection so auf sich hat 🙂

    werde mich wieder melden wenn ich fragen hab!!

    danke!!!



  • Entschuldigt, aber ich finde eine menge bei google, aber leider nix was mir hilft 😞

    Könnte mir jemand das erklären ?



  • In der FAQ wird eine DIB-Section z.B. zum Bitmap speichern benutzt:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-39400.html

    ...da allerdings um an die Pixeldaten ranzukommen um sie weg zu schreiben, nicht um sie zu setzen 😉

    Im Prinzip sagst du, welches Format deine Bitmap haben soll (Farbtiefe, Größe, etc.), rufst dann CreateDIBSection() auf und bekommst da bei dibvalues einen Zeiger auf den Speicher wo die Pixeldaten liegen.

    Ich empfehle dir biBitCount auf 32 zu setzen, und biCompression=BI_RGB, sowie biHeight= minus gewünschte Höhe.

    negative Höhe, hat auf die tatsächliche Höhe keine Auswirkung, sagt aber das in den dibvalues die linkere obere Ecke der Bitmap auch sofort am Anfang steht. Bei positiver Höhe, wäre der oberste linke Pixel ganz am Ende 😉

    Dank biBitCount=32 ersparst du dir Scanline-Rumrechnerei.

    Die einzelnen Pixel liegen dann Zeilweise in dibvalues drin. (R,G,B und ein ungenutzer Byte. Ich meine die lagen allerdings in anderer Reihenfolge drin, B,G,R,ungenutzt oder so)

    Nähere Details und Infos liegen verstückelt in der msdn rum 😉
    z.B. hier: http://msdn2.microsoft.com/en-us/library/ms532317.aspx



  • das habe ich schon gefunde, aber hilft mir leider nicht weiter 😞

    Das ist viel zu viel spanisch für mich ...

    Ich suche eher was was sich auf das wesentliche beschränkt, keine methoden kassen oder ähnliches benutzt, mag ich net^^

    ich versuche mich mal durch den code durchzu beissen, würde mich aber freuen wenn du was kennst was schön übersichtilich und einfach aufgebaut ist kennst 🙂

    Nochmals danke!



  • Showball schrieb:

    das habe ich schon gefunde, aber hilft mir leider nicht weiter 😞

    Das ist viel zu viel spanisch für mich ...

    Ich suche eher was was sich auf das wesentliche beschränkt, keine methoden kassen oder ähnliches benutzt, mag ich net^^

    ich versuche mich mal durch den code durchzu beissen, würde mich aber freuen wenn du was kennst was schön übersichtilich und einfach aufgebaut ist kennst 🙂

    Nochmals danke!

    da wirst du nicht drumherum kommen.. das ist schon einfach erklärt...



  • Also, ich möchte bloß die pixel anzeigen, wie lange das laden des bitmaps dauert ist mir eal, ich will bloß inen pixel so schnell zeichnen wie es geht, mir kommt das so vor als ob man damit läd, aber nicht anzeigt.

    Ich möcte kein bitmap anzigen sondern pixel ...
    😕



  • Bei einem einzigen Pixel wird SetPixel() wohl schnell genug sein 😉

    Bei vielen Pixeln ist die Nutzung einer DIB-Section zusammen mit BitBlt() oder SetDIBits() definitiv deutlich schneller.



  • Ja aber ich verstehe das irgent wie net, ich zeichne momentan 800x600 pixel mit setpixel()

    Wie zeichne ich aber jeden pixel einzelnd mit der dibsection ?



  • Beim erzeugen der DIB-Section bekommst du halt einen Zeiger auf den Speicher wo die Pixel alle hintereinander liegen. Die kannst du da einfach direkt manipulieren.

    Die DIB-Section selbst lässt sich genauso verwenden wie ne normale Bitmap (SelectObject, BitBlt, etc.) nur hast du halt direkten Zugriff auf den Speicherbereich wo die einzelnen Pixel liegen.



  • Irgentwie verstehe ich das immer noch net^^

    Also, ich versuche mal zu erklären was mein programm eigentlich macht.

    1. Ich lade ein bitmap
    2. speichere alle pixel des bitmaps in einer arrayvariable vom typ colorref
    3. Nun zeige ich jeden pixel an, das sieht bei mir momentan so aus:

    for (int i = 0; i < 800; i++)
    		{
    			for (int j = 0; j < 600; j++)
    			{
    
    	   SetPixel (hdc, i, j, buffer[i][j]) ;
    
    			}
    }
    

    Dies passiert nun 100 mal die sekunde, man kann sich vorstellen, das das gewisse problematiken bereitet.

    Also, ich will kein bild laden oda so, ich hantiere auch nichmehr mit dem bild herum, sondern ich handtiere nurnoch mit dem coloref herum, mit einer variable halt.

    Nur das anzeigen macht problehme, das anzeigen der einzelnen pixel 😕

    Ich suche ganz einfach in schnellere funktion als diese hier:
    SetPixel (hdc, i, j, buffer[i][j]) ;

    mit bitbtl oda so habe ich in der anwendung nix am hut, zeichne bloß pixel.

    oda habe ich da jetzt irgentwas falsch verstanden?



  • Bitte helft mir, ich finde bei google einfach nix da zeigen die komplette bitmaps immer nur an, ich will einfach nur pixl anzeigen, keine bitmaps 😞



  • SetPixel() ist nunmal lahmarschig (dafür wird die Änderung aber auch nach jedem SetPixel sofort sichtbar) 😉

    Der Weg über eine Bitmap ist nunmal deutlich schneller.
    Du setzt die Pixel direkt im Speicher ohne Umwege und kannst die ganzen gesetzten Pixel dann in einem Rutsch dank BitBlt() anzeigen.

    Es gibt nichts wirklich anderes in der WinAPI.



  • Jetzt nehmen wir mal an ich will daraus mal ein mini 2d game machen, ist das möglich, also das das bild nicht mehr flackert etc?

    Langsamm fange ich an zu verstehen, aber noch nicht ganz 😞

    Ist di anzeige geschwindigkeit dann genauso schnell als ob ich ein normales bitmap normal anzeige oder schneller?

    Ich frage das nur ungerne, aber könntest du ein codebeispiel senden?
    Ich komme da einfach nicht weiter 😞



  • Es flackert auf jedenfall deutlich weniger als bei SetPixel() (es sei denn du nutzt BackBuffer, dann tut sich in beiden Fällen da nichts)

    Pixel-setzen bei ner DIB-Section und BitBlt zusammen dauert sehr sehr sehr viel weniger als SetPixel. Bei sagen wir 800x600 ist SetPixel() schon derbst bescheiden.

    Wenn du ein Spiel machst: Wozu musst du da einzelne Pixel setzen?! Wenn du da ne Figur oder so über den Bildschirm wandern lassen willst, würde ich eher die Person in ne Bitmap klatschen und Hintergrund etc. jeweils ne Bitmap und das ganze jeweils direkt via BitBlt(), TransparentBlt(), AlphaBlend() oder so auf den Bildschirm pappen.
    Bei BitBlt() muss 'quasi' nur kopiert werden, das geht selbst bei größeren Bildern noch ratz-fatz.

    Aber für Spiele lohnt sich wohl eher SDL oder speziell bei 2D-Spielen das gute alte DirectDraw 😉

    (Quellcode habe ich keinen (mehr) da, bin auf C# umgestiegen)



  • Ich werde es nie kapieren ...



  • So, mal Flugs anhand der msdn gebaut - unkontrolliert und vermutlich fehlerhaft:

    HBITMAP aBmp;			// Handle der DIB
    BITMAPINFO bi;			// BITMAPINFO-Struktur
    BITMAPINFOHEADER bmih;	// BITMAPINFOHEADER-Struktur
    char *dibvalues;		// Zeiger auf die Pixeldaten
    
    // Eigenschaften der zu erzeugenden DIB-Section setzen:
    ZeroMemory(&bmih,sizeof(BITMAPINFOHEADER));
    bmih.biSize=sizeof(BITMAPINFOHEADER);
    bmih.biHeight=-480;	// Höhe der Bitmap 480, negatives Vorzeichen: Oberstes linkes Pixel=erste Pixel in dibvalues
    bmih.biWidth=640;	// Breite der Bitmap 640 Pixel
    bmih.biPlanes=1;	// Ist irgendwie immer 1 ;D
    bmih.biBitCount=32;	// Ein Pixel besteht aus 32 Bits (8 Bit rot, 8 Bit grün, 8 Bit blau, 8 Bit ungenutzt)
    bmih.biCompression=BI_RGB;   // BI_RGB = nicht komprimiert
    
    // BITMAPINFO-Struktur (wird von CreateDIBSection() benötigt)
    // hat 2 Member, einen für die Palette, welche wir nicht benutzen und die BITMAPINFOHEADER-Struktur ist eingebettet:
    bi.bmiHeader=bmih;
    
    // Bei DIB_RGB_COLORS holt sich CreateDIBSection Paletteninfos auf dem hdc das wir übergeben, wir nehmen mal den hdc vom Desktop:
    HDC hdc=GetDC(NULL);
    
    // Das Ding hier erzeugt eine DIB-Section und liefert einen HBITMAP-Handle zurück.
    // In dibvalues speichert die Funktionen einen Zeiger auf den Speicherbereich wo die Pixel rumliegen
    aBmp=CreateDIBSection(hdc,&bi,DIB_RGB_COLORS,(void**)&dibvalues,NULL,NULL);
    
    // Kurz aufräumen:
    ReleaseDC(NULL,hdc);
    
    // Hat das überhaupt geklappt?
    if (aBmp==NULL)
    {
    	OutputDebugString("CreateDIBSection failed! \n");
    	return 0;
    }
    
    // Jetzt können wir munter Pixel setzen,
    // das hier entspricht quasi SetPixel()!
    // hier als Beispiel an der Stelle (x/y)
    // Ich bin mir nicht sicher aber ich glaube rot,grün,blau,ungenutzt entspricht nicht der hier stehende Reihenfolge
    // einfach mal rumprobieren.
    // Mit y*Breite*4+x*4 wird quasi die Position in dibvalues berechnet (hoffe ich)
    // Warum *4 ? Ein Pixel hatte 32 Bit!
    dibvalues[y*bmih.biWidth*4+x*4+0] = rotanteil des Pixels an der Stelle (x/y);
    dibvalues[y*bmih.biWidth*4+x*4+1] = grünanteil des Pixels an der Stelle (x/y);
    dibvalues[y*bmih.biWidth*4+x*4+2] = blauanteil des Pixels an der Stelle (x/y);
    dibvalues[y*bmih.biWidth*4+x*4+3] = ungenutzt ?;
    
    // ** Ab hier wird aBmp wie eine gewöhnliche Bitmap verwendet **
    
    // Erzeugen wir mal nen temporären DC:
    hdc=GetDC(NULL);
    HDC temp_hdc=CreateCompatibleDC(hdc);
    ReleaseDC(NULL,hdc);
    
    // Selektieren da wie bei anderen Bitmaps auch die Bitmap rein:
    HGDIOBJ OldObj=SelectObject(temp_hdc,aBmp);
    
    // ...und blitten die aufs Ziel-DC:
    BitBlt(ziel_hdc,0,0,640,480,temp_hdc,0,0,SRCCOPY); 
    
    // ...und natürlich aufräumen:
    SelectObject(temp_hdc,OldObj);
    DeleteObject(aBmp);
    DeleteDC(temp_hdc);
    

    Die DIB-Section braucht man dabei im Prinzip eigentlich nur 1x beim programmstart erzeugen und kann dann mit dibvalues die Pixel ändern wie man will, ist man fertig einfach nochmal BitBlt().



  • cool danke, die erklärungen sind sehr gut nun frage ich mich aber, wie kann ich nun die pixel setzen, ich zeige ja kein bitmap an sondern pixel, oder wie kann ich jetzt aus ainem coloref array ein bitmap machen sodass es auch angezeigt wird ?



  • Du hast das in buffer[i][j] liegen? j wäre bei mir y und i bei mir x?
    Dann offensichtlich so 😉

    for (int j=0; j<480; j++)
    {
        for (int i=0; i<640; i++)
        {
            dibvalues[j*bmih.biWidth*4+i*4+0] = GetRValue(buffer[i][j]);
            dibvalues[j*bmih.biWidth*4+i*4+0] = GetGValue(buffer[i][j]);
            dibvalues[j*bmih.biWidth*4+i*4+0] = GetBValue(buffer[i][j]);
        }
    }
    


  • lol danke 😃

    werde ich wenn ich zuhause bin gleich mal testen 🙂

    nochmals tausenden dank 🙂


Anmelden zum Antworten