![]() |
TWAIN-Problem (TDelphiTwain versagt)
Hi,
momentan versuche ich meinem Bildverarbeitungsprogramm TWAIN import beizubringen, leider gibt es da ein gewaltiges Problem: der TWAIN import sollte nur ein kleines "nice-to-have" sein und ich dachte, dass die DelphiTwain-Komponente genau das richtige wäre. Nun hat sich aber herausgestellt, dass die Implementierung nicht mit dem Leica DFC Twaintreiber klarkommt und das bereitet mir ernsthafte Magenschmerzen, denn weder mein selbstgefummeltes Programm, noch die Beispielprogramme zur Komponente können das Bild überhaupt importieren. Die TWAIN sample application von twain.org ist zwar merklich langsamer, kann allerdings immerhin ein Bild in eine Datei schreiben (ich gehe davon aus, dass der Importmodus schon so gewählt ist). Bevor ich mich nun also durch tonnenweise C++ Beispielcode wühle - hat jemand schon Erfahrungen mit TWAIN gemacht, da der Import von Bildern mit dem Beispielcode nicht funktionierte? schonmal ein dickes Danke für eure Hilfe! hboy ps. ![]() ![]() |
AW: TWAIN-Problem (TDelphiTwain versagt)
Hallo...
so einfach läßt sich das nicht sagen was zu tun ist. Zeig mal deinen Code und dann schaun wir mal. Ich hatte mal Probleme mit einem Twain Treiber der den Scanner via IP ansprach. Letztendlich war ein wenig Umstellen angesagt. ...schaun wir mal :zwinker: |
AW: TWAIN-Problem (TDelphiTwain versagt)
- -
|
AW: TWAIN-Problem (TDelphiTwain versagt)
Liste der Anhänge anzeigen (Anzahl: 1)
Delphi-Quellcode:
procedure TForm1.OnTwainAcquire(Sender: TObject; const Index: Integer;
Image: TBitmap; var Cancel: Boolean); var newidx: integer; datestr: string; devname: string; begin // ... glm.Layers[newidx].data.Canvas.Draw(0,0,image); //... Cancel := False; TwainHelper.FinishAcquisition; end; sorry, dass der code auf sich warten lassen musste, ich war nicht zuhause am PC und hatte unterwegs auch nur das compilierte Programm dabei. Meine Implementierung ist recht simpel vom Beispielcode abgeleitet, ich mache auch keine Einstellungen und so ganz zufrieden bin ich damit natürlich nicht. Da aber auch das "fullfeatures"-Beispiel mit allen verschiedenen Modi nicht hinkriegt, ein Bild zu importieren, zweifle ich etwas daran, ob es so sinnvoll ist, mit TDelphiTwain weiterzumachen :( Vielleicht muss ich doch den anderen code mal fläddern. Nochmal zur Problembeschreibung: Die Quellenauswahl klappt soweit, sobald ich beim UI der Kamerasoftware auf "transferieren" klicke läuft eine Progressbar bis 60..80%, danach verschwindet der Dialog und weiter passiert nichts, es gibt auch keine Fehlermeldung. Es gibt von Leica auch einen dummytreiber, der eine Kamera simuliert, die sich gleichermaßen bockig stellt. Ich schaue mal, ob der irgendwo zu bekommen ist, damit kann man zumindest mal Trockenübungen machen. ps. unter ![]() |
AW: TWAIN-Problem (TDelphiTwain versagt)
Nun denn,
ich habe die Chose noch etwas massiert und bin an der Stelle angelangt, dass
Delphi-Quellcode:
mir nur TWRC_FAILURE zurückliefert, das wäre der Anfang des Transferprozesses. Ich war so frei, noch messageboxes einzuführen, die mir zunächst den Wert von GetReturnStatus anzeigen, bis ich dann herausgefunden habe, dass der Rückgabewert von TwainProc, der aussagt, ob diese überhaupt erfolgreich war, weggeworfen wird und so Phantasiewerte für den TW_STATUS.ConditionCode rauskommen.
{Transfer image memory}
function TTwainSource.TransferImageMemory(var ImageHandle: HBitmap; PixelType: TW_INT16): TW_UINT16; var {...} begin {Obtain information on the transference buffers} Result := Owner.TwainProc(AppInfo, @Structure, DG_CONTROL, DAT_SETUPMEMXFER, MSG_GET, @Setup); {...} Meine Vermutung wäre, dass die Twainquelle (Leica DFC Demokamera) es schon nicht hinbekommt, in den bereitgestellten Speicher zu schreiben und dann abbricht - wenn nicht schon vorher. Ich habe auch schon etwas im funktionierenden c++-Code der Testapplikation von twain.org herumgelesen, allerdings ohne Erfolg. Kann mir jemand einen Ratschlag geben, wie ich weiter debuggen kann, ohne die 664 Seiten der Twain 2.1 Spezifikationen durchzulesen? Danke schonmal. ps. das Bitmap wird, soweit ich es auf den ersten Blick beurteilen konnte, noch korrekt erzeugt, wenn man den return code überschreibt, kommt ein schwarzes Bild an, das einen korrekten Header hat. Irgendwas geht zwischen dem Start der GUI und dem Callback kaputt... |
AW: TWAIN-Problem (TDelphiTwain versagt)
Zitat:
|
AW: TWAIN-Problem (TDelphiTwain versagt)
Zitat:
Delphi-Quellcode:
wird der angelegte Buffer verworfen, der Rückgabewert von TransferImageMemory ist TWRC_FAILURE und das wars. Wenn man der Transfervorbereitungsfunktion ein TWRC_SUCCESS unterjubelt, kommt ein mit $00 gefüllter Puffer an.
if Result <> TWRC_XFERDONE then
DeleteObject(ImageHandle); Ich tappe leider noch ziemlich im Dunkeln, warum nun eigentlich ein Fehler auftritt. Denkbar wäre, dass sich die Implementierung von Leica den Puffer oder irgendwelche flags anders vorgestellt hätte und schon vor dem Transfer den Modus verlässt, in welchem die Strukturinformationen verfügbar sind. |
AW: TWAIN-Problem (TDelphiTwain versagt)
Zitat:
|
AW: TWAIN-Problem (TDelphiTwain versagt)
Dennoch Danke für die Bemühungen :-)
Ich habe die Geschichte noch etwas weiter verfolgt und schrittweise die Werte beäugt, alles scheint gut zu gehen, bis in TransferImageMemory
Delphi-Quellcode:
aufgerufen wird.
{Retrieve another piece of memory to the pointer}
Xfer.BytesWritten := 0; Result := Owner.TwainProc(AppInfo, @Structure, DG_IMAGE, DAT_IMAGEMEMXFER, MSG_GET, @Xfer); |
AW: TWAIN-Problem (TDelphiTwain versagt)
Ich habe nun ein Bild (die Lösung ist denkbar einfach gewesen und obendrein recht dämlich: der Leica DFC TWAIN-Treiber unterstützt ttmMemory nicht - nur ttmNative. Die Demokamera funktioniert nun, ich hoffe, dass es im echten Leben dann auch tut...). Die Auflösung lässt sich nicht ändern und es dauert auch eine Sekunde zum herausleiern, aber es tut soweit.
In TransferImageMemory habe ich diesen Block hinzugefügt, durch den man auf die Nichtanwendbarkeit vom ttmMemory Transfermode hingewiesen wird.
Delphi-Quellcode:
In DelphiTwain.pas habe ich GetReturnStatus modifiziert:
{...}
end {TWRC_SUCCESS} else begin if Result = TWRC_FAILURE then begin // TWCC_ constant if GetReturnStatus <> $FFFF then Windows.MessageBox(0,PChar('Error '+IntToStr(GetReturnStatus)), 'Acquisition error',0) else Windows.MessageBox(0,'An error occured in TransferImageMemory.'+ #13#10'Aditionally, GetReturnStatus failed.','Acquisition error',0); end; end; {...}
Delphi-Quellcode:
{Returns return status information}
function TTwainSource.GetReturnStatus: TW_UINT16; var StatusInfo: TW_STATUS; rc : TW_UINT16; begin {The source must be loaded in order to get the status} if Loaded then begin {Call method to get the information} rc := Owner.TwainProc(AppInfo, @Structure, DG_CONTROL, DAT_STATUS, MSG_GET, @StatusInfo); Result := StatusInfo.ConditionCode; if rc <> TWRC_SUCCESS then Result := $FFFF; // bad things have happened end else Result := 0 {In case it was called while the source was not loaded} end; Mit der Wandlungsroutine für Fix32 bin ich auch noch nicht zufrieden, sie scheint irgendwie falsch zu sein. Ich habe mich mal an die Implementierung von GIMP gehalten:
Delphi-Quellcode:
//Convert from extended to Fix32
function FloatToFIX32(floater: Extended):TW_FIX32; begin result.Whole := trunc(floater); result.Frac := round( abs(floater - trunc(floater)) * 65536.0 ) and $FFFF; end; //Convert from twain Fix32 to extended function FIX32ToFloat(Value : TW_FIX32):Extended; begin if Value.Whole < 0 then // remember that frac part is unsigned Result := Value.Whole - Value.Frac / 65536.0 else Result := Value.Whole + Value.Frac / 65536.0; end; |
AW: TWAIN-Problem (TDelphiTwain versagt)
Noch zwei Feststellungen für den heutigen Abend:
1) Problem: bei geöffnetem user interface ist nur einmaliges scannen und einmaliges Übertragen von Bildern möglich. Lösung:
Delphi-Quellcode:
enthält
{Method to transfer the images}
procedure TTwainSource.TransferImages();
Delphi-Quellcode:
weg mit dem enabled! Sobald die Variante ohne UI fertig ist, wird eine message in der message loop des virtuellen Fensters bearbeitet, die SourceDisable zur Folge hat, wohin ggf. der OnSourceDisable Event ausgelöst wird. Mit UI wird diese Eventfolge beim Schließen des UIs durch den Nutzer angestoßen.
repeat
{ ... hier werden alle ausstehenden Bilder übertragen, bis PendingXfers = 0 ist ... } until Done; {Disable source} Enabled := False; // <--- das ist Blödsinn. end; 2) Creative LiveCam Vista mag (wie wohl viele andere auch...) nach dem ersten Bilderholen nicht mehr aufnehmen Oft ist es notwendig, eine Quelle neu zu laden. Dies habe ich nun auf den Start des Importierens verlegt. Dies macht die Sache im Vergleich zu fortlaufender Ausführung merklich langsamer, jedoch ist das die einzige Methode, die bei allen meinen Testquellen funktioniert.
Delphi-Quellcode:
if assigned(CallbackEvent) then
begin MainTwainObject.OnTwainAcquire := CallbackEvent; end; with MainTwainObject.Source[MainTwainSource] do begin if Loaded then UnloadSource; // <-- Neustart für mehr Kompatibilität Loaded := TRUE; ShowUI := TRUE; TransferMode := TransferModeChoice; Enabled := TRUE; end; das "streamen" von Bilddaten werde ich ohnehin anders lösen, daher ist dieser Kompromiss hinnehmbar. |
AW: TWAIN-Problem (TDelphiTwain versagt)
Liste der Anhänge anzeigen (Anzahl: 1)
Also beim Lesen Deiner Beschreibungen sind mir 3 Dinge aufgefallen:
Melde mal bitte, ob das bei Dir/Deinem Scanner/Deiner Kamera funktioniert. Gruß, Alex |
AW: TWAIN-Problem (TDelphiTwain versagt)
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:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:40 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz