Sign in to follow this  
Followers 0
Tolf

Set Get pixel color with GDI+

14 posts in this topic

Hi,

In my script, I use a GDI+ graphic and I want to get and set the colors of pixels (and not of rectangles or circles), but I don't know how I can do.

Do you have any ideas ?


My UDF : Array2D

Share this post


Link to post
Share on other sites



Hi,

In my script, I use a GDI+ graphic and I want to get and set the colors of pixels (and not of rectangles or circles), but I don't know how I can do.

Do you have any ideas ?

Look in help file about _GDIPlus_PenCreate.


When the words fail... music speaks

Share this post


Link to post
Share on other sites

Look in help file about _GDIPlus_PenCreate.

I've already tested it : _GDIPlus_PenCreate just defines the pen color and the pen width, but it doesn't set a pixel color.

My UDF : Array2D

Share this post


Link to post
Share on other sites

I've tested it, but in my script, I don't load a file but I use _WinAPI_CreateBitmap and I've :

AutoIT3.exe ended.rc:-1073741819
written on the console : AutoIt can't do _GDIPlus_BitmapLockBits.


My UDF : Array2D

Share this post


Link to post
Share on other sites

From gdi32.dll, we have SetPixel and GetPixel. Color format is 0xBBGGRR.

A search of the forum will show other examples of their use.

From gdiplus.dll, we have BitmapSetPixel and BitmapGetPixel. Color format is 0xAARRGGBB.

Could not find other examples on AutoIt forums

#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
#include <ScreenCapture.au3>

Opt('MustDeclareVars', 1)

_Main()

Func _Main()
    Local $hGUI, $hBMP, $hBitmap, $hGraphic, $hDC, $aRet, $iArgb

    ; Capture upper left corner of screen
    $hBMP = _ScreenCapture_Capture("", 0, 0, 400, 300)

    ; Create GUI
    $hGUI = GUICreate("GDI+", 400, 300)
    GUISetState()

    ; Initialize GDI+ library
    _GDIPlus_Startup()
    $hDC = _WinAPI_GetDC($hGUI)
    ; Draw bitmap to GUI
    $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBMP)
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    
    ;Using GDI+ BitmapSetPixel 
    For $x = 25 To 45
        For $y = 5 To 55
            GDIPlus_BitmapSetPixel($hBitmap, $x, $y, 0xFF0000FF)
        Next
    Next
    
    _GDIPlus_GraphicsDrawImage($hGraphic, $hBitmap, 0, 0)
    
    ; Using gdi32.dll GetPixel
    ;Used in forums search GetPixel
    $aRet = DllCall("gdi32.dll", "int", "GetPixel", "hwnd", $hDC, "int", 100, "int", 100)
    ConsoleWrite("GetPixel  = 0x" & Hex($aRet[0], 6) & @LF)
    
    ;Using GDI+ BitmapGetPixel
    $iArgb = GDIPlus_BitmapGetPixel($hBitmap, 100, 100)
    ConsoleWrite("$iArgb  = " & $iArgb & @LF)
    
    ; Using gdi32.dll SetPixel
    For $x = 5 To 15
        For $y = 5 To 35
            SetPixel($hGUI, $x, $y, "0x0000FF")
        Next
    Next
    
    ; Clean up resources
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_ImageDispose($hBitmap)
    _WinAPI_DeleteObject($hBMP)
    _WinAPI_ReleaseDC($hGUI, $hDC)

    ; Shut down GDI+ library
    _GDIPlus_Shutdown()

    ; Loop until user exits
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
EndFunc   ;==>_Main

;The GetPixel method gets the color of a specified pixel in this bitmap.
;GdipBitmapGetPixel(GpBitmap* bitmap, INT x, INT y, ARGB *color)
;
Func GDIPlus_BitmapGetPixel($hBitmap, $iX, $iY)
    Local $tArgb, $pArgb, $aRet
    $tArgb = DllStructCreate("dword Argb")
    $pArgb = DllStructGetPtr($tArgb)
    $aRet = DllCall($ghGDIPDll, "int", "GdipBitmapGetPixel", "hwnd", $hBitmap, "int", $iX, "int", $iY, "ptr", $pArgb)
    Return "0x" & Hex(DllStructGetData($tArgb, "Argb"))
EndFunc   ;==>GDIPlus_BitmapGetPixel

; Write pixel to screen
; Used in forums search SetPixel
;
Func SetPixel($handle, $x, $y, $color)
    Local $dc
    $dc = DllCall("user32.dll", "int", "GetDC", "hwnd", $handle)
    DllCall("gdi32.dll", "long", "SetPixel", "long", $dc[0], "long", $x, "long", $y, "long", $color)
    DllCall("user32.dll", "int", "ReleaseDC", "hwnd", 0, "int", $dc[0])
    Return 1
EndFunc   ;==>SetPixel

;The SetPixel method sets the color of a specified pixel in this bitmap.
;GdipBitmapSetPixel(GpBitmap* bitmap, INT x, INT y, ARGB color)
;
Func GDIPlus_BitmapSetPixel($hBitmap, $iX, $iY, $iArgb)
    Local $aRet
    $aRet = DllCall($ghGDIPDll, "int", "GdipBitmapSetPixel", "hwnd", $hBitmap, "int", $iX, "int", $iY, "dword", $iArgb)
    Return
EndFunc   ;==>GDIPlus_BitmapSetPixel

Hope this helps.

Share this post


Link to post
Share on other sites

From gdi32.dll, we have SetPixel and GetPixel. Color format is 0xBBGGRR.

A search of the forum will show other examples of their use.

From gdiplus.dll, we have BitmapSetPixel and BitmapGetPixel. Color format is 0xAARRGGBB.

Could not find other examples on AutoIt forums

#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
#include <ScreenCapture.au3>

Opt('MustDeclareVars', 1)

_Main()

Func _Main()
    Local $hGUI, $hBMP, $hBitmap, $hGraphic, $hDC, $aRet, $iArgb

    ; Capture upper left corner of screen
    $hBMP = _ScreenCapture_Capture("", 0, 0, 400, 300)

    ; Create GUI
    $hGUI = GUICreate("GDI+", 400, 300)
    GUISetState()

    ; Initialize GDI+ library
    _GDIPlus_Startup()
    $hDC = _WinAPI_GetDC($hGUI)
    ; Draw bitmap to GUI
    $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBMP)
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    
    ;Using GDI+ BitmapSetPixel 
    For $x = 25 To 45
        For $y = 5 To 55
            GDIPlus_BitmapSetPixel($hBitmap, $x, $y, 0xFF0000FF)
        Next
    Next
    
    _GDIPlus_GraphicsDrawImage($hGraphic, $hBitmap, 0, 0)
    
    ; Using gdi32.dll GetPixel
    ;Used in forums search GetPixel
    $aRet = DllCall("gdi32.dll", "int", "GetPixel", "hwnd", $hDC, "int", 100, "int", 100)
    ConsoleWrite("GetPixel  = 0x" & Hex($aRet[0], 6) & @LF)
    
    ;Using GDI+ BitmapGetPixel
    $iArgb = GDIPlus_BitmapGetPixel($hBitmap, 100, 100)
    ConsoleWrite("$iArgb  = " & $iArgb & @LF)
    
    ; Using gdi32.dll SetPixel
    For $x = 5 To 15
        For $y = 5 To 35
            SetPixel($hGUI, $x, $y, "0x0000FF")
        Next
    Next
    
    ; Clean up resources
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_ImageDispose($hBitmap)
    _WinAPI_DeleteObject($hBMP)
    _WinAPI_ReleaseDC($hGUI, $hDC)

    ; Shut down GDI+ library
    _GDIPlus_Shutdown()

    ; Loop until user exits
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
EndFunc   ;==>_Main

;The GetPixel method gets the color of a specified pixel in this bitmap.
;GdipBitmapGetPixel(GpBitmap* bitmap, INT x, INT y, ARGB *color)
;
Func GDIPlus_BitmapGetPixel($hBitmap, $iX, $iY)
    Local $tArgb, $pArgb, $aRet
    $tArgb = DllStructCreate("dword Argb")
    $pArgb = DllStructGetPtr($tArgb)
    $aRet = DllCall($ghGDIPDll, "int", "GdipBitmapGetPixel", "hwnd", $hBitmap, "int", $iX, "int", $iY, "ptr", $pArgb)
    Return "0x" & Hex(DllStructGetData($tArgb, "Argb"))
EndFunc   ;==>GDIPlus_BitmapGetPixel

; Write pixel to screen
; Used in forums search SetPixel
;
Func SetPixel($handle, $x, $y, $color)
    Local $dc
    $dc = DllCall("user32.dll", "int", "GetDC", "hwnd", $handle)
    DllCall("gdi32.dll", "long", "SetPixel", "long", $dc[0], "long", $x, "long", $y, "long", $color)
    DllCall("user32.dll", "int", "ReleaseDC", "hwnd", 0, "int", $dc[0])
    Return 1
EndFunc   ;==>SetPixel

;The SetPixel method sets the color of a specified pixel in this bitmap.
;GdipBitmapSetPixel(GpBitmap* bitmap, INT x, INT y, ARGB color)
;
Func GDIPlus_BitmapSetPixel($hBitmap, $iX, $iY, $iArgb)
    Local $aRet
    $aRet = DllCall($ghGDIPDll, "int", "GdipBitmapSetPixel", "hwnd", $hBitmap, "int", $iX, "int", $iY, "dword", $iArgb)
    Return
EndFunc   ;==>GDIPlus_BitmapSetPixeloÝ÷ Øz)zØb²¥¦Ïêº^b«r^rëyËeË
+Æî´ý½æjÖ¥zºè¯^h¶¬jëh×6#include <GDIPlus.au3>

_GDIPlus_Startup()

$h_bitmap = _WinAPI_CreateBitmap(150, 150, 1, 32)
$h_image = _GDIPlus_BitmapCreateFromHBITMAP($h_bitmap)
$h_graphic = _GDIPlus_ImageGetGraphicsContext($h_image)
_GDIPlus_GraphicsClear($h_graphic, 0xFFFFFFFF)

For $line = 20 To 40
    For $col = 10 To 110
        _GDIPlus_BitmapSetPixel($h_bitmap, $col, $line, 0xFF0000FF)
    Next
Next
_GDIPlus_ImageSaveToFile($h_image, "test.bmp")

_GDIPlus_Shutdown()

Func _GDIPlus_BitmapSetPixel($hBitmap, $iX, $iY, $iArgb)
    Local $aRet
    $aRet = DllCall($ghGDIPDll, "int", "GdipBitmapSetPixel", "hwnd", $hBitmap, "int", $iX, "int", $iY, "dword", $iArgb)
    Return
EndFunc

My UDF : Array2D

Share this post


Link to post
Share on other sites

What is the fatal error?

Share this post


Link to post
Share on other sites

#include <GDIPlus.au3>

_GDIPlus_Startup()

$h_bitmap = _WinAPI_CreateBitmap(150, 150, 1, 32)
$h_image = _GDIPlus_BitmapCreateFromHBITMAP($h_bitmap)
$h_graphic = _GDIPlus_ImageGetGraphicsContext($h_image)
_GDIPlus_GraphicsClear($h_graphic, 0xFFFFFFFF)

For $line = 20 To 40
    For $col = 10 To 110
        _GDIPlus_BitmapSetPixel($h_bitmap, $col, $line, 0xFF0000FF)
    Next
Next
_GDIPlus_ImageSaveToFile($h_image, "test.bmp")

_GDIPlus_Shutdown()

Func _GDIPlus_BitmapSetPixel($hBitmap, $iX, $iY, $iArgb)
    Local $aRet
    $aRet = DllCall($ghGDIPDll, "int", "GdipBitmapSetPixel", "hwnd", $hBitmap, "int", $iX, "int", $iY, "dword", $iArgb)
    Return
EndFuncoÝ÷ Ûú®¢×¯+aÆ®¶­sb6æ6ÇVFRfÇC´tDÇW2æS2fwC° ¥ôtDÇW5õ7F'GW ¢b33c¶ö&FÖÒõväô7&VFT&FÖSÂSÂÂ3"¢b33c¶öÖvRÒôtDÇW5ô&FÖ7&VFTg&öÔ$DÔb33c¶ö&FÖ¢b33c¶öw&2ÒôtDÇW5ôÖvTvWDw&746öçFWBb33c¶öÖvR¥ôtDÇW5ôw&746ÆV"b33c¶öw&2Âdddddddb ¤f÷"b33c¶ÆæRÒ#FòC f÷"b33c¶6öÂÒFò ôtDÇW5ô&FÖ6WEVÂb33c¶öÖvRÂb33c¶6öÂÂb33c¶ÆæRÂdcdb æW@¤æW@¥ôtDÇW5ôÖvU6fUFôfÆRb33c¶öÖvRÂgV÷C·FW7Bæ&×gV÷C² ¥ôtDÇW5ôÖvTF7÷6Rb33c¶öÖvR¥õväôFVÆWFTö&¦V7Bb33c¶ö&FÖ¥ôtDÇW5õ6WFF÷vâ ¤gVæ2ôtDÇW5ô&FÖ6WEVÂb33c¶&FÖÂb33c¶Âb33c¶Âb33c¶&v" Æö6Âb33c¶&W@ b33c¶&WBÒFÆÄ6ÆÂb33c¶vtDFÆÂÂgV÷C¶çBgV÷C²ÂgV÷C´vF&FÖ6WEVÂgV÷C²ÂgV÷C¶væBgV÷C²Âb33c¶&FÖÂgV÷C¶çBgV÷C²Âb33c¶ÂgV÷C¶çBgV÷C²Âb33c¶ÂgV÷C¶Gv÷&BgV÷C²Âb33c¶&v" &WGW&à¤VæDgVæ2³ÓÒfwCµôtDÇW5ô&FÖ6WEV

This seems to work on my xp.

Share this post


Link to post
Share on other sites

Try this:-

#include <GDIPlus.au3>

_GDIPlus_Startup()

$h_bitmap = _WinAPI_CreateBitmap(150, 150, 1, 32)
$h_image = _GDIPlus_BitmapCreateFromHBITMAP($h_bitmap)
$h_graphic = _GDIPlus_ImageGetGraphicsContext($h_image)
_GDIPlus_GraphicsClear($h_graphic, 0xFFFFFFFF)

For $line = 20 To 40
    For $col = 10 To 110
        _GDIPlus_BitmapSetPixel($h_image, $col, $line, 0xFF0000FF)
    Next
Next
_GDIPlus_ImageSaveToFile($h_image, "test.bmp")

_GDIPlus_ImageDispose ($h_image)
_WinAPI_DeleteObject ($h_bitmap)
_GDIPlus_Shutdown()

Func _GDIPlus_BitmapSetPixel($hBitmap, $iX, $iY, $iArgb)
    Local $aRet
    $aRet = DllCall($ghGDIPDll, "int", "GdipBitmapSetPixel", "hwnd", $hBitmap, "int", $iX, "int", $iY, "dword", $iArgb)
    Return
EndFunc   ;==>_GDIPlus_BitmapSetPixel

This seems to work on my xp.

thx, it works good !

My UDF : Array2D

Share this post


Link to post
Share on other sites

I cant get the alpha channel to work:(

When i change the alpha in the example above me to 00 or to 80 or anything else it will be ff on the output image. :/

Anyone got an solution for that?


Fuck 'em if they can't take a joke.

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

This is close. There is a problem with double painting of the GUI.

The saved image is fine.

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

Global $GuiSizeX = 300, $GuiSizeY = 300

$hGui = GUICreate("GDIPlus Example", $GuiSizeX, $GuiSizeY)
GUISetState()

_GDIPlus_Startup()
$hGraphicGUI = _GDIPlus_GraphicsCreateFromHWND($hGui)
$hBMPBuff = _GDIPlus_BitmapCreateFromGraphics($GuiSizeX, $GuiSizeY, $hGraphicGUI)
$hGraphic = _GDIPlus_ImageGetGraphicsContext($hBMPBuff)

;Graphics here

_GDIPlus_GraphicsClear($hGraphic, 0xFFEEEEEE)

For $line = 20 To 40
    For $col = 10 To 110
        _GDIPlus_BitmapSetPixel($hBMPBuff, $col, $line, 0xFFFF0000) ; Opaque
    Next
Next

For $line = 60 To 80
    For $col = 10 To 110
        _GDIPlus_BitmapSetPixel($hBMPBuff, $col, $line, 0x60FF0000)
    Next
Next

For $line = 100 To 120
    For $col = 10 To 110
        _GDIPlus_BitmapSetPixel($hBMPBuff, $col, $line, 0x20FF0000)
    Next
Next

;End of graphics

GUIRegisterMsg(0xF, "MY_PAINT"); Register PAINT-Event 0x000F = $WM_PAINT (WindowsConstants.au3)

_GDIPlus_GraphicsClear($hGraphicGUI, 0xFFEEEEEE)
_GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0)

_GDIPlus_ImageSaveToFile($hBMPBuff, "test.png")
ShellExecute("test.png")

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            _GDIPlus_GraphicsDispose($hGraphic)
            _GDIPlus_GraphicsDispose($hGraphicGUI)
            _WinAPI_DeleteObject($hBMPBuff)
            _GDIPlus_Shutdown()
            Exit
    EndSwitch
WEnd

;Func to redraw on PAINT MSG
Func MY_PAINT($hWnd, $msg, $wParam, $lParam)
    _GDIPlus_GraphicsClear($hGraphicGUI, 0xFFEEEEEE)
    _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0)
    Return $GUI_RUNDEFMSG
EndFunc ;==>MY_PAINT


Func _GDIPlus_BitmapSetPixel($hBitmap, $iX, $iY, $iArgb)
    Local $aRet
    $aRet = DllCall($ghGDIPDll, "int", "GdipBitmapSetPixel", "hwnd", $hBitmap, "int", $iX, "int", $iY, "dword", $iArgb)
    Return
EndFunc ;==>_GDIPlus_BitmapSetPixel

Edit: Added _GDIPlus_GraphicsClear($hGraphicGUI, 0xFFEEEEEE) to clear existing graphics of GUI, to prevent superimposing bitmap, $hBMPBuff, onto existing GUI, $hGui.

Edited by Malkey

Share this post


Link to post
Share on other sites

Thanks, worked like a charm! :D


Fuck 'em if they can't take a joke.

Share this post


Link to post
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
Sign in to follow this  
Followers 0