Jump to content

Inverting RGB, the second


Recommended Posts

As I already said in a post with the same name I don't have the problem to invert the RGB-information, but I need a faster way to do it. I have this program

$dll = DllOpen("Gdi32.dll")
$hwnd = DllCall("user32.dll", "hwnd", "GetActiveWindow")
$dc = DllCall("user32.dll", "hwnd", "GetDC", "hwnd", $hwnd[0])
For $i = 0 to @DesktopWidth 
    For $j = 0 to @DesktopHeight
        $rgb = DllCall($dll, "int", "GetPixel", "hwnd", $dc[0], "int", $i, "int", $j)
        $rgb[0] = BitNot("0x" & Hex($rgb[0]))
        DllCall($dll, "int", "SetPixel", "hwnd", $dc[0], "int", $i, "int", $j, "int", "0x00" & StringTrimLeft(Hex($rgb[0]), 2))
    Next
Next    
DllClose($dll)

It does basicially nothing else than getting every single pixel color and invert it, but as you might imagine, changing 1280x1024 pixel for example, takes quite long.

"weaponx" has already led my attention to a post from "Siao", thanks for this, but if I understood Siaos script right it can hardly help me. And because I don't wanted to spam the other RGB-invert topic furtheron I created my own, hoping anyone with more experience in GDI and GDIplus has any ideas.

Edited by CHronologist
Link to comment
Share on other sites

  • Moderators

If you use GetDibSection + BitBlt (with the invert option) + LockBits, it would be much faster. No time to write a demonstration script, but should be interesting to see what you come up with.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Well, heres my solution for the slowness, I created 4 scripts that would run at the same time, the first one does every other vertical collumn, the second one does the ones it missed, then the other two do the same except starting at the right of the screen, all four of them stop at the middle of the screen

but even so its still not fast enough to refresh XD

$dll = DllOpen("Gdi32.dll")
$hwnd = DllCall("user32.dll", "hwnd", "GetActiveWindow")
$dc = DllCall("user32.dll", "hwnd", "GetDC", "hwnd", $hwnd[0])
For $i = 0 to @DesktopWidth / 2 Step +2
    For $j = 0 to @DesktopHeight
        $rgb = DllCall($dll, "int", "GetPixel", "hwnd", $dc[0], "int", $i, "int", $j)
        $rgb[0] = BitNOT("0x" & Hex($RGB[0]))
        DllCall($dll, "int", "SetPixel", "hwnd", $dc[0], "int", $i, "int", $j, "int", "0x00" & StringTrimLeft(Hex($rgb[0]), 2))
    Next
Next    
DllClose($dll)

$dll = DllOpen("Gdi32.dll")
$hwnd = DllCall("user32.dll", "hwnd", "GetActiveWindow")
$dc = DllCall("user32.dll", "hwnd", "GetDC", "hwnd", $hwnd[0])
For $i = 1 to @DesktopWidth / 2 Step +2
    For $j = 0 to @DesktopHeight
        $rgb = DllCall($dll, "int", "GetPixel", "hwnd", $dc[0], "int", $i, "int", $j)
        $rgb[0] = BitNOT("0x" & Hex($RGB[0]))
        DllCall($dll, "int", "SetPixel", "hwnd", $dc[0], "int", $i, "int", $j, "int", "0x00" & StringTrimLeft(Hex($rgb[0]), 2))
    Next
Next    
DllClose($dll)

$dll = DllOpen("Gdi32.dll")
$hwnd = DllCall("user32.dll", "hwnd", "GetActiveWindow")
$dc = DllCall("user32.dll", "hwnd", "GetDC", "hwnd", $hwnd[0])
For $i = @DesktopWidth to @DesktopWidth / 2 + 1 Step - 2
    For $j = 0 to @DesktopHeight
        $rgb = DllCall($dll, "int", "GetPixel", "hwnd", $dc[0], "int", $i, "int", $j)
        $rgb[0] = BitNOT("0x" & Hex($RGB[0]))
        DllCall($dll, "int", "SetPixel", "hwnd", $dc[0], "int", $i, "int", $j, "int", "0x00" & StringTrimLeft(Hex($rgb[0]), 2))
    Next
Next    
DllClose($dll)

$dll = DllOpen("Gdi32.dll")
$hwnd = DllCall("user32.dll", "hwnd", "GetActiveWindow")
$dc = DllCall("user32.dll", "hwnd", "GetDC", "hwnd", $hwnd[0])
For $i = @DesktopWidth - 1 to @DesktopWidth / 2 +1 Step - 2
    For $j = 0 to @DesktopHeight
        $rgb = DllCall($dll, "int", "GetPixel", "hwnd", $dc[0], "int", $i, "int", $j)
        $rgb[0] = BitNOT("0x" & Hex($RGB[0]))
        DllCall($dll, "int", "SetPixel", "hwnd", $dc[0], "int", $i, "int", $j, "int", "0x00" & StringTrimLeft(Hex($rgb[0]), 2))
    Next
Next    
DllClose($dll)

[center]"When you look at old, classic games like Snake, you often put it off because it's such a simple game, but it's only when you actually try and create your own unique game from scratch, do you finally appreciate those games."[/center][center]Don't ask for answers if you haven't TRIED yet![/center][center]Most answers can be answered in the help file! Use it![/center]

Link to comment
Share on other sites

very creative solution, but I will try working on smoke_n 's idea, but it's quite hard to understand, because I just started working with GDI so if anyone has experience with those function let me know :P

Edited by CHronologist
Link to comment
Share on other sites

So this is now the next step. It can invert the screen colors within 300ms. Two problems left:

1) it's still to slow, but the way it works now will surely hold methods to speed up more

2) when looped, the color turns normal every second time or if windows are moved only parts turn nomal again, so the program has top redraw the screen everytim, what makes it slower again

have a look at it

HotKeySet("{Esc}", "_Exit")

While 1
    $hdc = _WinAPI_GetDC(0)
    $hcdc = _WinAPI_CreateCompatibleDC($hdc)
    $hcbmp =  _WinAPI_CreateCompatibleBitmap($hdc, @DesktopWidth, @DesktopHeight)
    _WinAPI_SelectObject($hcdc, $hcbmp)
    _WinAPI_BitBlt($hcdc, 0, 0, @DesktopWidth, @DesktopHeight, $hdc, 0, 0, $NOTSRCERASE) 
    _GDIPlus_Startup()
    $gc = _GDIPlus_GraphicsCreateFromHDC($hdc)
    $bmp = _GDIPlus_BitmapCreateFromHBITMAP($hcbmp)
    _GDIPlus_GraphicsDrawImageRectRect($gc, $bmp, 0, 0, @DesktopWidth, @DesktopHeight, 0, 0, @DesktopWidth, @DesktopHeight)
    _WinAPI_RedrawWindow(0, 0, 0, $RDW_INVALIDATE+$RDW_UPDATENOW+$RDW_ALLCHILDREN)
    _GDIPlus_GraphicsDispose($gc)
    _GDIPlus_ImageDispose($bmp)
    _GDIPlus_Shutdown()
    _WinAPI_ReleaseDC(0, $hdc)
    _WinAPI_DeleteDC($hcdc)
    _WinAPI_DeleteObject($hcbmp)
WEnd

Func _Exit()
    Exit
EndFunc

I mean, it's a really annoying effect now, but not what I intended :P

Edited by CHronologist
Link to comment
Share on other sites

Pretty cool effect. Very annoying though :P

Just increase anyone wanted to know the Includes to make this work....

#include <WinAPI.au3>
#include <GuiConstantsEx.au3>
#Include <GDIPlus.au3>
#include <WindowsConstants.au3>
Link to comment
Share on other sites

CHronologist

Nice! Little modify :P

#include <WinAPI.au3>
#Include <GDIPlus.au3>
#include <WindowsConstants.au3>

HotKeySet("{Esc}", "_Exit")

$hdc = _WinAPI_GetDC(0)
$hcdc = _WinAPI_CreateCompatibleDC($hdc)
    
While 1
    $hcbmp =  _WinAPI_CreateCompatibleBitmap($hdc, @DesktopWidth, @DesktopHeight)
    $hOldBMP = _WinAPI_SelectObject($hcdc, $hcbmp)
   
   _WinAPI_BitBlt($hcdc, 0, 0, @DesktopWidth, @DesktopHeight, $hdc, 0, 0, $NOTSRCERASE)
    
    _GDIPlus_Startup()
    $gc = _GDIPlus_GraphicsCreateFromHDC($hdc)
    $bmp = _GDIPlus_BitmapCreateFromHBITMAP($hcbmp)
    _GDIPlus_GraphicsDrawImageRectRect($gc, $bmp, 0, 0, @DesktopWidth, @DesktopHeight, 0, 0, @DesktopWidth, @DesktopHeight)
    
    ;_WinAPI_RedrawWindow(0, 0, 0, BitOR($RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_ALLCHILDREN))
    
    _GDIPlus_GraphicsDispose($gc)
    _GDIPlus_ImageDispose($bmp)
    _GDIPlus_Shutdown()
    
    _WinAPI_SelectObject($hOldBMP, $hcbmp)
    _WinAPI_DeleteObject($hcbmp)
    
    Sleep(100)
WEnd

Func _Exit()
    _WinAPI_ReleaseDC(0, $hdc)
    _WinAPI_DeleteDC($hcdc)
    _WinAPI_RedrawWindow(0, 0, 0, BitOR($RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_ALLCHILDREN))
    Exit
EndFunc
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...