Mit meinem Bildbearbeitungsprogramm möchte ich Bildbearbeitung und -Analysefunktionalität haben. So arbeite ich momentan an einem Korrelierer, wodurch man ein vorgegebenes Muster auf der aktuellen Ebene wiederfinden kann. Die TWAIN-Quelle tritt dabei nochmals auf in Form einer selbstaktualisierenden Ebene , die (letztenendes mit hoffentlich mehr als 1fps) das jeweils neue Bild von der Quelle holt und den Filterstapel darauf anwendet. Die Bildanalyse wird einer dieser Filter sein, neben Kanalmischung (die Kamera produziert im Blaukanal quasi nur Abberationen) und anderen Filtern nach dem Geschmack des Nutzers, wie Schärfung, Helligkeit/Kontrast etc.
Es können dann verschiedene Skalenbemaßungen aufgetragen werden, sodass die Relativkoordinaten der Verschiebungen der wiedergefundenen Muster in physikalischen Längeneinheiten angebbar sind.
Ich erachte das SourceDisable nach dem Holen der Bilder als Unfug, da es zwar vom Ablauf her notwendig sein kann, falls die Implementierung der Quelle schlampig ist, jedoch verbaut diese Vorgehensweise die Möglichkeit, aus einem laufenden UI nochmals Bilder zu übertragen. Konsequent müsste man DisableSource und UnloadSource anwenden, vollkommen richtig - dann ist zumindest das UI weg und die Ansicht konsistent mit den dem Nutzer verbleibenden Möglichkeiten (keine), jedoch setzt gerade das von Leica in Auftrag gegebene Interface wie auch die Implementierung der Creative Steuersoftware darauf, während einer laufenden UI-Session beliebig oft Bilder übertragen zu können. Bei dem UI meines scanners ist es wahrscheinlich das gleiche, dort habe ich erneutes capturing jedoch noch nicht getestet.
Der bestmögliche Kompromiss nach meinem Ermessen ist daher, das "plattmachen" der TWAIN-Quelle auf das Ereignis zu verschieben, bei dem der Nutzer eine neue Quelle wählt oder erneut auf Import klickt.
Das Beispielprogramm habe ich getestet, es läuft mit meinen Modifikationen an DelphiTwain gut, auch mehrmaliges Importieren von Bildern läuft problemlos.
Ein paar Punkte bleiben nun jedoch noch offen:
- Das Behandeln von Fehlern sollte den eigens dafür eingerichteten error handler nutzen, hier meine Änderung in TransferImageMemory:
Delphi-Quellcode:
else
begin
if Result = TWRC_FAILURE then
begin
// added some error handling and messages in case errors are left unhandled
//
if GetReturnStatus <> $FFFF then
begin
if assigned(Owner) then
if assigned(Owner.fOnAcquireError) then
Owner.fOnAcquireError(self,index,TWRC_FAILURE,GetReturnStatus)
else
Windows.MessageBox(0,PChar('Error '+IntToStr(GetReturnStatus)),
'Acquisition error',0);
end
else
if assigned(Owner.fOnAcquireError) then
Owner.fOnAcquireError(self,index,TWRC_FAILURE,GetReturnStatus)
else
Windows.MessageBox(0,'An error occured in TransferImageMemory.'+
#13#10'Aditionally, GetReturnStatus failed.','Acquisition error',0);
end;
end;
- @Schwedenbitter: die Implementierung ist, wenn man kleinlich sein will, nur für positive Zahlen korrekt. Ich hätte ein ungutes Gefühl dabei, eine so allgemein betitelte Routine bei negativen Werten nicht-konforme Werte ausgeben zu lassen. Soweit ich es verstanden habe, und nur dann hat der Wert 65536 auch einen Sinn, ist Frac ohne Signum zu speichern, also als Typ WORD. Das führt dazu, dass für hypothetische Negativwerte etwa -0.3 auf +0.7 abgebildet wird, damit sind die angegebenen Routinen im allgemeinen Fall inkonsistent.
- Wo liegt denn nun genau der Hund bei ttmMemory begraben? Ich habe die Vermutung, dass einige Codesegmente aus C-Code übersetzt sind, wofür schon die in Delphi nicht notwendige Float-Formatierung der Konstante als xxxxx.0 spräche. In der TWAIN Spezifikation sind ebenfalls einige Beispielsegmente gegeben. Ist es ein Berechnungsfehler bei den Adresszeigern, der manchmal zu Buche schlägt, ein Zugriffsproblem wegen TWMF_APPOWNS oder ein Kommunikationsfehler?