Sign in to follow this  
Followers 0
4ggr35510n

Two GDI+ questions

9 posts in this topic

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

Share this post


Link to post
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.

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

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

Share this post


Link to post
Share on other sites

Please, help me solve this problem :blink:

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

Thank you UEZ so much!

But... is there any chance to draw image from png file that wouldn't disappeare at all when moved out of screen (like standard guictrlcreatepic from jpg file)?

Share this post


Link to post
Share on other sites

Did you try the "buffering" version of UEZ´s script?

Share this post


Link to post
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?

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