Bildschirm in Graustufen/spiegeln/etc. bzw. Screenshot machen ohne Overlay

  • Hi,

    ich würde gerne das, was man auf dem Monitor sieht, mit GDI+ bearbeiten können. Also z.B. dass alles in Graustufen angezeigt wird.
    Wie man das fertige Bild am Ende über alles drüber legt, aber trotzdem noch alles verwenden kann, habe ich schon hier gefunden. Wie man mit GDI+ Bilder s/w macht steht ja auch schon in den GDI+ Beispielen.
    Das Problem ist jetzt, das man ja irgendwoher das Bild braucht, was man dann umwandeln kann. Das klappt einmal indem man einen Screenshot macht, aber danach würde man den ja nur noch von den umgewandelten angezeigten Bild machen. Also: Was tun?

    Ich wollte das übrigens nur zum Spaß machen, das hat bei mir keinen praktischen Nutzen.

    Rechtschreibfehler sind Spezialeffekte meiner Tastatur.

  • Hi,
    flackert etwas, wenn sich der Inhalt der Fenster "bewegt"

    Spoiler anzeigen
    [autoit]

    ;~ #include <AssembleIt2.au3>

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    #include <WinAPI.au3>

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    #cs graustufen
    use32 ;sollte immer eingesetzt werden!
    ;ret
    mov esi,dword[esp+4] ;Startadresse Bitmapdaten (Pixel)
    mov ecx,dword[esp+8] ;anzahl Pixel
    mov edi,21845 ;konstante, *21845/2^16 ist ungefähr 1/3

    [/autoit] [autoit][/autoit] [autoit]

    _schleife: ;so lange, bis ecx=0
    mov edx,[esi] ;pixel laden AARRGGBB (RR+GG+BB)/3 =farbe graustufe
    mov eax,0 ;eax=zur ermittlung des grautons = (RR+GG+BB)/3 =farbe graustufe
    mov al,dl ;lowbyte (BB) vom Pixel nach lowbyte al
    movzx bx,dh ;highbyte (GG) vom Pixel nach lowbyte von bx (bh ist 0)
    add ax,bx ;BB + GG
    shr edx,8 ;RR ins dh schieben
    movzx bx,dh ;highbyte (RR) vom Pixel nach lowbyte von bx (bh ist 0)
    add ax,bx ;und dazuzählen dx=RR+GG+BB
    mul edi ;*21845 *21845/2^16 ist ungefähr 1/3
    shr eax,16 ;/2^16 in al steht nun der farbcode (grauton) für RR, GG und BB
    add eax,1
    movzx dx,al ;grauton nach dl, in dh steht 0
    shl edx,16 ;grauton nach RR, in AA steht 0!
    mov dh,al ;grauton nach GG
    mov dl,al ;grauton nach BB In edx steht nun 00alalal=grauton
    mov [esi],edx ;pixel schreiben
    add esi,4
    loop _schleife ;so lange, bis ecx=0
    ret
    #ce

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $w = @DesktopWidth
    $h = @DesktopHeight

    [/autoit] [autoit][/autoit] [autoit]

    $binarycode = "0x8B7424048B4C2408BF555500008B16B80000000088D0660FB6DE6601D8C1EA08660FB6DE6601D8F7E7C1E81083C001660FB6D0C1E21088C688C2891683C604E2CCC3" ;code in Speicher schreiben
    Global $tCodeBuffer = DllStructCreate("byte[" & StringLen($binarycode) / 2 - 1 & "]") ;reserve Memory for opcodes
    DllStructSetData($tCodeBuffer, 1, $binarycode) ;write opcodes into memory

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $DC_desktop = _WinAPI_GetDC(0) ;DeviceContext GUI holen
    Global $ptr1, $hbmp1
    $DC_bmp = _CreateNewBmp32($w, $h, $ptr1, $hbmp1) ;leere Bitmap

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    While Sleep(10)
    _WinAPI_BitBlt($DC_bmp, 0, 0, $w, $h, $DC_desktop, 0, 0, 0xCC0020);DC in bitmap blitten
    ;$ret = _AssembleIt2("ptr", "graustufen", "ptr", $ptr1, "int", $w * $h) ;ptr als Rückgabe, um die hexzahlen schön zu sehen
    $ret = DllCallAddress("uint:cdecl", DllStructGetPtr($tCodeBuffer), "ptr", $ptr1, "int", $w * $h);bytecode aufrufen, rückgabe in a[0]
    _WinAPI_BitBlt($DC_desktop, 0, 0, $w, $h, $DC_bmp, 0, 0, 0xCC0020);bitmap in DC blitten
    WEnd

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;~ _DeleteBitmap32($DC_bmp, $ptr1, $hbmp1)
    ;~ Exit

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _CreateNewBmp32($iWidth, $iHeight, ByRef $ptr, ByRef $hbmp) ;erstellt leere 32-bit-Bitmap; Rückgabe $HDC und $ptr und handle auf die Bitmapdaten
    $hcdc = _WinAPI_CreateCompatibleDC(0) ;Desktop-Kompatiblen DeviceContext erstellen lassen
    $tBMI = DllStructCreate($tagBITMAPINFO) ;Struktur der Bitmapinfo erstellen und Daten eintragen
    DllStructSetData($tBMI, 1, DllStructGetSize($tBMI) - 4);Structgröße abzüglich der Daten für die Palette
    DllStructSetData($tBMI, 2, $iWidth)
    DllStructSetData($tBMI, 3, -$iHeight) ;minus =standard = bottomup
    DllStructSetData($tBMI, 4, 1)
    DllStructSetData($tBMI, 5, 32) ;32 Bit = 4 Bytes => AABBGGRR
    $adib = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBMI), 'uint', 0, 'ptr*', 0, 'ptr', 0, 'uint', 0)
    $hbmp = $adib[0] ;hbitmap handle auf die Bitmap, auch per GDI+ zu verwenden
    $ptr = $adib[4] ;pointer auf den Anfang der Bitmapdaten, vom Assembler verwendet
    _WinAPI_SelectObject($hcdc, $hbmp) ;objekt hbitmap in DC
    Return $hcdc ;DC der Bitmap zurückgeben
    EndFunc ;==>_CreateNewBmp32

    [/autoit] [autoit][/autoit] [autoit]

    Func _DeleteBitmap32($DC, $ptr, $hbmp)
    _WinAPI_DeleteDC($DC)
    _WinAPI_DeleteObject($hbmp)
    $ptr = 0
    EndFunc ;==>_DeleteBitmap32

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit]


    Ggf. könnte man eine "durchklickbare" GUI erstellen, auf die man den Desktopinhalt blittet, dann flackert auch nichts und man kann sämtliche Spielereien wie gespiegelten oder gedrehten Desktop implementieren

  • Cool das das funktioniert! Leider flackert es aber wirklich zu doll um das länger zu verwenden. Den Code verstehe ich auch überhaupt nicht :(. Und was ist "blitten"?

    Rechtschreibfehler sind Spezialeffekte meiner Tastatur.

  • Zitat

    Cool das das funktioniert!

    Wundert dich das, und wenn ja, warum?

    Zitat

    Leider flackert es aber wirklich zu doll um das länger zu verwenden.

    Wie gesagt, lass dir was einfallen...die Vorlage hast du!

    Zitat

    Den Code verstehe ich auch überhaupt nicht

    Der Code ist kommentiert! Was ist daran nicht zu verstehen? Man holt sich den DeviceContext vom Desktop, schreibt diesen in eine Bitmap, wandelt die farbigen Pixel in der Bitmap in Graustufen und blittet dann dieses Bitmap wieder auf den Desktop...

    Zitat

    Und was ist "blitten"?

    Du hast weder hier im Forum nach der Umwandlung von Farbe in Graustufen gesucht, noch bist du in der Lage, ein einfaches Wort in eine Suchmaschine deiner Wahl einzutippen! Wenn du nicht weißt wie man effektiv im Internet sucht, wieso fragst du dann nicht wie das geht?
    Eine der Möglichkeiten...