PDA

View Full Version : Displaying images stored in the ring buffer



Unregistered
June 9, 2005, 20:54:24
After much trial and error, I have discovered that images stored in the ring buffer cannot be displayed one after the other by looping through the ring within an event handler. For example, the following does not work:

Private Sub btnDisplay_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDisplay.Click
Dim Frame As TIS.imaging.ImageBuffer
Dim i, nBuffers As Integer
nBuffers = IcImagingControl1.ImageBuffers.GetUpperBound(0)
For i = 0 To nBuffers
Frame = IcImagingControl1.ImageBuffers(i)
IcImagingControl1.DisplayImageBuffer(Frame)
Thread.Sleep(1000)
Next
End Sub

One can verify that an event handler (such as the one above) can display at most one image, and that the image is not displayed until after the handler exits.

Could you please explain this behaviour, and suggest an efficient way of displaying a succession of images (for example, to simulate time-lapse video). (I've thought of defining and raising an event, but haven't tried it yet.)

Thanks,

Bill

Stefan Geissler
June 10, 2005, 11:19:04
Hello Bill

Thanks for error reporting, i can reproduce the problem and gave it to the programming team. At this point of time, i can suggest a work around. Use a PictureBox for the display:



For i = 0 To nBuffers
Frame = IcImagingControl1.ImageBuffers(i)

PictureBox1.Image = Frame.Bitmap
PictureBox1.Refresh()
System.Threading.Thread.Sleep(1000)
Next

The "Refresh()" is important.

wsachs
June 10, 2005, 23:28:39
Thanks for the workaround. I believe I now understand the behaviour I described above:

The failure to display the frames in the ring buffer is understandable if the .DisplayImageBuffer method raises an event, and its event handler is actually responsible for displaying the specified frame. Because this event handler executes on the same thread as the btnDisplay.Click handler, it is blocked until the btnDisplay.Click handler exits, and all but the last display event generated during the loop are lost.

This suggests another workaround. I am sure there are more elegant ways to do this, but this works.


Define a Delegate and Thread:

Private Sub Delegate DisplayFrame(ByVal BufferIndex as Integer)
Private WorkThread as Thread


In the bntDisplay.Click handler, create and start WorkThread:

WorkThread = New Thread(AddressOf RingDisplay)
WorkThread.Start()


RingDisplay is the method executed by WorkThread. It executes the timed loop, and invokes a delegate on the main thread for each frame to be displayed:

Private Sub RingDisplay()
Dim i, nBuffers as Integer
nBuffers = IcImagingControl1.ImageBuffers.GetUpperBound(0)
For i = 0 To nBuffers
Me.Invoke(New DisplayFrame(AddressOf DisplayBuffer), New Object() {i})
Thread.Sleep(1000)
Next
End Sub


Finally, the method executed by the delegate is:

Private Sub DisplayBuffer(ByVal BufferIndex as Integer)
Dim Frame as TIS.Imaging.ImageBuffer
Frame = IcImagingControl1.ImageBuffers(BufferIndex)
IcImagingControl1.DisplayImageBuffer(Frame)
End Sub


Because the btnDisplay.Click handler exits as soon as the looping thread starts, and because DisplayBuffer is only responsible for displaying a single frame, there is no block and each frame in the ring buffer is displayed.

Stefan Geissler
June 13, 2005, 09:33:45
Hello,

That is cool. Thank you!