Fast Point and Plot?
-
- User
- Posts: 11
- Joined: Thu Apr 22, 2004 6:42 pm
Fast Point and Plot?
Hi, I am new to Purebasic and its command set, wanted to know what would be the fastest way for me to read a pixel colour from one image, process it and then plot a pixel onto another image?
Do I have to change the drawing output back and forward during the loop? or can I specify an image buffer?
Thanks.
Do I have to change the drawing output back and forward during the loop? or can I specify an image buffer?
Thanks.
- Fluid Byte
- Addict
- Posts: 2336
- Joined: Fri Jul 21, 2006 4:41 am
- Location: Berlin, Germany
The fastet way would be to peek the bitmap data directly from memory but that seems redundant as you can simply copy the image.
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
- netmaestro
- PureBasic Bullfrog
- Posts: 8451
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
The very fastest way is to read and write directly to the image's color bits buffer. This buffer is not something PureBasic provides you with for an image, but the GetObject_() API will give you a pointer to it. (assuming you're on Windows, of course) Here's a little demo prog that illustrates the speed gain. Please disable the debugger to run it (Debugger menu in IDE -> Use Debugger = unselected) for best results:
This program takes all the red pixels from the first image and duplicates them on the second image as green for the plot method and blue for the read/write buffer method. You should notice a significant delay when you press the Plot button as the image is processed, while the API button will probably give instant results.
Note: This is a very quick-and-dirty version to demonstrate the speed difference, for an actual program you would likely want to use GetDIBits_() for a more professional approach.
Code: Select all
; Make a good-sized image to read from
CreateImage(1, 1000,720,32)
StartDrawing(ImageOutput(1))
Box(0,0,1000,720,#White)
Ellipse(500,330,450,300,#Red)
StopDrawing()
; An equal-sized image to write to
CreateImage(2, 1000,720,32)
StartDrawing(ImageOutput(2))
Box(0,0,1000,720,GetSysColor_(#COLOR_BTNFACE))
StopDrawing()
; Make an array to use for transferring colors
Dim colors(1000,720)
; Open a window for display test results
OpenWindow(0,0,0,1000,768,"",$CA0001)
CreateGadgetList(WindowID(0))
ImageGadget(1,0,0,0,0,0)
ButtonGadget(2,330,730,80,20,"Plot")
ButtonGadget(3,420,730,80,20,"API")
ButtonGadget(4,510,730,80,20,"Clear")
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Gadget
If EventGadget() = 2
StartDrawing(ImageOutput(1))
For h = 0 To 719
For w = 0 To 999
colors(w,h) = Point(w,h)
Next
Next
StopDrawing()
StartDrawing(ImageOutput(2))
For h=0 To 719
For w = 0 To 999
If colors(w,h) = #Red
Plot(w,h,#Green)
EndIf
Next
Next
StopDrawing()
SetGadgetState(1, ImageID(2))
ElseIf EventGadget() = 3
GetObject_(ImageID(1), SizeOf(BITMAP), @bmp1.BITMAP)
width = bmp1\bmWidth
height = bmp1\bmHeight
widthbytes = bmp1\bmWidthbytes
*colorbits1 = bmp1\bmBits
GetObject_(ImageID(2), SizeOf(BITMAP), @bmp2.BITMAP)
*colorbits2 = bmp2\bmBits
*pxin.LONG
*pxout.LONG
For y=0 To height-1
For x=0 To widthbytes-1 Step 4
*pxin = *colorbits1 + widthbytes * y + x
If *pxin\l = RGB(0,0,255)
*pxout = *colorbits2 + widthbytes * y + x
*pxout\l = RGB(255,0,0)
cc+1
EndIf
Next
Next
DeleteObject_(bmp1)
DeleteObject_(bmp2)
SetGadgetState(1, ImageID(2))
ElseIf EventGadget() = 4
SetGadgetState(1,0)
EndIf
EndSelect
Until Event = #WM_CLOSE
Note: This is a very quick-and-dirty version to demonstrate the speed difference, for an actual program you would likely want to use GetDIBits_() for a more professional approach.
BERESHEIT
- Fluid Byte
- Addict
- Posts: 2336
- Joined: Fri Jul 21, 2006 4:41 am
- Location: Berlin, Germany
This what I already said and I didn't provided code for a reason. Considering his request he doesn't need this technique at all because he can just copy the image, so it's not worth the hassle. Furthermore hes a beginner so the code is rather useless to him because its pretty advanced. Speaking for myself I can tell that it took me a couple of years of knowledge to understand bitmap manipulation like this. So as I said before, if he has the image already loaded there's no need to plot anything from image to another. He can simply copy it.netmaestro wrote:The very fastest way is to read and write directly to the image's color bits buffer.
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
- Kaeru Gaman
- Addict
- Posts: 4826
- Joined: Sun Mar 19, 2006 1:57 pm
- Location: Germany
I think you shouldn't consider your opponent just dumb, asking such a question just to COPY an image.Fluid Byte wrote:This what I already said and I didn't provided code for a reason. Considering his request he doesn't need this technique at all because he can just copy the image, so it's not worth the hassle. Furthermore hes a beginner so the code is rather useless to him because its pretty advanced. Speaking for myself I can tell that it took me a couple of years of knowledge to understand bitmap manipulation like this. So as I said before, if he has the image already loaded there's no need to plot anything from image to another. He can simply copy it.netmaestro wrote:The very fastest way is to read and write directly to the image's color bits buffer.
he asked for a method to transfer Data from one image to another pixelwise.
that he wants to do some manipulation with the data is implemented.
nobody would be so dumb to ask for read/process/plot instead of "how can I copy an image" if he just wanted to copy it.what would be the fastest way for me to read a pixel colour from one image, process it and then plot a pixel onto another image?
oh... and have a nice day.
- netmaestro
- PureBasic Bullfrog
- Posts: 8451
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
-
- User
- Posts: 11
- Joined: Thu Apr 22, 2004 6:42 pm
Thanks netmaestro, thats just what I was looking for. As you stated I am new to Purebasic but not to programming.
This is for a fast edge detection routine, I already have my app running in Blitz and peek/poke the mem to read/write the bitmaps, but did not know how to achive this in Pure.
I am hoping that Pure is faster on large images so that I can move my project over.
Thanks.
This is for a fast edge detection routine, I already have my app running in Blitz and peek/poke the mem to read/write the bitmaps, but did not know how to achive this in Pure.
I am hoping that Pure is faster on large images so that I can move my project over.
Thanks.
-
- User
- Posts: 11
- Joined: Thu Apr 22, 2004 6:42 pm
- netmaestro
- PureBasic Bullfrog
- Posts: 8451
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
You need to use the GetDIBits_() API for that. It allows you to create a colorbits buffer in your desired depth. There are several examples of implementing this around the forums if you do a search on it. Once you've done that though, you have to put the headers on it to make a complete image for drawing or saving or sending over the network.
BERESHEIT
- netmaestro
- PureBasic Bullfrog
- Posts: 8451
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Actually, come to think of it, there's a simple way that should work:
which should effectively create a 32-bit image #final from Image 0.
Code: Select all
CreateImage(#final, ImageWidth(0), ImageHeight(0), 32)
StartDrawing(ImageOutput(#final))
DrawImage(ImageID(0),0,0)
StopDrawing()
BERESHEIT
Personally I'd just copy it, then point/process/plot on the copy of the image.Kaeru Gaman wrote:I think you shouldn't consider your opponent just dumb, asking such a question just to COPY an image.Fluid Byte wrote:This what I already said and I didn't provided code for a reason. Considering his request he doesn't need this technique at all because he can just copy the image, so it's not worth the hassle. Furthermore hes a beginner so the code is rather useless to him because its pretty advanced. Speaking for myself I can tell that it took me a couple of years of knowledge to understand bitmap manipulation like this. So as I said before, if he has the image already loaded there's no need to plot anything from image to another. He can simply copy it.netmaestro wrote:The very fastest way is to read and write directly to the image's color bits buffer.
he asked for a method to transfer Data from one image to another pixelwise.
that he wants to do some manipulation with the data is implemented.nobody would be so dumb to ask for read/process/plot instead of "how can I copy an image" if he just wanted to copy it.what would be the fastest way for me to read a pixel colour from one image, process it and then plot a pixel onto another image?