Delphi Twain issue help
Using the DelphiTwain files from http://delphitwain.sourceforge.net/ and am getting some weird behavior.
- After each scan a little more memory is being held onto.
- After an hour or so of repetitive scans, the image scanned is zoomed in approxamately 10 times, and just the upper-left square inch is stored.
Has anyone had similar issues, or have some suggestions?
try try Twain := TDelphiTwain.Create(self); Twain.OnTwainAcquire := TwainAcquireHandler; //manually set the event handler Twain.OnSourceFileTransfer := TwainSourceFileTransfer; Twain.OnSourceSetupFileXfer := TwainSourceSetupFileXfer; Twain.LoadLibrary; Twain.LoadSourceManager; Twain.Source.Loaded := TRUE; Twain.Source.TransferMode := ttmFile; Twain.Source.EnableSource(false, false); except on e : exception do showmessage('Error loading Scanner.'); end; try while Twain.Source.Enabled do Application.ProcessMessages; except on e : exception do showmessage('Error Scanning Packing List.'); end; finally Twain.Source.Loaded := FALSE; Twain.UnloadSourceManager(true); Twain.UnloadLibrary; Twain.Destroy; end;
Since the TDelphiTwain appears to be a component you are creating in code, I would recommend passing in nil for the constructor and calling the .Free method or (as suggested by Joseph) FreeAndNil.
Twain := TDelphiTwain.Create(nil); try try Twain.OnTwainAcquire := TwainAcquireHandler; //manually set the event handler Twain.OnSourceFileTransfer := TwainSourceFileTransfer; Twain.OnSourceSetupFileXfer := TwainSourceSetupFileXfer; Twain.LoadLibrary(); Twain.LoadSourceManager(); Twain.Source.Loaded := True; Twain.Source.TransferMode := ttmFile; Twain.Source.EnableSource(False, False); except on e : exception do showmessage('Error loading Scanner.'); end; try while Twain.Source.Enabled do Application.ProcessMessages; except on e : exception do showmessage('Error Scanning Packing List.'); end; Twain.Source.Loaded := False; Twain.UnloadSourceManager(True); Twain.UnloadLibrary(); finally FreeAndNil(Twain); end;
I would also recommend better exception handling, but not related to question you asked. The only thing users will see and report to you (or worse, the quiet guy in the corner responsible for your IT support who loves to get non-descriptive errors from users) is 'Error doing something'
Another area to look at is if the scanner supports WIA (Windows Image Acquisition)
var DevMgr: IDeviceManager; Scanner: Idevice; Picture: IItem; Image: OleVariant; AImage: IImageFile; begin DevMgr := CreateOleObject('WIA.DeviceManager') as IDeviceManager; // Figure out which device is the scanner Scanner:= DevMgr.DeviceInfos.Item.Connect; //Command: Figure out which command scans.. Picture := Scanner.ExecuteCommand(Scanner.Commands.Item.CommandID); //Transfer as JPG Image := Picture.Transfer(Picture.Formats.Item); //Save the image AImage := IImageFile(Image); AImage.SaveFile('c:\wia_viaScanner\image.' + AImage.FileExtension); end;
More info on the WIA library can be found here.. http://msdn.microsoft.com/en-us/library/ms629859(VS.85).aspx
Examining the code within these calls may be fruitful:
TwainAcquireHandler; TwainSourceFileTransfer; TwainSourceSetupFileXfer;
Do any of those create any objects without freeing them?
If you are using Delphi 2006 or higher, then you can add this line to your .DPR file:
ReportMemoryLeaksOnShutdown := True;
Then reproduce the memory leak, close your app... and it will describe the leaks in detail. A little more info about this can be found here.
On another note, I'd suggest replacing
.Destroy will call the destructor directly, while FreeAndNil is a safer alternative that will also prevent the "Twain" variable from pointing anywhere dangerous. (See the accepted answer to this question).
I can't address the problem you're reporting but you have a busy loop there that will gobble CPU time.
What are you doing when you get the Image, did you keep in memory? Or the library can have some memory leaks, you can check if it is true with FastMM4.
to KevinRF: I need to use WIA automation in Delphi 7 project. I registered WIAAut.dll in my system, import this library into Delphi and past your programm code into my project and got some errors:
Types of actual and formal var parameters must be identical in "Item" must be Item[var Index: OleVariant], but "1" is integer
What's wrong, what i need to made it works?