Problem with RetrieveImage
-
Thursday, October 01, 2009 2:26 PMHi, i have successfully got code working to read a cheque image from a Magtek MicrImage reader. However, the RetrieveImage method is causing me problems as when i attempt to read the ImageData property, i get corrupted or half an image - which i'm guessing is due to me trying to read the imagedata before RetrieveImage has completed (the device is using serial over USB).
I stuck a thread sleep in and waiting for a few seconds before saving and all the data seems to be there but obviously i dont want to put a "finger in the air" guess-bit-of-code around this waiting for the data to complete. Is there any way i can be signalled when the image data has been downloaded in full?
Steve
Answers
-
Friday, October 02, 2009 11:04 AMAnswerer
Hi,
While you should always call BeingInsertion etc. to ensure your code works with devices that require it, it sounds like your device doesn't need that because of the auto-sheet feeder, so those methods *should* be irrelevant as far as your problems go.
It might pay you to alter the statusupdateevent to check whether or not the status event you've received is actually an image arriving. It might be you're asking for an image when you get some other kind of status event and that's messing something up... maybe. The value of e.Status should equal CheckScanner.StatusScanComplete before you actually attempt to read the image.
I think the reason you don't get an image after the first one is that the dataevent has been disabled... in the status update event, after you retrieve the image, reset both DeviceEnabled (in case the AutoDisable property is set to true as well) and DataEventEnabled to true. That should allow the next image to be captured.
Short of the status check, I'm not sure why you'd only get half an image though.- Marked As Answer by Stephen Whitaker Monday, October 05, 2009 8:26 AM
-
Friday, October 02, 2009 7:20 PMAnswerer
Acutally, in addition to my previous comments I think this part of the documentation is key;
"If the application has to retrieve the image or a cropped part of the image, it calls the RetrieveImage method. The image data is sent from the device to the service object and stored in the ImageData property. When the corresponding DataEvent event is delivered, the current image (or cropped part of the current image) may be accessed by the application reading the image file that is contained in the ImageData property."
Looking at my own implementation, I call RetrieveImage in the statusupdate event if e.Status == CheckScanner.StatusScanComplete, then in my event handler for the DataEvent (which I have already connected to previously) I retrieve the contents of the ImageData property and then re-enable the device and data event.
It's quite likely you're reading the buffer before it's completely full because you're not waiting for the data event before retrieving the image, which would explain the half/corrupted image, and failure to re-enable the device/data event would prevent further images being scanned.
The CheckScanner is defintely one of the more awkward Pos .Net devices to use.- Marked As Answer by Stephen Whitaker Monday, October 05, 2009 8:26 AM
-
Sunday, October 04, 2009 4:11 AM
While not related to your specific problem, I strongly recommend that you pass the form when you create the PosExplorer in order to ensure that all events are marshaled to the UI thread.While I've used MICRs, I don't have any personal experience with CheckScanners. I would just recommend that you read the UPOS spec carefully for this device category and see if you may have overlooked something.- Marked As Answer by Stephen Whitaker Monday, October 05, 2009 8:26 AM
All Replies
-
Thursday, October 01, 2009 7:03 PMAnswererHi Steve,
When and where are you calling RetrieveImage... can you post the code ?
There is a status event that that indicates the image has been read, if you are calling RetrieveImage from the StatusUpdateEvent event handler when you get the event code that means image read, then the buffer *should* contain a complete image as far as I know. -
Friday, October 02, 2009 9:25 AM
Imports Microsoft.PointOfService Imports System.Threading Public Class Form1 Private explorer As PosExplorer Private scannerList As DeviceCollection Private activeDevice As DeviceInfo Private WithEvents activeScanner As Microsoft.PointOfService.CheckScanner Private autoReset As New AutoResetEvent(False) Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load explorer = New PosExplorer scannerList = explorer.GetDevices For Each Device As DeviceInfo In scannerList If Device.ServiceObjectName = "MagTek MicrImage" Then activeDevice = Device Exit For End If Next activeScanner = CType(explorer.CreateInstance(activeDevice), CheckScanner) activeScanner.Open() activeScanner.Claim(1000) activeScanner.DeviceEnabled = True activeScanner.DataEventEnabled = True End Sub Private Sub activeScanner_StatusUpdateEvent(ByVal sender As Object, ByVal e As Microsoft.PointOfService.StatusUpdateEventArgs) Handles activeScanner.StatusUpdateEvent Dim crop As Integer = Microsoft.PointOfService.CheckScanner.CropAreaEntireImage activeScanner.RetrieveImage(crop) activeScanner.ImageData.Save("c:\temp\scanner-" & Now.ToString("dd-MM-yyyy-HH-mm-ss") & ".bmp") End Sub Private Sub btnEndInsertion_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEndInsertion.Click activeScanner.EndInsertion() activeScanner.BeginRemoval(1000) activeScanner.EndRemoval() End Sub Private Sub btnBeginInsertion_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBeginInsertion.Click activeScanner.BeginInsertion(10000) End Sub End Class -
Friday, October 02, 2009 9:27 AMThe problem i've got is knowing what order to do things in - i appreciate that BeginInsertion, EndInsertion, BeginRemoval, EndRemoval need always to be called according to the documentation but the device has an automatic sheet feeder and the StatusUpdateEvent is always called when a cheque is inserted regardless. It seems to not save anything first time through, when i feed the check through again it saves it and then thats it, no more image files.
-
Friday, October 02, 2009 11:04 AMAnswerer
Hi,
While you should always call BeingInsertion etc. to ensure your code works with devices that require it, it sounds like your device doesn't need that because of the auto-sheet feeder, so those methods *should* be irrelevant as far as your problems go.
It might pay you to alter the statusupdateevent to check whether or not the status event you've received is actually an image arriving. It might be you're asking for an image when you get some other kind of status event and that's messing something up... maybe. The value of e.Status should equal CheckScanner.StatusScanComplete before you actually attempt to read the image.
I think the reason you don't get an image after the first one is that the dataevent has been disabled... in the status update event, after you retrieve the image, reset both DeviceEnabled (in case the AutoDisable property is set to true as well) and DataEventEnabled to true. That should allow the next image to be captured.
Short of the status check, I'm not sure why you'd only get half an image though.- Marked As Answer by Stephen Whitaker Monday, October 05, 2009 8:26 AM
-
Friday, October 02, 2009 7:20 PMAnswerer
Acutally, in addition to my previous comments I think this part of the documentation is key;
"If the application has to retrieve the image or a cropped part of the image, it calls the RetrieveImage method. The image data is sent from the device to the service object and stored in the ImageData property. When the corresponding DataEvent event is delivered, the current image (or cropped part of the current image) may be accessed by the application reading the image file that is contained in the ImageData property."
Looking at my own implementation, I call RetrieveImage in the statusupdate event if e.Status == CheckScanner.StatusScanComplete, then in my event handler for the DataEvent (which I have already connected to previously) I retrieve the contents of the ImageData property and then re-enable the device and data event.
It's quite likely you're reading the buffer before it's completely full because you're not waiting for the data event before retrieving the image, which would explain the half/corrupted image, and failure to re-enable the device/data event would prevent further images being scanned.
The CheckScanner is defintely one of the more awkward Pos .Net devices to use.- Marked As Answer by Stephen Whitaker Monday, October 05, 2009 8:26 AM
-
Sunday, October 04, 2009 4:11 AM
While not related to your specific problem, I strongly recommend that you pass the form when you create the PosExplorer in order to ensure that all events are marshaled to the UI thread.While I've used MICRs, I don't have any personal experience with CheckScanners. I would just recommend that you read the UPOS spec carefully for this device category and see if you may have overlooked something.- Marked As Answer by Stephen Whitaker Monday, October 05, 2009 8:26 AM
-
Monday, October 05, 2009 8:05 AM
Following everyone's helpful comments it now works as it should - i can insert cheques repeatedly and the image is saved correctly each time - i guess its just a case of getting everything in the right order. I am posting the code here for reference to help anyone else out with a similar problem. Many thanks all!
Imports Microsoft.PointOfService Public Class Form1 Private explorer As PosExplorer Private scannerList As DeviceCollection Private activeDevice As DeviceInfo Private WithEvents activeScanner As Microsoft.PointOfService.CheckScanner Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing activeScanner.Release() activeScanner.Close() End Sub Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load explorer = New PosExplorer(Me) scannerList = explorer.GetDevices For Each Device As DeviceInfo In scannerList If Device.ServiceObjectName = "MagTek MicrImage" Then activeDevice = Device Exit For End If Next activeScanner = CType(explorer.CreateInstance(activeDevice), CheckScanner) activeScanner.Open() activeScanner.Claim(1000) activeScanner.DeviceEnabled = True activeScanner.DataEventEnabled = True activeScanner.BeginInsertion(1000) End Sub Private Sub activeScanner_DataEvent(ByVal sender As Object, ByVal e As Microsoft.PointOfService.DataEventArgs) Handles activeScanner.DataEvent activeScanner.ImageData.Save("c:\temp\scanner-" & Now.ToString("dd-MM-yyyy-HH-mm-ss") & ".bmp") activeScanner.DeviceEnabled = True activeScanner.DataEventEnabled = True End Sub Private Sub activeScanner_StatusUpdateEvent(ByVal sender As Object, ByVal e As Microsoft.PointOfService.StatusUpdateEventArgs) Handles activeScanner.StatusUpdateEvent If e.Status = CheckScanner.StatusScanComplete Then activeScanner.EndInsertion() activeScanner.BeginRemoval(1000) activeScanner.EndRemoval() Dim crop As Integer = Microsoft.PointOfService.CheckScanner.CropAreaEntireImage activeScanner.RetrieveImage(crop) End If End Sub End Class

