Jump to content

This site uses cookies. By continuing to browse the site you are agreeing to our use of cookies. Find out more here. X
X


Photo

Converting GDI+ Bitmap/Image to SDL Surface


  • Please log in to reply
5 replies to this topic

#1 AdmiralClaws

AdmiralClaws

    Here be dragons

  • Active Members
  • PipPipPipPipPipPip
  • 4,637 posts

Posted 12 October 2010 - 10:58 AM

Anyone else thinks it would be cool if you could move data between a bitmap and a surface?

It would be useful for both SDL and GDI+ users.

If you use SDL:
Load images from disc with GDI+ instead of big SDL_image.
There's one problem with this, per-pixel alpha. I don't know why but it's just solid black. I would be very grateful for any help on this!

If you use GDI+:
Use SDL to blit to screen.
SDL is faster, handles redrawing "automagically", and you doesn't need any "double-buffer template" to combat flickering.


Here's an example demonstrating loading images with GDI+ for usage in SDL. The second image uses alpha to show the problem above.
 

AutoIt         
#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseX64=n #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #Include <GDIPlus.au3> #Include "SDL.au3" Local $sFile1 = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt", "InstallDir") _     & "\Examples\GUI\msoobe.jpg"   ;Path to image1 Local $sFile2 = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt", "InstallDir") _     & "\Examples\GUI\Torus.png"   ;Path to image2 ;Initialize libraries _SDL_Init($_SDL_INIT_VIDEO)   ;initialize SDL _GDIPlus_Startup() $pScreen = _SDL_GuiCreate(StringTrimRight(@ScriptName, 4), 1024, 768, 32, $_SDL_SWSURFACE)   ;You can use zero on bbp and SDL will choose what it thinks is appropriate $hImage1 = _SDL_GDIPlus_ImageLoadFromFile($sFile1) _SDL_BlitSurface($hImage1, 0, $pScreen, 0) _SDL_FreeSurface($hImage1) $hImage2 = _SDL_GDIPlus_ImageLoadFromFile($sFile2) _SDL_BlitSurface($hImage2, 0, $pScreen, 0) _SDL_FreeSurface($hImage2) _SDL_Flip($pScreen) While 1     Sleep(10) WEnd Func _SDL_GDIPlus_ImageLoadFromFile($sFile)     $hImage = _GDIPlus_ImageLoadFromFile($sFile)     $iWidth = _GDIPlus_ImageGetWidth($hImage)     $iHeight = _GDIPlus_ImageGetHeight($hImage)     $Reslt = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iWidth, $iHeight, $GDIP_ILMREAD, $GDIP_PXF32ARGB)     $Scan0 = DllStructGetData($Reslt, "Scan0")     $pOldBitmap = _SDL_CreateRGBSurfaceFrom($Scan0, $iWidth, $iHeight, 32, $iWidth * 4, 0, 0, 0, 0)     $pNewSurface = _SDL_CreateRGBSurface($_SDL_SWSURFACE, $iWidth, $iHeight, 32, 0, 0, 0, 0)   ;If you set 0 for $iRmask, $iGmask, $iBmask, $iAmask it will be set to a default value     _SDL_BlitSurface($pOldBitmap, 0, $pNewSurface, 0)     _SDL_FreeSurface($pOldBitmap)     _GDIPlus_BitmapUnlockBits($hImage, $Reslt)     _GDIPlus_ImageDispose($hImage)     Return $pNewSurface EndFunc

And a quick example to show the extra speed you get with SDL:

AutoIt         
#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseX64=n #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #Include <GDIPlus.au3> #Include "SDL.au3" #include <WindowsConstants.au3> Opt("GUIOnEventMode", 1) Global $iBlittingMethod = 1, $asBlittingMethod[4] = ["", "SDL", "GDI+", "GDI+wSDL"] HotKeySet("{SPACE}", "_Next") Local $iWidth = 800, $iHeight = 600 $hGui = GUICreate(StringTrimRight(@ScriptName, 4), $iWidth, $iHeight, 0, 0) EnvSet("SDL_WINDOWID", $hGui) _SDL_Init($_SDL_INIT_VIDEO) _GDIPlus_Startup() $hScreenSurface = _SDL_SetVideoMode($iWidth, $iHeight, 32, $_SDL_SWSURFACE) $hScreenGraphics = _GDIPlus_GraphicsCreateFromHWND($hGui) $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hScreenGraphics) $hGraphics = _GDIPlus_ImageGetGraphicsContext($hBitmap) GUISetState() GUISetOnEvent(-3, "_Exit") Global $iLoopCurrent = 0 AdlibRegister("_FPS", 1000) Do     Switch $iBlittingMethod         Case 1             _SDL_FillRect($hScreenSurface, 0, Random(0, 0xFFFFFF, 1))             _SDL_Flip($hScreenSurface)         Case 2             $hBrush = _GDIPlus_BrushCreateSolid("0xFF" & Random(0, 0xFFFFFF, 1))             _GDIPlus_GraphicsFillRect($hScreenGraphics, 0, 0, $iWidth, $iHeight, $hBrush)             _GDIPlus_BrushDispose($hBrush)         Case 3             $hBrush = _GDIPlus_BrushCreateSolid("0xFF" & Random(0, 0xFFFFFF, 1))             _GDIPlus_GraphicsFillRect($hGraphics, 0, 0, $iWidth, $iHeight, $hBrush)             _GDIPlus_BrushDispose($hBrush)             $Reslt = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $iWidth, $iHeight, $GDIP_ILMREAD, $GDIP_PXF32ARGB)             $Scan0 = DllStructGetData($Reslt, "Scan0")             $pOldBitmap = _SDL_CreateRGBSurfaceFrom($Scan0, $iWidth, $iHeight, 32, $iWidth * 4, 0, 0, 0, 0)             _SDL_BlitSurface($pOldBitmap, 0, $hScreenSurface, 0)             _SDL_FreeSurface($pOldBitmap)             _GDIPlus_BitmapUnlockBits($hBitmap, $Reslt)             _SDL_Flip($hScreenSurface)     EndSwitch     $iLoopCurrent += 1 Until 0 Func _FPS()     WinSetTitle($hGui, "", "Rendering with: " & $asBlittingMethod[$iBlittingMethod] & " (" & $iLoopCurrent & " FPS)")     $iLoopCurrent = 0 EndFunc Func _Next()     $iBlittingMethod += 1     If $iBlittingMethod = 4 Then $iBlittingMethod = 1 EndFunc Func _Exit()     _SDL_Quit()     Exit EndFunc

If you don't have the SDL udf already, download it from HERE (you only need SDL.dll and SDL.au3 for the above code).


Edited by AdmiralAlkex, 22 June 2014 - 05:34 PM.

  • Xandy likes this







#2 Authenticity

Authenticity

    Universalist

  • MVPs
  • 2,619 posts

Posted 12 October 2010 - 01:21 PM

You can use SDL_SetColorKey, so you only need 24 bits image.

_SDL_SetColorKey($pNewSurface, $_SDL_SRCCOLORKEY, 0) _SDL_BlitSurface($pOldBitmap, 0, $pNewSurface, 0)


According to the documentation:

[RGBA]mask are the bitmasks used to extract that colour from a pixel. For instance, Rmask being FF000000 means the red data is stored in the most significant byte. Using zeros for the RGB masks sets a default value, based on the depth. (e.g. SDL_CreateRGBSurface(flags,w,h,32,0,0,0,0);) However, using zero for the Amask results in an Amask of 0.



#3 AdmiralClaws

AdmiralClaws

    Here be dragons

  • Active Members
  • PipPipPipPipPipPip
  • 4,637 posts

Posted 12 October 2010 - 05:48 PM

That's a neat trick, as long as you don't need anything between fully opaque and fully transparent ;)

It looks like this now:

AutoIt         
#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseX64=n #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #Include <GDIPlus.au3> #Include "SDL.au3" Local $sFile1 = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt", "InstallDir") _     & "\Examples\GUI\msoobe.jpg"   ;Path to image1 Local $sFile2 = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt", "InstallDir") _     & "\Examples\GUI\Torus.png"   ;Path to image2 ;Initialize libraries _SDL_Init($_SDL_INIT_VIDEO)   ;initialize SDL _GDIPlus_Startup() ;~ _MemTest()   ;Uncomment and look at task manager. "Private Working Set" does increase a few MB, but how often do you load 10K images normally?? :P $pScreen = _SDL_GuiCreate(StringTrimRight(@ScriptName, 4), 1024, 768, 32, $_SDL_SWSURFACE)   ;You can use zero on bbp and SDL will choose what it thinks is appropriate (but we want 32) $hImage1 = _SDL_GDIPlus_ImageLoadFromFile($sFile1) _SDL_BlitSurface($hImage1, 0, $pScreen, 0) _SDL_FreeSurface($hImage1) $hImage2 = _SDL_GDIPlus_ImageLoadFromFile($sFile2) _SDL_BlitSurface($hImage2, 0, $pScreen, 0) _SDL_FreeSurface($hImage2) _SDL_Flip($pScreen) While 1     Sleep(10) WEnd Func _SDL_GDIPlus_ImageLoadFromFile($sFile)     $hImage = _GDIPlus_ImageLoadFromFile($sFile)     $iWidth = _GDIPlus_ImageGetWidth($hImage)     $iHeight = _GDIPlus_ImageGetHeight($hImage)     $Reslt = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iWidth, $iHeight, $GDIP_ILMREAD, $GDIP_PXF32ARGB)     $Scan0 = DllStructGetData($Reslt, "Scan0")     $pOldBitmap = _SDL_CreateRGBSurfaceFrom($Scan0, $iWidth, $iHeight, 32, $iWidth * 4, 0, 0, 0, 0)     $pNewSurface = _SDL_CreateRGBSurface($_SDL_SWSURFACE, $iWidth, $iHeight, 32, 0, 0, 0, 0)   ;If you set 0 for $iRmask, $iGmask, $iBmask it will be set to a default value     _SDL_SetColorKey($pNewSurface, $_SDL_SRCCOLORKEY, 0)     _SDL_BlitSurface($pOldBitmap, 0, $pNewSurface, 0)     _SDL_FreeSurface($pOldBitmap)     _GDIPlus_BitmapUnlockBits($hImage, $Reslt)     _GDIPlus_ImageDispose($hImage)     Return $pNewSurface EndFunc Func _MemTest()     MsgBox(0, "", "Before array")     Local $apSurfaces[10000]   ;Uses about 1.4 GB memory     MsgBox(0, "", "Before loading")     For $iX = 0 To UBound($apSurfaces) -1         $apSurfaces[$iX] = _SDL_GDIPlus_ImageLoadFromFile($sFile2)     Next     MsgBox(0, "", "Before UNloading")     For $iX = 0 To UBound($apSurfaces) -1         _SDL_FreeSurface($apSurfaces[$iX])     Next     MsgBox(0, "", "After UNloading") EndFunc


Thank you Authenticity!

Edited by AdmiralAlkex, 16 October 2010 - 01:15 PM.


#4 JScript

JScript

    I'm back ... I miss, why not!

  • Active Members
  • PipPipPipPipPipPip
  • 1,176 posts

Posted 22 June 2014 - 04:37 PM

@AdmiralAlkex

Hello friend, the download link has problems, see:

Forbidden
You don't have permission to access /amax/autoit/SDL.zip on this server.
Additionally, a 403 Forbidden error was encountered while trying to use an ErrorDocument to handle the request.


JS
http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!)
Spoiler

dropbo10.pngDownload Dropbox - Simplify your life!
Your virtual HD wherever you go, anywhere!       


#5 AdmiralClaws

AdmiralClaws

    Here be dragons

  • Active Members
  • PipPipPipPipPipPip
  • 4,637 posts

Posted 22 June 2014 - 05:28 PM

@AdmiralAlkex

Hello friend, the download link has problems, see:

JS

 
Yes, unfortunately they discontinued their hosting service but I couldn't remember all the places where I linked to files on my site there. Thanks for telling me.
 
If it is okay for you, please download the full SDL UDF from HERE and you can extract the needed 2 files from there. If you prefer a smaller package (pay per MB internet?) then tell me and I will prepare a new small zip.



#6 JScript

JScript

    I'm back ... I miss, why not!

  • Active Members
  • PipPipPipPipPipPip
  • 1,176 posts

Posted 23 June 2014 - 09:04 AM

Thanks for your attention!
I've done the download, now I'm testing to see the possibilities of exchanging some functions
.

 

JS


http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!)
Spoiler

dropbo10.pngDownload Dropbox - Simplify your life!
Your virtual HD wherever you go, anywhere!       





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users