AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia TWAIN-Problem (TDelphiTwain versagt)

TWAIN-Problem (TDelphiTwain versagt)

Ein Thema von hboy · begonnen am 3. Sep 2010 · letzter Beitrag vom 6. Okt 2010
Antwort Antwort
Seite 2 von 2     12
hboy

Registriert seit: 16. Jan 2004
364 Beiträge
 
#11

AW: TWAIN-Problem (TDelphiTwain versagt)

  Alt 30. Sep 2010, 22:58
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:
{Method to transfer the images}
procedure TTwainSource.TransferImages();
enthält
Delphi-Quellcode:
  repeat
      { ... hier werden alle ausstehenden Bilder übertragen, bis PendingXfers = 0 ist ... }
  until Done;

  {Disable source}
  
  Enabled := False; // <--- das ist Blödsinn.

end;
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.


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.
Power is nothing without TControl
  Mit Zitat antworten Zitat
Schwedenbitter

Registriert seit: 22. Mär 2003
Ort: Finsterwalde
622 Beiträge
 
Turbo Delphi für Win32
 
#12

AW: TWAIN-Problem (TDelphiTwain versagt)

  Alt 4. Okt 2010, 18:16
Also beim Lesen Deiner Beschreibungen sind mir 3 Dinge aufgefallen:
  1. Wie Du selbst schon festgestellt hast und wie ich Dir bereits in der PM mitgeteilt hatte, gibt es einen Fehler mit TDelphiTwain.TransferMode := ttmMemory;. Ich halte das auch nicht für ein Problem der jewiligen Twain-Software, sondern vielmehr für eines von TDelphiTwain. Da die Komponente aber - soweit ich das beurteilen kann - nicht mehr weiterentwickelt wird, wird sich daran auch nichts mehr ändern.
    Die Weiterentwicklung macht auch nicht wirklich Spaß. Denn viele Hersteller halten sich nicht exakt an die Spezifikationen und damit kann man z.B. viele Einstellungen am Scanner nur noch mit der mitgelieferten Software vornehmen. Schade eigentlich.
  2. Die Zitate des Quellcode sind für mich teilweise nicht nachvollziehbar. Aber das Enabled := False; ist m.E. keineswegs Blödsinn. Der Schöpfer von TDelphiTwain hatte offensichtlich auch gemerkt, dass eben einige Hersteller von Twain-Software kein Ende anzeigen und damit OnSourceDisable eben nicht ausgelöst wird.
    Ich gehe sogar noch weiter. Bei mir steht in OnTwainAcquireCancel explizit ein TDelphiTwain.Source[FScanner].UnloadSource;.
  3. FloatToFIX32(); und FIX32ToFloat(); sind buggy. Dazu findet man im Netz einiges und auch eine Anleitung, wie man den Fehler behebt. Ich schicke Dir gern per PM meine Version(en).[EDIT]
    Delphi-Quellcode:
    function FloatToFix32 (floater: extended): TW_FIX32;
    {var
      fracpart : extended;}

    begin
      { Original-Code : .............
      //Obtain numerical part by truncating the float number
      Result.Whole := trunc(floater);
      //Obtain fracional part by subtracting float number by
      //numerical part. Also we make sure the number is not
      //negative by multipling by -1 if it is negative
      fracpart := floater - result.Whole;
      if fracpart < 0 then fracpart := fracpart * -1;
      //Multiply by 10 until there is no fracional part any longer
      while FracPart - trunc(FracPart) <> 0 do fracpart := fracpart * 10;
      //Return fracional part
      Result.Frac := trunc(fracpart);    }


      { Neuer Code: }
      Result.Whole:=trunc(floater);
      Result.Frac:=trunc(frac(floater)*65536.0);
    end;

    {Convert from twain Fix32 to extended}
    function Fix32ToFloat(Value: TW_FIX32): Extended;
    begin
      Result := Value.Whole + (Value.Frac / 65536.0);
    end;
    [/EDIT]
Ich habe Deine Eingangsfrage so verstanden, dass Du ein Grafikprogramm geschrieben hast, welches als Zugabe einen Scanner ansteuern soll. Es sollen also vermutlich mehrere Scanner damit funktionieren. Ich habe mal ein sehr kleines Beispielprogramm beigefügt. Dieses enthält den Aufbau in exakt derselben Art und Weise, wie ich mit den Scannern und den Bildern umgehe.
Melde mal bitte, ob das bei Dir/Deinem Scanner/Deiner Kamera funktioniert.

Gruß, Alex
Angehängte Dateien
Dateityp: zip TwainTest_p.zip (2,7 KB, 23x aufgerufen)
Alex Winzer

Geändert von Schwedenbitter ( 4. Okt 2010 um 18:19 Uhr)
  Mit Zitat antworten Zitat
hboy

Registriert seit: 16. Jan 2004
364 Beiträge
 
#13

AW: TWAIN-Problem (TDelphiTwain versagt)

  Alt 6. Okt 2010, 12:15
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?
Power is nothing without TControl
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:28 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz