Einzelnen Beitrag anzeigen

Schwedenbitter

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

AW: Leere Seite (blank page) filtern bei DelphiTwain

  Alt 25. Aug 2015, 18:40
Danke für Eure Antworten!
... Soweit ich mich erinnere, kann man aber auch ein Bild von Grau in Schwarz-Weiß umwandeln, indem man die Helligkeitsstufe festlegt, ab welcher das jeweilige Pixel weiß sein soll. Da würde ich mal ansetzen.
Dieser letzte Satz hat mich auf die - aus meiner Sicht - richtige Fährte geschickt. Für mich habe ich das Problem gelöst.

Zunächst habe ich das Bild nach schwarz/weiß umgewandelt. Mein nächster Ansatz war es dann, die schwarzen Pixel zu zählen. Anschließend habe ich diese mit den weißen ins Verhältnis gesetzt und ab einem Wert von 3 ‰ (Promille) das Bild als Bild mit Inhalt deklariert. Allerdings war das sehr fehlerbehaftet. Denn es gibt nicht nur Staub, Falten etc., sondern dann auch schwarze Ränder und - überholter Beitrag - schwarze Löscher.
Also schneide ich jetzt die Ränder innerhalb bestimmter Grenzen ab. Anschließend zähle ich die Anzahl der schwarzen Pixel. Wenn diese einen absoluten Wert überschreiten, ist es kein leeres Bild mehr. Das beschleunigt sogar die Suche, weil ich dann die Procedure verlassen kann.

Hier mein Code fürs Protokoll:
Delphi-Quellcode:
// Leeres Bild erkennen --------------------------------------------------------
// MaxBlack ist die Anzahl maximal zulässiger schwarzer Pixel.
// Beim Scannen können schwarze Ränder, Staubkörner etc. auftreten. Um ein
// möglichst genaues Ergebnis zu erzielen werden zuerst die Ränder abge-
// schnitten und dann die Anzahl der dunkeln/schwarzen Pixel ermittelt.
// Der Wert selbst dürfte hardwareabhängig sein und kann deshalb als Variable
// übergeben werden.
Function TScanForm.PictureIsEmpty(Const BitMap: TBitmap;
   Const MaxBlack: Integer = 75): Boolean;
Const
   lMargin         = 12;                              // linker Rand
   rMargin         = 8;                              // rechter Rand
   bMargin         = 4;                              // unterer Rand
   tMargin         = 8;                              // oberer Rand
   Tolerance      = 118;                           // guter Schwarz-Wert
Var
   lWidth         : Integer;
   lHeight         : Integer;
   lBlack         : Int64;
   I, J            : Integer;
   lLine            :^TRGBTriple;
Begin
   Result:=True;                                    // ausgehen von leerem Bild
   lWidth:= BitMap.Width - lMargin - rMargin;      // maximale Breite
   lHeight:=BitMap.Height - tMargin - bMargin;      // maximale Höhe
   BitBlt(Bitmap.Canvas.Handle, 0, 0, lWidth, lHeight,
      Bitmap.Canvas.Handle, lMargin, tMargin, SRCCOPY);
   BitMap.Width :=lWidth;
   BitMap.Height:=lHeight;
   If (Bitmap.PixelFormat <> pf24bit) Then
       Bitmap.PixelFormat := pf24bit;               // wegen Scanline
   lBlack:=0;                                       // schwarze Pixel

   For I:=0 To Pred(Bitmap.Height) Do               // alle Zeilen durchgehen
   Begin
      lLine:=Bitmap.Scanline[I];                     // Zeile zuweisen
      For J:=0 To Pred(Bitmap.Width) Do            // Zeile abarbeiten
      Begin
         If (lLine^.rgbtred + lLine^.rgbtBlue +
               lLine^.rgbtgreen) Div 3 < Tolerance Then
            Inc(lBlack);                           // = dunkler Wert -> schwarz
         If (lBlack >= MaxBlack) Then               // viele schwarze Pixel
         Begin
            Result:=False;                           // = Bild mit Inhalt
//         Exit;                                    // Zeit sparen!!!
         End;
         Inc(lLine);                                 // nächste Zeile durchsuchen
      End;
   End;

// TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TE
   fList.Append(IntToStr(fCount) + ';' + IntToStr(BitMap.Height * BitMap.Width) +
      ';' + IntToStr(lBlack));
// TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TE
End;
Alex Winzer
  Mit Zitat antworten Zitat