Sign in to follow this  
Followers 0
Andreik

GDIPlus Fill Shape

7 posts in this topic

#1 ·  Posted (edited)

Is there any way to fill a shape using GDI+ without using an array to store the polygon points, just based on a point (X,Y) inside the shape?

Edited by Andreik

When the words fail... music speaks

Share this post


Link to post
Share on other sites



I know only a GDI32 version to fill (flood) a shape ->

Br,

UEZ


Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Thanks for the link, there example work but when I tried to make work for my script don't work. What I do wrong?

#include <GDIPlus.au3>

_GDIPlus_Startup()
$MAIN = GUICreate("Europe Map",387,371)
$GRAPHIC = _GDIPlus_GraphicsCreateFromHWND($MAIN)
GUISetState(@SW_SHOW,$MAIN)

DrawMap($GRAPHIC,@ScriptDir & "\Europe.bmp")
FillArea($GRAPHIC,10,10,0xFF8000)

While True
    Switch GUIGetMsg()
        Case -3
            _GDIPlus_GraphicsDispose($GRAPHIC)
            _GDIPlus_Shutdown()
            Exit
    EndSwitch
    Sleep(10)
WEnd

Func DrawMap($GRAPHIC,$PATH)
    Local $IMG = _GDIPlus_ImageLoadFromFile($PATH)
    _GDIPlus_GraphicsDrawImageRect($GRAPHIC,$IMG,0,0,387,371)
    _GDIPlus_ImageDispose($IMG)
EndFunc

Func FillArea($GRAPHIC,$X,$Y,$COLOR)
    Local $DC = _GDIPlus_GraphicsGetDC($GRAPHIC)
    Local $BRUSH = _GDIPlus_BrushCreateSolid($COLOR)
    Local $OBJ = _WinAPI_SelectObject($DC,$BRUSH)
    DllCall("gdi32.dll","int","ExtFloodFill","int",$DC,"int",$X,"int",$Y,"int",PixelGetColor($X,$Y),"uint",1)
    _WinAPI_SelectObject($DC,$OBJ)
    _GDIPlus_BrushDispose($BRUSH)
EndFunc

EDIT:

It works in this way but I'm interesed if works with GDI+

$MAIN = GUICreate("Europe Map",387,371)
$MAP = GUICtrlCreatePic(@ScriptDir & "\Europe.bmp",0,0,387,371)
GUISetState(@SW_SHOW)
FillArea(ControlGetHandle($MAIN,"",$MAP),200,200,0xFF8000)

While 1
    Switch GUIGetMsg()
        Case -3
            Exit
    EndSwitch
    Sleep(10)
WEnd

Func FillArea($HWND,$X,$Y,$COLOR)
    $DC = DllCall("user32.dll","int","GetDC","hwnd",$HWND)
    $BRUSH = DllCall("gdi32.dll","long","CreateSolidBrush","int",$COLOR)
    $OBJ = DLLCall("gdi32.dll","int","SelectObject","int",$DC[0],"int",$BRUSH[0])
    DllCall("gdi32.dll","int","ExtFloodFill","int",$DC[0],"int",$X,"int",$Y,"int",0x00,"uint",0) ; border color
    DllCall("gdi32.dll","int","SelectObject","int",$DC[0],"int",$OBJ[0])
    DllCall("gdi32.dll","int","DeleteObject","int",$BRUSH[0])
EndFunc
Edited by Andreik

When the words fail... music speaks

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

You mean something like this?:

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#Include <Misc.au3>

Opt("GUIOnEventMode", 1)
Opt("MouseCoordMode",2)

Global $dll = DllOpen("user32.dll")

_GDIPlus_Startup()
Global $bitmap_from_file = _GDIPlus_BitmapCreateFromFile(@ScriptDir & '\Europe.bmp')

Global $width = _GDIPlus_ImageGetWidth ($bitmap_from_file)
Global $height = _GDIPlus_ImageGetHeight ($bitmap_from_file)

Global $hwnd = GUICreate("GDI32: Flood Fill Example", $width, $height)

GUISetOnEvent(-3, "Close")
GUISetState()

Global $hDC = _WinAPI_GetDC($hWnd)
Global $hGraphics = _GDIPlus_GraphicsCreateFromHDC($hDC)

_GDIPlus_GraphicsDrawImageRect($hGraphics, $bitmap_from_file, 0, 0, $width, $height)

Global $hBrush = DllCall("gdi32.dll", "long", "CreateSolidBrush", "int", 0xFF5050) ; fill color BGR
Global $obj_orig = DLLCall("gdi32.dll", "int", "SelectObject", "int", $hDC, "int", $hBrush[0])

While Sleep(50)

    If _IsPressed("01") And WinActive($hWnd) Then
        $mp = MouseGetPos()
        DllCall("gdi32.dll", "int", "FloodFill", "int", $hDC, "int", $mp[0], "int", $mp[1], "int", 0x000000)
    EndIf
WEnd

Func Close()
    DllClose($dll)
    DLLCall("gdi32.dll", "int", "SelectObject", "hwnd", $hwnd, "int", $obj_orig[0])
    DLLCall("gdi32.dll", "int", "DeleteObject", "int",$hBrush[0])
    _WinAPI_ReleaseDC($hWnd, $hDC)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()
    Exit
EndFunc

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

Yes, finally I could create the function FillMap() as I wanted. One more question: why CreateSolidBrush() cannot create a brush with alpha channel? I tried GdipCreateSolidFill() but didn't work, any idea how can I make it work?


When the words fail... music speaks

Share this post


Link to post
Share on other sites

This is the code I have, have anyone an ideea why I cannot create a brush using GDI+ UDF with alpha channel instead of CreateSolidBrush() function?

#include <GDIPlus.au3>

_GDIPlus_Startup()
$MAIN = GUICreate("Europe Map",790,590)
$MAP = GUICtrlCreatePic(@ScriptDir & "\Europe.bmp",0,0,790,590)
GUISetState(@SW_SHOW)
FillArea(ControlGetHandle($MAIN,"",$MAP),430,215,"00FF80","AA")

While 1
    Switch GUIGetMsg()
        Case -3
            _GDIPlus_Shutdown()
            Exit
    EndSwitch
    Sleep(10)
WEnd

Func FillArea($HWND,$X,$Y,$COLOR,$ALPHA)
    $DC = DllCall("user32.dll","int","GetDC","hwnd",$HWND)
;~  $BRUSH = _GDIPlus_BrushCreateSolid('0x' & $ALPHA & $COLOR)
    $BRUSH = DllCall("gdi32.dll","long","CreateSolidBrush","int",'0x' & $COLOR)
    $OBJ = DllCall("gdi32.dll","int","SelectObject","int",$DC[0],"int",$BRUSH[0])
    DllCall("gdi32.dll","int","ExtFloodFill","int",$DC[0],"int",$X,"int",$Y,"int",0,"uint",0)
    DllCall("gdi32.dll","int","SelectObject","int",$DC[0],"int",$OBJ[0])
    DllCall("gdi32.dll","int","DeleteObject","int",$BRUSH[0])
EndFunc

When the words fail... music speaks

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

My understanding is export functions from gdi32.dll use device contexts and 24 bits RGB or BGR colour format.

GDIPlus.dll export functions use handles to bitmaps and 32 bit ARGB colour format.

So I believe a 32 bit, GDIPlus brush is not compatiable, and can not be used with a 24 bit gdi32 device context of the type that is found in _WinAPI_SelectObject().

I would love to be proved wrong. Or maybe some clever work-around created by someone.

Edited by Malkey

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