Jump to content

Two GDI+ questions


Recommended Posts

1. Is there any udf using hardware acceleratation? Afaik gdi+ doesn't...

2. Using Help Examples, I've created gui window displaying desirable images... Everything works fine, with exception of horrible flickering every time I move window outside the borders of screen.

Image is "refreshing" every time WM_PAINT code is sent - which is pretty often when window is moving outside of screen.

Here's fragmentary sample code:

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

Opt('MustDeclareVars', 1)

    Local $hGUI, $hBMP, $hBitmap, $hGraphic

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

    ; Create GUI
    $hGUI = GUICreate("GDI+", 1000, 900)

    ; Initialize GDI+ library
    _GDIPlus_Startup ()

    ; Draw bitmap to GUI
    $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP ($hBMP)
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hGUI)

    GuiRegisterMsg($WM_PAINT, "PAINT_IT")
    GUISetState()

    Func PAINT_IT()
       _GDIPlus_GraphicsDrawImage ($hGraphic, $hBitmap, 0, 0)
    EndFunc

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

    ; Clean up resources
    _GDIPlus_GraphicsDispose ($hGraphic)
    _GDIPlus_ImageDispose ($hBitmap)
    _WinAPI_DeleteObject ($hBMP)

    ; Shut down GDI+ library
    _GDIPlus_ShutDown ()

So, my 2nd question is:

Is there any way to get rid of this flickering? Is there any window message code similar to WM_PAINT, but not as often called?

I thought for a while about GuiRegisterMsg("PAINT_IT", 250) solution - but then window - when moving - is not refreshing at all :|

Help me find the anwsers.

BR,

4gr

Link to comment
Share on other sites

I'm not too experienced with GDI+ (or much of anything else for that matter) but I think you should look up buffering on the forum. I think the idea is that you write your frame to a buffer and then that is written all at once.

Link to comment
Share on other sites

#Include <ScreenCapture.au3>

$hBitmap = _ScreenCapture_Capture('', 0, 0, 1000, 900)

GUICreate('GDI+', 1000, 900)
GUICtrlCreatePic('', 0, 0, 1000, 900)
GUICtrlSendMsg(-1, 0x0172, 0, $hBitmap)
GUISetState()

Do
Until GUIGetMsg() = -3

Link to comment
Share on other sites

jaberwocky:

Thank you for tip.

Yashied:

Thanbks for help, but GUICtrlCreatePic is not an option here, because I need to create .png images, and Pic can't display them.

Besides, ur sample doesn't even properly displays screenshot :|

Edited by 4ggr35510n
Link to comment
Share on other sites

Try this:

;Coded by UEZ
#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
Opt('MustDeclareVars', 1)
Opt("GUIOnEventMode", 1)
Global $hWnd, $hGraphic, $file, $hImage, $scale_factor
Global $iX, $iY

$file = FileOpenDialog("Select image to load", @ScriptDir, "Images (*.jpg;*.png;*.bmp)")
If @error Then Exit

_GDIPlus_Startup()

$hImage = _GDIPlus_ImageLoadFromFile($file)

$scale_factor = 1.0 ;1.00 = 100%, 1.25 = 125%

$iX = _GDIPlus_ImageGetWidth($hImage) * $scale_factor
$iY = _GDIPlus_ImageGetHeight($hImage) * $scale_factor

$hWnd = GUICreate("Display Image: " & $file & " (" & $iX & "x" & $iY & " -> " & $scale_factor * 100 & "%)!", $iX, $iY)
GUISetState()

$hGraphic = _GDIPlus_GraphicsCreateFromHWND($hWnd)
_GDIPlus_GraphicsDrawImageRect($hGraphic, $hImage, 0, 0, $iX, $iY)

GUIRegisterMsg(0x000F, "WM_PAINT") ;$WM_PAINT = 0x000F
GUIRegisterMsg(0x0014 , "WM_ERASEBKGND") ;WM_ERASEBKGND = 0x0014

GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")

Do
Until Not Sleep(10000000)

Func _Exit()
    GUIRegisterMsg(0x000F, "")
    GUIRegisterMsg(0x0014, "")
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_Shutdown()
    Exit
EndFunc

Func WM_PAINT()
    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hImage, 0, 0, $iX, $iY)
    Return "GUI_RUNDEFMSG"
EndFunc ;==>WM_PAINT

Func WM_ERASEBKGND()
    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hImage, 0, 0, $iX, $iY)
    Return "GUI_RUNDEFMSG"
EndFunc

Or this with buffering:

;Coded by UEZ
#include <GDIPlus.au3>
#include <WindowsConstants.au3>

Opt("GUIOnEventMode", 1)
Opt('MustDeclareVars', 1)

Local $file = FileOpenDialog("Select image to load", @ScriptDir, "Images (*.jpg;*.png;*.bmp)")
If @error Then Exit

_GDIPlus_Startup()

Local $hImage = _GDIPlus_ImageLoadFromFile($file)
Local $iX = _GDIPlus_ImageGetWidth($hImage)
Local $iY = _GDIPlus_ImageGetHeight($hImage)

Local $hWnd = GUICreate("GDI+ Redraw Window", $iX, $iY)
GUISetState()
GUISetOnEvent(-3, "_Close")

_GDIPlus_Startup()
Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd)
Local $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iX, $iY, $hGraphics)
Local $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
_GDIPlus_GraphicsDrawImageRect($hGraphics, $hImage, 0, 0, $iX, $iY)


GUIRegisterMsg($WM_PAINT, "Draw")

While Sleep(30000)
WEnd

Func Draw()
    _GDIPlus_GraphicsDrawImageRect($hBackbuffer, $hImage, 0, 0, $iX, $iY)
    _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $iX, $iY)
EndFunc

Func _Close()
    GUIRegisterMsg($WM_PAINT, "")
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_GraphicsDispose($hBackbuffer)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()
    GUIDelete($hwnd)
    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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Yes, I did! I've just thanked him for it!

But it's still based on redrawing on wm_paint message.

Redrawing is much faster, so flickering is less noticable... But on older computers and bigger images - it's still there, hurting my eyes :[

When I create jpg images with GuiCtrlCreatePic - I don't even need to register functions on wm_paint = no redrawing = no flickering.

I was wondering is there any way to do same with png? Without redrawing, without flickering?

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...