Page 1 of 1

address of point?

Posted: Mon Sep 01, 2014 11:24 am
by high key
Is there something like

getaddressofpoint(#image,x,y) ?

It would be very helpful.

Re: address of point?

Posted: Mon Sep 01, 2014 12:16 pm
by luis
StartDrawing(ImageOutput((#Image)) + DrawingBuffer() + DrawingBufferPitch()

http://www.purebasic.com/documentation/ ... uffer.html

You get the base address of the image, from that it's just some arithmetic taking into account the image format.

Re: address of point?

Posted: Mon Sep 01, 2014 5:54 pm
by infratec
Hi,

Code: Select all

Procedure.i GetAddressOfPoint(Image.i, x.i, y.i)
  
  Protected.i Result, PixelFormat, PixelByteSize
  Protected *Buffer
  
  
  Result = -1
  If IsImage(Image)
    If StartDrawing(ImageOutput(Image))
      *Buffer = DrawingBuffer()
      PixelFormat = DrawingBufferPixelFormat()
      Select PixelFormat & ~#PB_PixelFormat_ReversedY
        Case #PB_PixelFormat_8Bits
          PixelByteSize = 1
        Case #PB_PixelFormat_15Bits, #PB_PixelFormat_16Bits
          PixelByteSize = 2
        Case #PB_PixelFormat_24Bits_RGB, #PB_PixelFormat_24Bits_BGR
          PixelByteSize = 3
        Case #PB_PixelFormat_32Bits_RGB, #PB_PixelFormat_32Bits_BGR
          PixelByteSize = 4
      EndSelect
      If PixelFormat & #PB_PixelFormat_ReversedY
        y = ImageHeight(0) - y - 1
      EndIf
      Result = *Buffer + (y * DrawingBufferPitch()) + (x * PixelByteSize)      
      StopDrawing()
    EndIf
  EndIf
  
  ProcedureReturn Result
  
EndProcedure


CreateImage(0, 10, 10)
StartDrawing(ImageOutput(0))
Plot(3, 3, $123456)
StopDrawing()

Debug Hex(PeekI(GetAddressOfPoint(0, 3, 3) & $FFFFFF))
But I have no idea for what you need this.
You can get the colour of the point with Point() :mrgreen:

And be carefull, you have to check also the bytesize of the pixel.

Or use CustomFilterCallback() if you have to change more pixels at once.

Bernd

Re: address of point?

Posted: Mon Sep 01, 2014 7:34 pm
by high key
Thank you luis and infratec!

My idea was to copy some single lines of an image with copymemory instead of checking single points and drawing them with plot, which is extremely slow. But the thing seems much more complicate than I thought.
So my idea of getting an address and copying a number of bytes (3 bytes per pixel) to a new address was a bit naive :?

Re: address of point?

Posted: Tue Sep 02, 2014 2:49 am
by Demivec
high key wrote:My idea was to copy some single lines of an image with copymemory instead of checking single points and drawing them with plot, which is extremely slow. But the thing seems much more complicate than I thought.
So my idea of getting an address and copying a number of bytes (3 bytes per pixel) to a new address was a bit naive :?
You can use GrabImage() to snag just the part you want to copy and then draw this in the new image.

Here is an example of just grabbing the 5th line of Image_1 and drawing it over the 10th line of Image_2:

Code: Select all

GrabImage(#Image_1, #Image_Temp, 0, 5, ImageWidth(#Image_1), 1) ;grab the 5th line of Image_1

StartDrawing(ImageOutput(#Image_2))
  DrawImage(ImageID(#Image_Temp), 0, 10) ;draw over line 10
StopDrawing()

Re: address of point?

Posted: Tue Sep 02, 2014 3:01 am
by netmaestro
checking single points and drawing them with plot, which is extremely slow.
This used to be the case but not anymore. Since the 2DDrawing library was overhauled with version 4.4 Point() and Plot() are pretty close in speed to read/writes using structured pointers. You can use them with confidence.

Re: address of point?

Posted: Tue Sep 02, 2014 10:59 am
by luis
netmaestro wrote:You can use them with confidence.
They are indeed faster than before but they still have the stack overhead of being functions

Code: Select all

; Point(x,y)
  PUSH   dword [v_y]
  PUSH   dword [v_x]
  CALL  _PB_Point@8
; Plot(x, y, 255)
  PUSH   dword 255
  PUSH   dword [v_y]
  PUSH   dword [v_x]
  CALL  _PB_Plot2@12
1) Since these instructions are normally used inside loops, that can still have a substantial impact compared to using pointers.

2) Also inline code using pointers has locality as a further advantage, and so more possibilities of being kept in the CPU cache, even if the PB exes tends to be small and CPU caches got a lot bigger than in the past, so it may or may not be an issue (the CALLed code can be near enough).

3) Also the Point() and Plot() commands, taking X and Y as parameters, I believe have to calculate the offset of the target pixel in memory every time, whilst using pointers you can unroll the loops and transform that calculations in increments of the pointers moving along in memory to the next pixel. A lot faster.

Re: address of point?

Posted: Tue Sep 02, 2014 11:25 am
by Fred
IMHO, the point of netmaestro was it's not "dead" slow like it was before. There is indeed a penality over raw pointer access, but depending of what you do with the pixels, it can be fast enough to avoid bothering with a more complex (and more bug prone) code.

Re: address of point?

Posted: Tue Sep 02, 2014 11:33 am
by luis
Fred wrote:IMHO, the point of netmaestro was it's not "dead" slow like it was before.
Sure, I'm totally for writing code "fast enough" and not "the absolute faster code I can" 99% of the time.

But at least for educational purpose... knowing how in reality things work is always better then knowing a good approximation of it.

Then everyone will hopefully use what it's appropriate when it's appropriate, or at least know there is a margin for improvement at the cost of more work.

Most of the people here already knew what I wrote. I wrote it for the others, now they know, and maybe are curious enough to experiment and learn something else from this starting point.

Re: address of point?

Posted: Tue Sep 02, 2014 11:55 am
by high key
Things are getting clearer now :)

I haven't tried the point() with PB5 because converting my old large 3.9 source would take some time to convert to the newer PB conventions .

But it's good news to know, point is working now noticeable faster!

I already have tested the grabimage method before and it didn't work.
I used grabimage between startdrawing() stopdrawing() on the drawing image and got black grabimages.
This can propably not work because the image at that moment is not existent for grabimage.
I now tried it with grabbing from a copy of the image - and that works fine!

Thank you all for the detailed infos, I learned a lot from them!

Re: address of point?

Posted: Tue Sep 02, 2014 12:43 pm
by Fred
You can use GrabDrawingImage() instead

Re: address of point?

Posted: Tue Sep 02, 2014 6:24 pm
by Demivec
high key wrote:I already have tested the grabimage method before and it didn't work.
I used grabimage between startdrawing() stopdrawing() on the drawing image and got black grabimages.
This can propably not work because the image at that moment is not existent for grabimage.
I now tried it with grabbing from a copy of the image - and that works fine!
I thought you were copying parts of one image over parts of another image. My mistake :oops: , Fred has posted the better way to handle capture and drawing to the same output using GrabDrawingImage().

Re: address of point?

Posted: Tue Sep 02, 2014 7:10 pm
by Danilo
Fred wrote:You can use GrabDrawingImage() instead
It was introduced with PB 4.40, and from what I understood he is still using v3.90 because
converting the old large 3.9 source would take some time to convert to the newer PB conventions.