Fast ScanRegion (now very fast)

Share your advanced PureBasic knowledge/code with the community.
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Post by Flype »

nico wrote:; I made some modification to remove buffer.l[....] in the Structure REGIONDATA
; and allocate dynamically the buffer according to the image
that's exactly what disturbed me in the netmaestro's (very good) code because a (100 000 x 4 bytes) table can be too much imho...


very interesting piece of code.
thank you guys, it will be useful.
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Yes, that's good work. I meant to get around to doing that little job soon, as it's definitely better memory management. But job one was to get the thing working and the way I wrote it left it easiest to understand and debug during that phase. Thanks for covering that off for me, nico.
BERESHEIT
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Here's a final version with some cleanups, e.g. the separate structure declaration is no more necessary as RGNDATAHEADER covers what's needed for the allocatememory approach and the free's are grouped together near the end for better maintainability. Also nico is credited, thanks so much eesau and nico for helping to make this procedure kick the amazing ass that it does.

Code: Select all

ProcedureDLL GrabRegion(ImageID, transcolor) ; HBITMAP ImageID, COLORREF transcolor

  ;======================================================= 
  ;                                                      = 
  ;      Very fast bitmap -> region creator              = 
  ;                                                      = 
  ;      By netmaestro                                   =
  ;                                                      =
  ;      Contributors: eesau, nico                       =
  ;                                                      = 
  ;      June 26, 2007                                   = 
  ;                                                      = 
  ;======================================================= 

  Structure RGBTRIPLEC 
    rgbtBlue.c 
    rgbtGreen.c 
    rgbtRed.c 
  EndStructure 

  GetObject_(ImageID, SizeOf(BITMAP), @bmp.BITMAP) 
  Protected width       = bmp\bmWidth 
  Protected height      = bmp\bmHeight 
  Protected hVisibleRgn = CreateRectRgn_(0, 0, width, height) 
  Protected tred        = Red(transcolor) 
  Protected tgreen      = Green(transcolor) 
  Protected tblue       = Blue(transcolor) 
  
  BmiInfo.BITMAPINFOHEADER 
  With BmiInfo 
    \biSize         = SizeOf(BITMAPINFOHEADER) 
    \biWidth        = width 
    \biHeight       = -height 
    \biPlanes       = 1 
    \biBitCount     = 24 
    \biCompression  = #BI_RGB 
  EndWith    
  
  bytesperrow = 4*((3*width+3)/4) 

  *ColorBits = AllocateMemory(bytesperrow*height) 
  hDC   = GetWindowDC_(#Null) 
  iRes  = GetDIBits_(hDC, ImageID, 0, height, *ColorBits, @bmiInfo, #DIB_RGB_COLORS) 
  ReleaseDC_(#Null, hDC) 
  
  Structure_Max=(width*height*16)+SizeOf(RGNDATAHEADER) 
  *Buffer.RGNDATAHEADER=AllocateMemory(Structure_Max) 
  *rd.LONG=*Buffer+SizeOf(RGNDATAHEADER) 

  bufferloc = 0 : rectcount = 0 
  For y=0 To height-1 
    pxcount=0 
    For x=0 To bytesperrow-1 Step 3 
      *px.RGBTRIPLEC = *ColorBits + bytesperrow * y + x 
      If *px\rgbtRed=tred And *px\rgbtGreen=tgreen And *px\rgbtBlue=tblue 
        transcount = 1 : firsttrans = pxcount 
        While *px\rgbtRed=tred And *px\rgbtGreen=tgreen And *px\rgbtBlue=tblue And x <= bytesperrow-4 
          transcount+1 : pxcount+1 : x+3      
          *px = *ColorBits + bytesperrow * y + x 
        Wend 
        rectcount+1 
        *rd\l = firsttrans            : *rd+4 
        *rd\l = y                     : *rd+4 
        *rd\l = firsttrans+transcount : *rd+4 
        *rd\l = y+1                   : *rd+4 
      EndIf 
      pxcount+1 
    Next 
  Next 
  
  With *Buffer
    \dwSize         = SizeOf(RGNDATAHEADER) 
    \iType          = #RDH_RECTANGLES 
    \nCount         = rectcount 
    \nRgnSize       = rectcount * SizeOf(RECT) 
    \rcBound\left   = 0 
    \rcBound\top    = 0 
    \rcBound\right  = width 
    \rcBound\bottom = height 
  EndWith 
  
  RegionSize=SizeOf(RGNDATAHEADER)+(rectcount * SizeOf(RECT)) 
  hTransparentRgn = ExtCreateRegion_(#Null, RegionSize, *Buffer) 
  CombineRgn_(hVisibleRgn, hVisibleRgn, hTransparentRgn, #RGN_XOR) 
    
  FreeMemory(*Buffer) 
  FreeMemory(*ColorBits) 
  DeleteObject_(hTransparentRgn) 
  
  ProcedureReturn hVisibleRgn 
  
EndProcedure 
Tailbites flawlessly for a compiled lib for your collection. Also the command's final name is GrabRegion as that best implies that it's quick.
BERESHEIT
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Post by Flype »

just to say it's not unicode compatible because your structure RGBTRIPLEC uses .c fields.

if i were you i would do it this way (minor changes) :

Code: Select all

Macro UBYTE(byte)
  (byte & 255)
EndMacro

Structure RGBTRIPLEC
  rgbtBlue.b
  rgbtGreen.b
  rgbtRed.b
EndStructure

[...]
If UBYTE(*px\rgbtRed)=tred And UBYTE(*px\rgbtGreen)=tgreen And UBYTE(*px\rgbtBlue)=tblue
  While UBYTE(*px\rgbtRed)=tred And UBYTE(*px\rgbtGreen)=tgreen And UBYTE(*px\rgbtBlue)=tblue And x<=bytesperrow-4
  Wend
EndIf
[...]
and a mix of your region-code and layered-window...

Code: Select all

;========================================
;========================================
;========================================

#ULW_ALPHA = $2

Macro UBYTE(byte)
  (byte & 255)
EndMacro

ProcedureDLL GrabRegion(ImageID, transcolor) ; HBITMAP ImageID, COLORREF transcolor

  ;=======================================================
  ;                                                      =
  ;      Very fast bitmap -> region creator              =
  ;                                                      =
  ;      By netmaestro                                   =
  ;                                                      =
  ;      Contributors: eesau, nico                       =
  ;                                                      =
  ;      June 26, 2007                                   =
  ;                                                      =
  ;=======================================================

  Structure RGBTRIPLEC
    rgbtBlue.b
    rgbtGreen.b
    rgbtRed.b
  EndStructure

  GetObject_(ImageID, SizeOf(BITMAP), @bmp.BITMAP)
  
  Protected width       = bmp\bmWidth
  Protected height      = bmp\bmHeight
  Protected hVisibleRgn = CreateRectRgn_(0, 0, width, height)
  Protected tred        = Red(transcolor)
  Protected tgreen      = Green(transcolor)
  Protected tblue       = Blue(transcolor)
 
  BmiInfo.BITMAPINFOHEADER
  With BmiInfo
    \biSize         = SizeOf(BITMAPINFOHEADER)
    \biWidth        = width
    \biHeight       = -height
    \biPlanes       = 1
    \biBitCount     = 24
    \biCompression  = #BI_RGB
  EndWith   
 
  bytesperrow = 4*((3*width+3)/4)

  *ColorBits = AllocateMemory(bytesperrow*height)
  hDC   = GetWindowDC_(#Null)
  iRes  = GetDIBits_(hDC, ImageID, 0, height, *ColorBits, @bmiInfo, #DIB_RGB_COLORS)
  ReleaseDC_(#Null, hDC)
 
  Structure_Max=(width*height*16)+SizeOf(RGNDATAHEADER)
  *Buffer.RGNDATAHEADER=AllocateMemory(Structure_Max)
  *rd.LONG=*Buffer+SizeOf(RGNDATAHEADER)

  bufferloc = 0 : rectcount = 0
  For y=0 To height-1
    pxcount=0
    For x=0 To bytesperrow-1 Step 3
      *px.RGBTRIPLEC = *ColorBits + bytesperrow * y + x
      If UBYTE(*px\rgbtRed)=tred And UBYTE(*px\rgbtGreen)=tgreen And UBYTE(*px\rgbtBlue)=tblue
        transcount = 1 : firsttrans = pxcount
        While UBYTE(*px\rgbtRed)=tred And UBYTE(*px\rgbtGreen)=tgreen And UBYTE(*px\rgbtBlue)=tblue And x<=bytesperrow-4
          transcount+1 : pxcount+1 : x+3 : *px = *ColorBits + bytesperrow * y + x
        Wend
        rectcount+1
        *rd\l = firsttrans            : *rd+4
        *rd\l = y                     : *rd+4
        *rd\l = firsttrans+transcount : *rd+4
        *rd\l = y+1                   : *rd+4
      EndIf
      pxcount+1
    Next
  Next
 
  With *Buffer
    \dwSize         = SizeOf(RGNDATAHEADER)
    \iType          = #RDH_RECTANGLES
    \nCount         = rectcount
    \nRgnSize       = rectcount * SizeOf(RECT)
    \rcBound\left   = 0
    \rcBound\top    = 0
    \rcBound\right  = width
    \rcBound\bottom = height
  EndWith
 
  RegionSize=SizeOf(RGNDATAHEADER)+(rectcount * SizeOf(RECT))
  hTransparentRgn = ExtCreateRegion_(#Null, RegionSize, *Buffer)
  CombineRgn_(hVisibleRgn, hVisibleRgn, hTransparentRgn, #RGN_XOR)
   
  FreeMemory(*Buffer)
  FreeMemory(*ColorBits)
  DeleteObject_(hTransparentRgn)
 
  ProcedureReturn hVisibleRgn
 
EndProcedure 

;========================================
;========================================
;========================================

LoadImage(0, "c:\girl.bmp")

OpenWindow(0, 0, 0, ImageWidth(0), ImageHeight(0), "", #PB_Window_ScreenCentered|#PB_Window_BorderLess|#PB_Window_Invisible)

SetWindowLong_(WindowID(0), #GWL_EXSTYLE, GetWindowLong_(WindowID(0), #GWL_EXSTYLE) | #WS_EX_LAYERED)

SetWindowRgn_(WindowID(0), GrabRegion(ImageID(image), #White), #True)

hDC = StartDrawing(ImageOutput(0))
If hDC 
  If GetObject_(ImageID(Image), SizeOf(BITMAP), @bm.BITMAP)
    bf.BLENDFUNCTION\SourceConstantAlpha = 168
    UpdateLayeredWindow_(WindowID(0), 0, 0, @bm\bmWidth, hDC, @p.POINT, 0, @bf, #ULW_ALPHA)
  EndIf
  StopDrawing()
EndIf

HideWindow(0,#False)

StickyWindow(0, #True)

Repeat 
  Select WaitWindowEvent()
    Case #WM_KEYDOWN
      Break
    Case #WM_LBUTTONDOWN
      SendMessage_(WindowID(0), #WM_NCLBUTTONDOWN, #HTCAPTION, 0) 
  EndSelect
ForEver

End

;========================================
;========================================
;========================================
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

OK very good. The Character type's size changes with Unicode, doesn't it. Latest version:

Code: Select all

ProcedureDLL GrabRegion(ImageID, transcolor) ; HBITMAP ImageID, COLORREF transcolor 

  ;======================================================= 
  ;                                                      = 
  ;      Very fast bitmap -> region creator              = 
  ;                                                      = 
  ;      By netmaestro                                   = 
  ;                                                      = 
  ;      Contributors: eesau, nico, flype                = 
  ;                                                      = 
  ;      June 26, 2007                                   = 
  ;                                                      = 
  ;======================================================= 

  GetObject_(ImageID, SizeOf(BITMAP), @bmp.BITMAP) 
  
  Protected width       = bmp\bmWidth 
  Protected height      = bmp\bmHeight 
  Protected hVisibleRgn = CreateRectRgn_(0, 0, width, height) 
  Protected tred        = Red(transcolor) 
  Protected tgreen      = Green(transcolor) 
  Protected tblue       = Blue(transcolor) 
  
  BmiInfo.BITMAPINFOHEADER 
  With BmiInfo 
    \biSize         = SizeOf(BITMAPINFOHEADER) 
    \biWidth        = width 
    \biHeight       = -height 
    \biPlanes       = 1 
    \biBitCount     = 24 
    \biCompression  = #BI_RGB 
  EndWith    
  
  bytesperrow = 4*((3*width+3)/4) 

  *ColorBits = AllocateMemory(bytesperrow*height) 
  hDC   = GetWindowDC_(#Null) 
  iRes  = GetDIBits_(hDC, ImageID, 0, height, *ColorBits, @bmiInfo, #DIB_RGB_COLORS) 
  ReleaseDC_(#Null, hDC) 
  
  Structure_Max=(width*height*16)+SizeOf(RGNDATAHEADER) 
  *Buffer.RGNDATAHEADER=AllocateMemory(Structure_Max) 
  *rd.LONG=*Buffer+SizeOf(RGNDATAHEADER) 

  bufferloc = 0 : rectcount = 0 
  For y=0 To height-1 
    pxcount=0 
    For x=0 To bytesperrow-1 Step 3 
      *px.RGBTRIPLE = *ColorBits + bytesperrow * y + x 
      If *px\rgbtRed&$FF=tred And *px\rgbtGreen&$FF=tgreen And *px\rgbtBlue&$FF=tblue 
        transcount = 1 : firsttrans = pxcount 
        While *px\rgbtRed&$FF=tred And *px\rgbtGreen&$FF=tgreen And *px\rgbtBlue&$FF=tblue  And x<=bytesperrow-4 
          transcount+1 : pxcount+1 : x+3 : *px = *ColorBits + bytesperrow * y + x 
        Wend 
        rectcount+1 
        *rd\l = firsttrans            : *rd+4 
        *rd\l = y                     : *rd+4 
        *rd\l = firsttrans+transcount : *rd+4 
        *rd\l = y+1                   : *rd+4 
      EndIf 
      pxcount+1 
    Next 
  Next 
  
  With *Buffer 
    \dwSize         = SizeOf(RGNDATAHEADER) 
    \iType          = #RDH_RECTANGLES 
    \nCount         = rectcount 
    \nRgnSize       = rectcount * SizeOf(RECT) 
    \rcBound\left   = 0 
    \rcBound\top    = 0 
    \rcBound\right  = width 
    \rcBound\bottom = height 
  EndWith 
  
  RegionSize=SizeOf(RGNDATAHEADER)+(rectcount * SizeOf(RECT)) 
  hTransparentRgn = ExtCreateRegion_(#Null, RegionSize, *Buffer) 
  CombineRgn_(hVisibleRgn, hVisibleRgn, hTransparentRgn, #RGN_XOR) 
    
  FreeMemory(*Buffer) 
  FreeMemory(*ColorBits) 
  DeleteObject_(hTransparentRgn) 
  
  ProcedureReturn hVisibleRgn 
  
EndProcedure 
BERESHEIT
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

And a last final version incorporating *pointer.LONG instead of *pointer.RGBTRIPLE, resulting in a further speed increase of approx. 15-20% overall:

Code: Select all

ProcedureDLL GrabRegion(ImageID, transcolor) ; HBITMAP ImageID, COLORREF transcolor 

  ;======================================================= 
  ;                                                      = 
  ;      Very fast bitmap -> region creator              = 
  ;                                                      = 
  ;      By netmaestro                                   = 
  ;                                                      = 
  ;      Contributors: eesau, nico, flype                = 
  ;                                                      = 
  ;      June 26, 2007                                   = 
  ;                                                      = 
  ;======================================================= 

  GetObject_(ImageID, SizeOf(BITMAP), @bmp.BITMAP) 
  
  Protected width       = bmp\bmWidth 
  Protected height      = bmp\bmHeight 
  Protected hVisibleRgn = CreateRectRgn_(0, 0, width, height) 
  Protected tred        = Red(transcolor) 
  Protected tgreen      = Green(transcolor) 
  Protected tblue       = Blue(transcolor) 
  
  BmiInfo.BITMAPINFOHEADER 
  With BmiInfo 
    \biSize         = SizeOf(BITMAPINFOHEADER) 
    \biWidth        = width 
    \biHeight       = -height 
    \biPlanes       = 1 
    \biBitCount     = 32 
    \biCompression  = #BI_RGB 
  EndWith    
  
  rowbytes =  4*width

  *ColorBits = AllocateMemory(rowbytes*height) 
 
  hDC   = GetWindowDC_(#Null) 
  iRes  = GetDIBits_(hDC, ImageID, 0, height, *ColorBits, @bmiInfo, #DIB_RGB_COLORS) 
  ReleaseDC_(#Null, hDC) 
 
  Structure_Max=(width*height*16)+SizeOf(RGNDATAHEADER) 
  *Buffer.RGNDATAHEADER=AllocateMemory(Structure_Max) 
  *rd.LONG=*Buffer+SizeOf(RGNDATAHEADER) 

  bufferloc = 0 : rectcount = 0 
  For y=0 To height-1 
    pxcount=0 
    For x=0 To rowbytes-1 Step 4 
      *px.LONG = *ColorBits + rowbytes * y + x 
      If *px\l = transcolor  
        transcount = 1 : firsttrans = pxcount 
        While *px\l = transcolor And x<=rowbytes-5
          transcount+1 : pxcount+1 : x+4 : *px = *ColorBits + rowbytes * y + x 
        Wend 
        rectcount+1 
        *rd\l = firsttrans            : *rd+4 
        *rd\l = y                     : *rd+4 
        *rd\l = firsttrans+transcount : *rd+4 
        *rd\l = y+1                   : *rd+4 
      EndIf 
      pxcount+1 
    Next 
  Next 
  
  With *Buffer 
    \dwSize         = SizeOf(RGNDATAHEADER) 
    \iType          = #RDH_RECTANGLES 
    \nCount         = rectcount 
    \nRgnSize       = rectcount * SizeOf(RECT) 
    \rcBound\left   = 0 
    \rcBound\top    = 0 
    \rcBound\right  = width 
    \rcBound\bottom = height 
  EndWith 
  
  RegionSize=SizeOf(RGNDATAHEADER)+(rectcount * SizeOf(RECT)) 
  hTransparentRgn = ExtCreateRegion_(#Null, RegionSize, *Buffer) 
  CombineRgn_(hVisibleRgn, hVisibleRgn, hTransparentRgn, #RGN_XOR) 
    
  FreeMemory(*Buffer) 
  FreeMemory(*ColorBits) 
  DeleteObject_(hTransparentRgn) 
  
  ProcedureReturn hVisibleRgn 
  
EndProcedure 
transcolor is interpreted here with Blue as most significant, Red is least.
BERESHEIT
Hi-Toro
Enthusiast
Enthusiast
Posts: 269
Joined: Sat Apr 26, 2003 3:23 pm

Post by Hi-Toro »

Nice!
James Boyd
http://www.hi-toro.com/
Death to the Pixies!
User avatar
Michael Vogel
Addict
Addict
Posts: 2807
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Post by Michael Vogel »

Thanks netmaestro,

I think I've taken the latest latest of the latest versions now :wink:

Michael
User avatar
Michael Vogel
Addict
Addict
Posts: 2807
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Post by Michael Vogel »

Oops,

I've a small problem with the code, on my screen, some pixels on the left side disappear...

Made some graphics and the following code to demonstrate this...
- http://sudokuprogram.googlepages.com/Ziffern.bmp
- http://sudokuprogram.googlepages.com/ThermoX.bmp

Code: Select all

; Define
	Global temperatur=250

	Global WinID
	Global ZiffID
	Global WinDC

	#BOffX=32
	#BOffY=43
	#BWidth=9
	
	#ZiffX=11
	#ZiffY=14

	Enumeration
		#MainWindow
		#PopupMenu
		#MenuQuit
		#Image
		#BalkenOriginal
		#BalkenLeer
		#BalkenVoll
		#BalkenFein
		#Balken
		#Ziffern
		#Tacho
	EndEnumeration

	Enumeration 2000
		#TempMinus10
		#TempMinus1
		#TempPlus1
		#TempPlus10
	EndEnumeration

	CatchImage(#Image,?_Thermometer)
	CatchImage(#Ziffern,?_Ziffern)
	GrabImage(#Image,#BalkenOriginal,#BOffX,#BOffY,#BWidth,274)
	GrabImage(#Image,#Balken,#BOffX,#BOffY,#BWidth,274)
	GrabImage(#Image,#BalkenLeer,#BOffX,#BOffY,#BWidth,124)
	GrabImage(#Image,#BalkenFein,#BOffX,189,#BWidth,4)
	GrabImage(#Image,#BalkenVoll,#BOffX,193,#BWidth,130)
	GrabImage(#Image,#Tacho,16,374,41,24)

	DataSection
		_Thermometer: IncludeBinary "Data\ThermoX.bmp"
		_Ziffern: IncludeBinary "Data\Ziffern.bmp"
	EndDataSection

; EndDefine
ProcedureDLL GrabRegion(ImageID, transcolor)
	; Paramter: HBITMAP ImageID, COLORREF transcolor

	Structure RGBTRIPLEC
		rgbtBlue.c
		rgbtGreen.c
		rgbtRed.c
	EndStructure

	GetObject_(ImageID, SizeOf(BITMAP), @bmp.BITMAP)
	Protected width=bmp\bmWidth
	Protected height=bmp\bmHeight
	Protected hVisibleRgn=CreateRectRgn_(0,0,width,height)
	Protected tred=Red(transcolor)
	Protected tgreen=Green(transcolor)
	Protected tblue=Blue(transcolor)

	BmiInfo.BITMAPINFOHEADER
	With BmiInfo
		\biSize=SizeOf(BITMAPINFOHEADER)
		\biWidth=width
		\biHeight=-height
		\biPlanes=1
		\biBitCount=24
		\biCompression=#BI_RGB
	EndWith

	bytesperrow=4*((3*width+3)/4)
	*ColorBits=AllocateMemory(bytesperrow*height)
	hDC=GetWindowDC_(#Null)
	iRes=GetDIBits_(hDC, ImageID, 0, height, *ColorBits, @bmiInfo, #DIB_RGB_COLORS)
	ReleaseDC_(#Null, hDC)

	Structure_Max=(width*height*16)+SizeOf(RGNDATAHEADER)
	*Buffer.RGNDATAHEADER=AllocateMemory(Structure_Max)
	*rd.LONG=*Buffer+SizeOf(RGNDATAHEADER)
	bufferloc=0
	rectcount=0

	For y=0 To height - 1
		pxcount=0
		For x=0 To bytesperrow-1 Step 3
			*px.RGBTRIPLEC=*ColorBits+bytesperrow*y+x
			If *px\rgbtRed=tred And *px\rgbtGreen=tgreen And *px\rgbtBlue=tblue
				transcount=1
				firsttrans=pxcount
				While *px\rgbtRed=tred And *px\rgbtGreen=tgreen And *px\rgbtBlue=tblue And x <= bytesperrow - 4
					transcount+1
					pxcount+1
					x+3
					*px=*ColorBits+bytesperrow*y+x
				Wend
				rectcount+1
				*rd\l=firsttrans : *rd+4
				*rd\l=y : *rd+4
				*rd\l=firsttrans+transcount : *rd+4
				*rd\l=y+1 : *rd+4
			EndIf
			pxcount+1
		Next
	Next

	With *Buffer
		\dwSize=SizeOf(RGNDATAHEADER)
		\iType=#RDH_RECTANGLES
		\nCount=rectcount
		\nRgnSize=rectcount*SizeOf(RECT)
		\rcBound\left=0
		\rcBound\top=0
		\rcBound\right=width
		\rcBound\bottom=height
	EndWith

	RegionSize=SizeOf(RGNDATAHEADER)+(rectcount*SizeOf(RECT))
	hTransparentRgn=ExtCreateRegion_(#Null, RegionSize, *Buffer)
	CombineRgn_(hVisibleRgn, hVisibleRgn, hTransparentRgn, #RGN_XOR)

	FreeMemory(*Buffer)
	FreeMemory(*ColorBits)
	DeleteObject_(hTransparentRgn)

	ProcedureReturn hVisibleRgn

EndProcedure

Procedure Init()
	WinID=OpenWindow(#MainWindow,0,0,ImageWidth(#Image),ImageHeight(#Image),"", #PB_Window_ScreenCentered|#PB_Window_BorderLess|#PB_Window_Invisible)

	SetWindowLong_(WinID,#GWL_EXSTYLE,GetWindowLong_(WinID,#GWL_EXSTYLE)|#WS_EX_TOOLWINDOW)
	CreateGadgetList(WinID) ; Event windows without gadgets neeed a gadget list
	region=GrabRegion(ImageID(#Image),$ff00ff) ; Create the region for the included picture
	SetWindowRgn_(WinID, region, #True) ; Clip the image to the calculated region

	hBrush=CreatePatternBrush_(ImageID(#Image)) ; Set the window background to the image.
	SetClassLong_(WinID, #GCL_HBRBACKGROUND, hBrush) ; Subclass the window to allow dragging around

	AddKeyboardShortcut(#MainWindow,#PB_Shortcut_Escape,#MenuQuit)
	AddKeyboardShortcut(#MainWindow,#PB_Shortcut_Shift|#PB_Shortcut_Up,#TempPlus1)
	AddKeyboardShortcut(#MainWindow,#PB_Shortcut_Shift|#PB_Shortcut_Down,#TempMinus1)
	AddKeyboardShortcut(#MainWindow,#PB_Shortcut_Up,#TempPlus10)
	AddKeyboardShortcut(#MainWindow,#PB_Shortcut_Down,#TempMinus10)

	WinDC=GetDC_(WinID)
	ZiffID=CreateCompatibleDC_(WinDC)
	SelectObject_(ZiffID,ImageID(#Ziffern))

	StickyWindow(#MainWindow, 1) ; Make this window stay on top of all others
	HideWindow(#MainWindow, 0) ; Show the window now
EndProcedure
Procedure Main()
	Init()

	Repeat
		Select WaitWindowEvent(100)

		Case #WM_PAINT,#WM_NCPAINT
			y=270-temperatur>>1
			StartDrawing(ImageOutput(#Balken))
			DrawImage(ImageID(#BalkenOriginal),0,0)
			If y>145
				DrawImage(ImageID(#BalkenLeer),0,y-120-y%5)
			EndIf
			DrawImage(ImageID(#BalkenFein),0,y)
			If y<145
				DrawImage(ImageID(#BalkenVoll),0,y+4-y%5)
			EndIf
			StopDrawing()
			StartDrawing(WindowOutput(#MainWindow))
			DrawImage(ImageID(#Balken),#BOffX,#BOffY)
			
			DrawImage(ImageID(#Tacho),16,374)
			StopDrawing()

			n=temperatur
			y=0
			For x=0 To 2
				BitBlt_(WinDC,45-14*x,379+y,#ZiffX,#ZiffY,ZiffID,#ZiffX*n%10,0,#SRCPAINT)
				y=(n%10)>>1-2
				n/10
			Next x
	

		Case #WM_RBUTTONUP
			CreatePopupMenu(#PopupMenu)
			MenuItem(#MenuQuit, "Close")
			DisplayPopupMenu(#PopupMenu,WinID)

		Case #PB_Event_CloseWindow
			Break

		Case #PB_Event_Menu
			Select EventGadget()
			Case #MenuQuit;		Escape / Close
				Break
			Case #TempMinus10
				If temperatur>15 : temperatur-10 : PostMessage_(WinID,#WM_PAINT,0,0) : EndIf
			Case #TempMinus1
				If temperatur>5 : temperatur-1 : PostMessage_(WinID,#WM_PAINT,0,0) : EndIf
			Case #TempPlus1
				If temperatur<510 : temperatur+1 : PostMessage_(WinID,#WM_PAINT,0,0) : EndIf
			Case #TempPlus10
				If temperatur<500 : temperatur+10 : PostMessage_(WinID,#WM_PAINT,0,0) : EndIf
			EndSelect

		Case #WM_LBUTTONDOWN
			SendMessage_(WinID, #WM_NCLBUTTONDOWN, #HTCAPTION, 0) ; Allow the dragging of our image around
		
		EndSelect

	ForEver

ReleaseDC_(WinID,WinDC)

EndProcedure

Main()
Is this a "normal" behaviour with all graphic cards? Have I done something wrong? And, is there a more simple method (than Bitblt) to put images transparent over others?

Thanks,
Michael
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Thanks for your post, it found a bug in GrabRegion. It's fixed now, here's the latest:

Code: Select all

ProcedureDLL GrabRegion(ImageID, transcolor) ; HBITMAP ImageID, COLORREF transcolor 

  ;======================================================= 
  ;                                                      = 
  ;      Very fast bitmap -> region creator              = 
  ;                                                      = 
  ;      By netmaestro                                   = 
  ;                                                      = 
  ;      Contributors: eesau, nico, flype                = 
  ;                                                      = 
  ;      June 26, 2007                                   = 
  ;                                                      = 
  ;======================================================= 
  
  Structure RECTARRAY
    rect.RECT[0] 
  EndStructure 

  GetObject_(ImageID, SizeOf(BITMAP), @bmp.BITMAP) 
  
  Protected width       = bmp\bmWidth 
  Protected height      = bmp\bmHeight 
  Protected hVisibleRgn = CreateRectRgn_(0, 0, width, height) 
  
  BmiInfo.BITMAPINFOHEADER 
  With BmiInfo 
    \biSize         = SizeOf(BITMAPINFOHEADER) 
    \biWidth        = width 
    \biHeight       = -height 
    \biPlanes       = 1 
    \biBitCount     = 32 
    \biCompression  = #BI_RGB 
  EndWith    
  
  rowbytes =  SizeOf(LONG)*width 

  *ColorBits = AllocateMemory(rowbytes*height) 
  
  hDC   = GetWindowDC_(#Null) 
  iRes  = GetDIBits_(hDC, ImageID, 0, height, *ColorBits, @bmiInfo, #DIB_RGB_COLORS) 
  ReleaseDC_(#Null, hDC) 
  
  Structure_Max=(width*height*16)+SizeOf(RGNDATAHEADER) 
  *Buffer.RGNDATAHEADER=AllocateMemory(Structure_Max) 
  *rd.RECTARRAY=*Buffer+SizeOf(RGNDATAHEADER) 

  rectcount = 0 
  For y=0 To height-1 
    pxcount=0 
    For x=0 To rowbytes-1 Step 4 
      *px.LONG = *ColorBits + rowbytes * y + x 
      If *px\l = transcolor  
        transcount = 1 : firsttrans = pxcount 
        x+SizeOf(LONG) : *px.LONG = *ColorBits + rowbytes * y + x 
        While *px\l = transcolor And x <= rowbytes-1
          transcount+1 : pxcount+1 : x+SizeOf(LONG) 
          *px = *ColorBits + rowbytes * y + x 
        Wend 
        x-SizeOf(LONG) : *px.LONG = *ColorBits + rowbytes * y + x 
        *rd\rect[rectcount]\left   = firsttrans            
        *rd\rect[rectcount]\top    = y                     
        *rd\rect[rectcount]\right  = firsttrans+transcount 
        *rd\rect[rectcount]\bottom = y+1      
        rectcount+1 
      EndIf 
      pxcount+1 
    Next 
  Next 
  
  With *Buffer 
    \dwSize         = SizeOf(RGNDATAHEADER) 
    \iType          = #RDH_RECTANGLES 
    \nCount         = rectcount 
    \nRgnSize       = rectcount * SizeOf(RECT) 
    \rcBound\left   = 0
    \rcBound\top    = 0
    \rcBound\right  = width
    \rcBound\bottom = height
  EndWith 
  
  RegionSize=SizeOf(RGNDATAHEADER)+(rectcount * SizeOf(RECT)) 
  hTransparentRgn = ExtCreateRegion_(0, RegionSize, *Buffer) 
  CombineRgn_(hVisibleRgn, hVisibleRgn, hTransparentRgn, #RGN_XOR) 
    
  FreeMemory(*Buffer) 
  FreeMemory(*ColorBits) 
  DeleteObject_(hTransparentRgn) 
  
  ProcedureReturn hVisibleRgn 
  
EndProcedure 
BERESHEIT
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Post by Rescator »

I really love this code. (no use for it yet myself though) And pondered how to improve it, I could not think of anything except one two things:

The source is now EnableExplicit compliant

I added several error checks (PSDK used as reference to make sure proper checks was done, knowing MS the return codes tend to vary :)

Multimedia Timer with 1ms period used for speed test, best timing without having to worry about QueryPerformanceCounter and Thread Affinity on multi cores etc.

Code: Select all

EnableExplicit

ProcedureDLL GrabRegion(ImageID, transcolor) ; HBITMAP ImageID, COLORREF transcolor

  ;=======================================================
  ;                                                      =
  ;      Very fast bitmap -> region creator              =
  ;                                                      =
  ;      By netmaestro                                   =
  ;                                                      =
  ;      Contributors: eesau, nico, flype                =
  ;                                                      =
  ;      June 26, 2007                                   =
  ;                                                      =
  ;=======================================================
 
  Structure RECTARRAY
    rect.RECT[0]
  EndStructure

  Protected bmp.BITMAP,width.l,height.l,hVisibleRgn.l,result.l=#False
  Protected BmiInfo.BITMAPINFOHEADER,rowbytes.l,*ColorBits,hDC.l,iRes.l,Structure_Max.l
  Protected *Buffer.RGNDATAHEADER,*rd.RECTARRAY,rectcount.l,y.l,x.l,pxcount.l,*px.LONG
  Protected transcount.l,firsttrans.l,regionSize.l,hTransparentRgn.l


  If GetObject_(ImageID, SizeOf(BITMAP), @bmp.BITMAP) And bmp

    width = bmp\bmWidth
    height = bmp\bmHeight
    hVisibleRgn=CreateRectRgn_(0, 0, width, height)
    If hVisibleRgn
     
      With BmiInfo
        \biSize         = SizeOf(BITMAPINFOHEADER)
        \biWidth        = width
        \biHeight       = -height
        \biPlanes       = 1
        \biBitCount     = 32
        \biCompression  = #BI_RGB
      EndWith   
     
      rowbytes =  SizeOf(LONG)*width
    
      *ColorBits = AllocateMemory(rowbytes*height)
      If *ColorBits
      
        hDC   = GetWindowDC_(#Null)
        If hDC
          iRes  = GetDIBits_(hDC, ImageID, 0, height, *ColorBits, @bmiInfo, #DIB_RGB_COLORS)
          If iRes
            ReleaseDC_(#Null, hDC)
            Structure_Max=(width*height*16)+SizeOf(RGNDATAHEADER)
            *Buffer=AllocateMemory(Structure_Max)
            If *Buffer
              *rd=*Buffer+SizeOf(RGNDATAHEADER)
            
              rectcount = 0
              For y=0 To height-1
                pxcount=0
                For x=0 To rowbytes-1 Step 4
                  *px = *ColorBits + rowbytes * y + x
                  If *px\l = transcolor 
                    transcount = 1 : firsttrans = pxcount
                    x+SizeOf(LONG) : *px.LONG = *ColorBits + rowbytes * y + x
                    While *px\l = transcolor And x <= rowbytes-1
                      transcount+1 : pxcount+1 : x+SizeOf(LONG)
                      *px = *ColorBits + rowbytes * y + x
                    Wend
                    x-SizeOf(LONG) : *px.LONG = *ColorBits + rowbytes * y + x
                    *rd\rect[rectcount]\left   = firsttrans           
                    *rd\rect[rectcount]\top    = y                     
                    *rd\rect[rectcount]\right  = firsttrans+transcount
                    *rd\rect[rectcount]\bottom = y+1     
                    rectcount+1
                  EndIf
                  pxcount+1
                Next
              Next
             
              With *Buffer
                \dwSize         = SizeOf(RGNDATAHEADER)
                \iType          = #RDH_RECTANGLES
                \nCount         = rectcount
                \nRgnSize       = rectcount * SizeOf(RECT)
                \rcBound\left   = 0
                \rcBound\top    = 0
                \rcBound\right  = width
                \rcBound\bottom = height
              EndWith
              RegionSize=SizeOf(RGNDATAHEADER)+(rectcount * SizeOf(RECT))
              hTransparentRgn = ExtCreateRegion_(0, RegionSize, *Buffer)
              If hTransparentRgn
                If CombineRgn_(hVisibleRgn, hVisibleRgn, hTransparentRgn, #RGN_XOR)
                  result=hVisibleRgn
                EndIf
              EndIf
              DeleteObject_(hTransparentRgn)
            EndIf
            FreeMemory(*Buffer)
          EndIf
        EndIf
        FreeMemory(*ColorBits)
      EndIf
    EndIf
  EndIf
  ProcedureReturn hVisibleRgn
EndProcedure 

Define start.l,ending.l,image.l,region.l

timeBeginPeriod_(1)
LoadImage(0, "girl.bmp")
OpenWindow(0,0,0,ImageWidth(0),ImageHeight(0),"", #PB_Window_ScreenCentered|#PB_Window_BorderLess)
CreateGadgetList(WindowID(0))
ImageGadget(0,0,0,0,0,ImageID(0))
start = timeGetTime_()
region=GrabRegion(ImageID(image),#White)
ending = timeGetTime_()
If region
 SetWindowRgn_(WindowID(0), region, #True)
 MessageRequester("Created Region in:", Str(ending-start)+" milliseconds!",$C0)
Else
 MessageRequester("Failed to create Region:", Str(ending-start)+" milliseconds wasted!",$C0)
EndIf
Repeat
  WaitWindowEvent()
Until GetAsyncKeyState_(#VK_SPACE) & 32768
timeEndPeriod_(1)
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Very good, thanks for help. I just had to make a couple of tweaks, here is the latest:

Code: Select all

ProcedureDLL GrabRegion(ImageID, transcolor) ; HBITMAP ImageID, COLORREF transcolor 

  ;======================================================= 
  ;                                                      = 
  ;      Very fast bitmap -> region creator              = 
  ;                                                      = 
  ;      Version 1.0 Release                             = 
  ;                                                      = 
  ;      By netmaestro                                   = 
  ;                                                      = 
  ;      Contributors: eesau, nico, flype, rescator      = 
  ;                                                      = 
  ;      June 26, 2007                                   = 
  ;                                                      = 
  ;======================================================= 
  
  Structure RECTARRAY 
    rect.RECT[0] 
  EndStructure 

  Protected bmp.BITMAP,width.l,height.l,hVisibleRgn.l,combineresult.l=0, returnvalue.l = 0 
  Protected BmiInfo.BITMAPINFOHEADER,rowbytes.l,*ColorBits,hDC.l,iRes.l,Structure_Max.l 
  Protected *Buffer.RGNDATAHEADER,*rd.RECTARRAY,rectcount.l,y.l,x.l,pxcount.l,*px.LONG 
  Protected transcount.l,firsttrans.l,regionSize.l,hTransparentRgn.l 

  If GetObject_(ImageID, SizeOf(BITMAP), @bmp.BITMAP) And bmp 
    width = bmp\bmWidth 
    height = bmp\bmHeight 
    hVisibleRgn=CreateRectRgn_(0, 0, width, height) 
    If hVisibleRgn 
      With BmiInfo 
        \biSize         = SizeOf(BITMAPINFOHEADER) 
        \biWidth        = width 
        \biHeight       = -height 
        \biPlanes       = 1 
        \biBitCount     = 32 
        \biCompression  = #BI_RGB 
      EndWith    
      rowbytes =  SizeOf(LONG)*width 
      *ColorBits = AllocateMemory(rowbytes*height) 
      If *ColorBits 
        hDC   = GetWindowDC_(#Null) 
        If hDC 
          iRes  = GetDIBits_(hDC, ImageID, 0, height, *ColorBits, @bmiInfo, #DIB_RGB_COLORS) 
          If iRes 
            ReleaseDC_(#Null, hDC) 
            Structure_Max=(width*height*16)+SizeOf(RGNDATAHEADER) 
            *Buffer=AllocateMemory(Structure_Max) 
            If *Buffer 
              *rd=*Buffer+SizeOf(RGNDATAHEADER) 
              rectcount = 0 
              For y=0 To height-1 
                pxcount=0 
                For x=0 To rowbytes-1 Step 4 
                  *px = *ColorBits + rowbytes * y + x 
                  If *px\l = transcolor 
                    transcount = 1 : firsttrans = pxcount 
                    x+SizeOf(LONG) : *px.LONG = *ColorBits + rowbytes * y + x 
                    While *px\l = transcolor And x <= rowbytes-1 
                      transcount+1 : pxcount+1 : x+SizeOf(LONG) 
                      *px = *ColorBits + rowbytes * y + x 
                    Wend 
                    x-SizeOf(LONG) : *px.LONG = *ColorBits + rowbytes * y + x 
                    With *rd\rect[rectcount]
                      \left   = firsttrans            
                      \top    = y                      
                      \right  = firsttrans+transcount 
                      \bottom = y+1      
                    EndWith
                    rectcount+1 
                  EndIf 
                  pxcount+1 
                Next 
              Next 
              With *Buffer 
                \dwSize         = SizeOf(RGNDATAHEADER) 
                \iType          = #RDH_RECTANGLES 
                \nCount         = rectcount 
                \nRgnSize       = rectcount * SizeOf(RECT) 
                \rcBound\left   = 0 
                \rcBound\top    = 0 
                \rcBound\right  = width 
                \rcBound\bottom = height 
              EndWith 
              RegionSize=SizeOf(RGNDATAHEADER)+(rectcount * SizeOf(RECT)) 
              hTransparentRgn = ExtCreateRegion_(0, RegionSize, *Buffer) 
              If hTransparentRgn 
                combineresult = CombineRgn_(hVisibleRgn, hVisibleRgn, hTransparentRgn, #RGN_XOR) 
                If combineresult = #SIMPLEREGION Or combineresult = #COMPLEXREGION 
                  returnvalue = hVisibleRgn 
                Else 
                  returnvalue = 0 
                EndIf 
                DeleteObject_(hTransparentRgn) 
              EndIf 
              FreeMemory(*Buffer) 
            EndIf 
          EndIf 
        EndIf 
        FreeMemory(*ColorBits) 
      EndIf 
    EndIf 
    DeleteObject_(bmp) 
  EndIf 
  ProcedureReturn returnvalue 
EndProcedure 
BERESHEIT
Xombie
Addict
Addict
Posts: 898
Joined: Thu Jul 01, 2004 2:51 am
Location: Tacoma, WA
Contact:

Post by Xombie »

I've ran my own humble optimizations on this. Unfortunately, I also formatted it to what I'm used seeing. I apologize for that.

Code: Select all

ProcedureDLL.l TicksHQ() 
  Static maxfreq.q 
  Protected t.q 
  If maxfreq=0 
    QueryPerformanceFrequency_(@maxfreq) 
    maxfreq=maxfreq/1000 
  EndIf 
  QueryPerformanceCounter_(@t) 
  ProcedureReturn t/maxfreq 
EndProcedure 


Structure REGIONDATA 
  rdh.RGNDATAHEADER 
  Buffer.l[100000] 
EndStructure 

Structure RECTARRAY 
   Rect.RECT[0] 
EndStructure 

ProcedureDLL GrabRegion(ImageID, transcolor) ; HBITMAP ImageID, COLORREF transcolor 
   
   ;======================================================= 
   ;                                                      = 
   ;      Very fast bitmap -> region creator              = 
   ;                                                      = 
   ;      Version 1.0 Release                             = 
   ;                                                      = 
   ;      By netmaestro                                   = 
   ;                                                      = 
   ;      Contributors: eesau, nico, flype, rescator      = 
   ;                                                      = 
   ;      June 26, 2007                                   = 
   ;                                                      = 
   ;======================================================= 
   
   Protected bmp.BITMAP,width.l,height.l,hVisibleRgn.l,combineresult.l=0, ReturnValue.l = 0 
   Protected BmiInfo.BITMAPINFOHEADER,rowbytes.l,*ColorBits,hdc.l,iRes.l,Structure_Max.l 
   Protected *Buffer.RGNDATAHEADER,*rd.RECTARRAY,rectcount.l,y.l,x.l,pxcount.l,*px.Long 
   Protected transcount.l,firsttrans.l,RegionSize.l,hTransparentRgn.l 
   Protected yMul.l
   ;
   If GetObject_(ImageID, SizeOf(BITMAP), @bmp.BITMAP) And bmp 
      ;
      width = bmp\bmWidth : height = bmp\bmHeight 
      ;
      hVisibleRgn=CreateRectRgn_(0, 0, width, height) 
      ;
      If hVisibleRgn
         ;
         With BmiInfo 
            \biSize         = SizeOf(BITMAPINFOHEADER) 
            \biWidth        = width 
            \biHeight       = -height 
            \biPlanes       = 1 
            \biBitCount     = 32 
            \biCompression  = #BI_RGB 
         EndWith
         ;
         rowbytes =  SizeOf(Long) * width 
         ;
         *ColorBits = AllocateMemory(rowbytes * height) 
         ;
         If *ColorBits 
            ;
            hdc   = GetWindowDC_(#Null) 
            ;
            If hdc 
               ;
               iRes  = GetDIBits_(hdc, ImageID, 0, height, *ColorBits, @BmiInfo, #DIB_RGB_COLORS) 
               ;
               If iRes 
                  ;
                  ReleaseDC_(#Null, hdc) 
                  ;
                  Structure_Max = (width * height << 4) + SizeOf(RGNDATAHEADER) 
                  ;
                  *Buffer = AllocateMemory(Structure_Max)
                  ;
                  If *Buffer 
                     ;
                     *rd = *Buffer + SizeOf(RGNDATAHEADER) 
                     ;
                     y = 0 : rectcount = 0 : yMul = 0
                     ;
                     While y < height
                        ;
                        x = 0 : pxcount=0
                        ;
                        While x < rowbytes
                           ;
                           *px = *ColorBits + yMul + x 
                           ;
                           If *px\l = transcolor 
                              ;
                              transcount = 1 : firsttrans = pxcount 
                              ;
                              x + SizeOf(Long)
                              ;
                              While *px\l = transcolor And x < rowbytes
                                 x + SizeOf(Long) : *px = *ColorBits + yMul + x : transcount + 1 : pxcount + 1
                              Wend 
                              ;
                              x - SizeOf(Long)
                              ;
                              With *rd\Rect[rectcount] 
                                 \Left   = firsttrans
                                 \Top    = y
                                 \Right  = firsttrans + transcount
                                 \Bottom = y + 1
                              EndWith 
                              ;
                              rectcount + 1
                              ;
                           EndIf 
                           ;
                           pxcount + 1 : x + 4
                           ;
                        Wend
                        ;
                        y + 1 : yMul + rowbytes
                        ;
                     Wend
                     ;
                     With *Buffer 
                        \dwSize         = SizeOf(RGNDATAHEADER) 
                        \iType          = #RDH_RECTANGLES 
                        \nCount         = rectcount 
                        \nRgnSize       = rectcount * SizeOf(RECT) 
                        \rcBound\Left   = 0 
                        \rcBound\Top    = 0 
                        \rcBound\Right  = width 
                        \rcBound\Bottom = height 
                     EndWith
                     ;
                     RegionSize = SizeOf(RGNDATAHEADER) + (rectcount * SizeOf(RECT)) 
                     ;
                     hTransparentRgn = ExtCreateRegion_(0, RegionSize, *Buffer) 
                     ;
                     If hTransparentRgn
                        ;
                        combineresult = CombineRgn_(hVisibleRgn, hVisibleRgn, hTransparentRgn, #RGN_XOR) 
                        ;
                        If combineresult = #SIMPLEREGION Or combineresult = #COMPLEXREGION 
                           ReturnValue = hVisibleRgn 
                        Else 
                           ReturnValue = 0 
                        EndIf 
                        ;
                        DeleteObject_(hTransparentRgn) 
                        ;
                     EndIf 
                     ;
                     FreeMemory(*Buffer) 
                     ;
                  EndIf 
                  ;
               EndIf 
               ;
            EndIf 
            ;
            FreeMemory(*ColorBits) 
            ;
         EndIf 
         ;
      EndIf 
      ;
      DeleteObject_(bmp) 
      ;
   EndIf 
   ;
   ProcedureReturn ReturnValue 
   ;
EndProcedure 

LoadImage(0, "c:\temp\girl.bmp") 

OpenWindow(0,0,0,ImageWidth(0),ImageHeight(0),"", #PB_Window_ScreenCentered|#PB_Window_BorderLess|#PB_Window_Invisible) 
CreateGadgetList(WindowID(0)) 
ImageGadget(0,0,0,0,0,ImageID(0)) 

Delay(100)
start = TicksHQ() 
  region = GrabRegion(ImageID(0), #White) 
ending = TicksHQ() 

SetWindowRgn_(WindowID(0), region, #True) 
HideWindow(0,0) 
MessageRequester("Created Region in:", Str(ending-start)+" milliseconds",$C0) 
Repeat 
  WaitWindowEvent() 
Until GetAsyncKeyState_(#VK_SPACE) & 32768 
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Post by Mistrel »

This is really great, netmaestro. Is there any chance you could get it working with 8-bit transparency?
Post Reply