Is the DrawAlphaImage() command supposed to be this slow?...

Just starting out? Need help? Post your questions and find answers here.
Kale
PureBasic Expert
PureBasic Expert
Posts: 3000
Joined: Fri Apr 25, 2003 6:03 pm
Location: Lincoln, UK
Contact:

Is the DrawAlphaImage() command supposed to be this slow?...

Post by Kale »

I was kind of unsure as to where to post this question so mods feel free to move this post. :wink:

I've been playing with PBv4a9 and using the 2D drawing commands and noticed that the 'DrawAlphaImage()' command is veeeeeeerrry slow.

I loaded a WinXP icon with an eight bit alpha channel and then drawn 10,000 of these on another image created with 'CreateImage()' using the 'DrawImage()' command, this takes about 200ms

Then i converted this icon into a 32 bit PNG with an alpha channel, then loaded this and drawn 10,000 using the 'DrawAlphaImage()' command. This takes 9800ms!!!

These are with the debugger OFF. Are these time what is expected or does the 'DrawAlphaImage()' command need a bit of love?

Code: Select all

Enumeration
	#WINDOW_MAIN
	#IMAGE_GADGET
	#IMAGE_SMALL
	#IMAGE_MAIN
	#FONT_MAIN
EndEnumeration

Global ImageWidth = 400
Global ImageHeight = 200
Global XPos.l, YPos.l, LoadedImageWidth.l, LoadedImageHeight.l

Global File.s
Global RequesterText.s = "Choose an image"
Global DefaultFile.s = ""
Global Pattern.s = "Icon (*.ico)|*.ico|Png (*.png)|*.png"

UsePNGImageDecoder()

File = OpenFileRequester(RequesterText, DefaultFile, Pattern, 0)

If File
	StartTime.l = ElapsedMilliseconds()
	LoadImage(#IMAGE_SMALL, File)
	LoadedImageWidth = ImageWidth(#IMAGE_SMALL)
	LoadedImageHeight = ImageHeight(#IMAGE_SMALL)
	If CreateImage(#IMAGE_MAIN, ImageWidth,ImageHeight)
		If StartDrawing(ImageOutput(#IMAGE_MAIN))
			Box(0, 0,ImageWidth, ImageHeight, RGB(255, 255, 255))
			For x.l = 0 To 10000
				XPos = Random(ImageWidth) - (ImageWidth(#IMAGE_SMALL) / 2)
				YPos = Random(ImageHeight) - (ImageHeight(#IMAGE_SMALL) / 2)
				If SelectedFilePattern() = 1
					DrawAlphaImage(ImageID(#IMAGE_SMALL), XPos, YPos)
				Else
					DrawImage(ImageID(#IMAGE_SMALL), XPos, YPos)
				EndIf
			Next x
			DrawingMode(#PB_2DDrawing_Outlined)
			Box(0, 0, ImageWidth, ImageHeight, RGB(0, 0, 0))
			StopDrawing()
			EndTime.l = ElapsedMilliseconds()
		EndIf
	EndIf
	#TEXT = "Drawing Using Images"
	#FLAGS = #PB_Window_SystemMenu | #PB_Window_ScreenCentered
	If OpenWindow(#WINDOW_MAIN,0,0,ImageWidth+20,ImageHeight+20,#TEXT,#FLAGS)
		If CreateGadgetList(WindowID(#WINDOW_MAIN))
			ImageGadget(#IMAGE_GADGET,10,10,ImageWidth,ImageHeight,ImageID(#IMAGE_MAIN))
		EndIf
		MessageRequester("Timings", "The amount of time taken to complete all drawing actions was:" + #LF$ + #LF$ + Str(EndTime - StartTime) + "ms")
		Repeat
			Event.l = WaitWindowEvent()
		Until Event = #PB_Event_CloseWindow
	EndIf
	End
EndIf
I cant upload the images ATM because im currently without a hoster but the slow down occurs with all pngs drawn with the 'DrawAlphaImage()' command.
--Kale

Image
Fred
Administrator
Administrator
Posts: 18264
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Post by Fred »

The problem is we need to premultiply all the pixels, which means we create a temp image, multiply all the pixels, display and delete the temp image. It's very time consuming, we could may be add a flag to do the premultiply once (but that means than the image can't be used anymore with DrawImage()).
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 »

That sounds like a good idea. Anything that can be done to help the speed would be a good thing, as I'm getting results here showing that DrawAlphaImage() is slower by a factor of 10. (100ms for Draw, 1000 for DrawAlpha)
BERESHEIT
Kale
PureBasic Expert
PureBasic Expert
Posts: 3000
Joined: Fri Apr 25, 2003 6:03 pm
Location: Lincoln, UK
Contact:

Post by Kale »

I agree, adding a flag to do this would be cool. If you wanted to display an image and respect it's alpha channel then you wouldn't use 'DrawImage()' anyway. :)
--Kale

Image
mdp
Enthusiast
Enthusiast
Posts: 115
Joined: Mon Apr 18, 2005 8:28 pm

Post by mdp »

I'm not sure I understood correctly:

we have an AlphaImg (w: 160, h: 120)
and a MainImg (w: 600, h: 400)
we create a temporary 160x120, copy the area from MainImg it covers, multiply accoding to the pixels from AlphaImg, DrawImage() the temp on MainImg, free the temp.

Would it be possible (faster) instead to do everything "in loco"?
create a temp 600x400
copy the MainImg inside it
multiply according to AlphaImg in the temp
DrawImage() the (whole) temp on MainImg
free the tmp.

At first sight, this could be faster for a higher number of AlphaImg's.

Not only, but this way we could have a pointer to the temp in "normal" 2d-Drawing as we have with sprites. :wink:
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

Post by Fluid Byte »

Any news on this? This command is slow as hell while trying to display 32-Bit PNG wich is 360 x 119 Px in size. The only alternative would be using the Sprite3D library but the image has to be in 2^N format. This would 512 x 512 in this case wich is just a waste of space. And besides the manual says that 256 x 256 is the largest size you should use.
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
Post Reply