AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Barcode aus Bild auslesen

Ein Thema von DSCHUCH · begonnen am 15. Mai 2011 · letzter Beitrag vom 16. Jun 2016
Antwort Antwort
Seite 1 von 3  1 23      
DSCHUCH

Registriert seit: 6. Jun 2007
Ort: Dresden
185 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#1

Barcode aus Bild auslesen

  Alt 15. Mai 2011, 19:41
Hallo,

kennt jemand eine Komponenten, mit der man aus einem Bild Barcodes auslesen kann? Derzeit verwenden wir BarcodeReader als Active-X, funktioniert eigentlich gut und ich habe auch nichts anderes gefunden, aber vielleicht auch etwas übersehen.

http://www.imagesinfo.com/products/barcode-reader/

Schönen Abend.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: Barcode aus Bild auslesen

  Alt 15. Mai 2011, 21:17
Da gäbe es noch http://www.qualitysoft.de/
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
DSCHUCH

Registriert seit: 6. Jun 2007
Ort: Dresden
185 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#3

AW: Barcode aus Bild auslesen

  Alt 16. Mai 2011, 08:35
sehr gut, sogar deutsch. ^^
  Mit Zitat antworten Zitat
Andreas Schilling

Registriert seit: 6. Sep 2006
106 Beiträge
 
Delphi 10.3 Rio
 
#4

AW: Barcode aus Bild auslesen

  Alt 16. Mai 2011, 09:10
Wir arbeiten damit.
http://www.java4less.com/barcodedelp...odesdelphi.php
  Mit Zitat antworten Zitat
Benutzerbild von Coffeecoder
Coffeecoder

Registriert seit: 27. Apr 2011
242 Beiträge
 
Delphi 6 Enterprise
 
#5

AW: Barcode aus Bild auslesen

  Alt 16. Mai 2011, 09:14
Sieht sehr interessant aus

Mfg Coffeecoder
Coffeecoder
  Mit Zitat antworten Zitat
generic

Registriert seit: 24. Mär 2004
Ort: bei Hannover
2.415 Beiträge
 
Delphi XE5 Professional
 
#6

AW: Barcode aus Bild auslesen

  Alt 16. Mai 2011, 12:26
Das erzeugt nur Barcodes - Erkennung kann ich dort nicht finden.
Coding BOTT - Video Tutorials rund um das Programmieren - https://www.youtube.com/@codingbott
  Mit Zitat antworten Zitat
Andreas Schilling

Registriert seit: 6. Sep 2006
106 Beiträge
 
Delphi 10.3 Rio
 
#7

AW: Barcode aus Bild auslesen

  Alt 16. Mai 2011, 12:35
Stimmt, aber der Anbieter war schon richtig. Ich hatte auf die Schnelle den ersten Link ausgewählt wo das Wort Barcode drinnen vorkam. Hier also der richtige Link.
http://www.java4less.com/vision/vision.php
  Mit Zitat antworten Zitat
squetk

Registriert seit: 29. Aug 2004
Ort: Cottbus
118 Beiträge
 
Delphi XE2 Professional
 
#8

AW: Barcode aus Bild auslesen

  Alt 16. Mai 2011, 14:06
Eine Open Source Variante wäre unter
http://zbar.sourceforge.net/index.html zu finden.
Ist zwar keine Delphi-Komponente, steuern wir aber mit Delphi.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.142 Beiträge
 
Delphi 12 Athens
 
#9

AW: Barcode aus Bild auslesen

  Alt 29. Jun 2011, 14:40
@qsquetk: Wie macht ihr das denn?

Ich hab's ja schon geschafft die ZBar-DLL anzusprechen, aber die Ergebnisse lassen zu Wünschen übrig.
Von 6 ausreichend guten Strichcodes auf einem eingescannten A4 Bild (~1600x2300 Pixelchen) werden nur 1 bis 5 erkannt + ein paar "nichtexistierende" Codes
Und das auch erst, wenn ich das Bild in kleineren Schritten um bis zu 90° drehe.
(die Nichtexistierende kann man bestimmt/vermutlich noch über dernen "Quallitätsangabe" rausfiltern)

Deren vorkompilierte EXE erkennt aber wesentlich mehr und zuverlässiger nur das, was auch drauf ist.
Auch ohne das Bild zu drehen und einfach nur wagerecht+senkrecht zu scannen.


[add]Achtung, das ist der nichtfunktionierende Code ... der Richtige wurde später gepostet [/add]
Delphi-Quellcode:
bmp := TBitmap.Create;
bmp.PixelFormat := pf8bit;
try
  bmp.Width := Source.Width;
  bmp.Height := Source.Height;
  bmp.Canvas.Draw(0, 0, Source);
  bmp.Width := (bmp.Width + 3) and not 3; // damit die Scannlines direkt aneinander liegen und alles zusammen übergeben werden kann
  bytesPerLine := (bmp.Width + 3) and not 3;
  p := bmp.ScanLine[bmp.Height - 1]; // die Bildzeilen gehen von unten nach oben
//for i := (bytesPerLine * bmp.Height) - 1 downto 0 do
// if p[i] > 200 then p[i] := 255 else p[i] := 0;
  scanner := zbar_image_scanner_create;
  image := zbar_image_create;
  try
    zbar_image_set_format(image, 'Y800');
    zbar_image_set_size(image, bmp.Width, bmp.Height);
    zbar_image_set_data(image, p, bmp.Height * bytesPerLine, nil);

    // Disable all symbologies?
    zbar_image_scanner_set_config(scanner, ZBAR_NONE, ZBAR_CFG_ENABLE, 0);

    // Set the resolution of the scanner to 4 pixels. Helps with skewed and poor quality bar codes.
    stat := zbar_image_scanner_set_config(scanner, ZBAR_NONE, ZBAR_CFG_X_DENSITY, Density);
    if stat <> 0 then raise Exception.Create('set config failed');

    stat := zbar_image_scanner_set_config(scanner, ZBAR_NONE, ZBAR_CFG_Y_DENSITY, Density);
    if stat <> 0 then raise Exception.Create('set config failed');

    for stype in BarType do begin
      // Enable the requested symbology
      stat := zbar_image_scanner_set_config(scanner, stype, ZBAR_CFG_ENABLE, 1);
      if stat <> 0 then raise Exception.Create('set config failed');

      // Enable the use of a check digit is requested
      if CheckDigit then
        zbar_image_scanner_set_config(scanner, stype, ZBAR_CFG_ADD_CHECK, 1);
    end;

    //
    count := zbar_scan_image(scanner, image);
    if count > 0 then begin
      symbol := zbar_image_first_symbol(image);
      while Assigned(symbol) do begin
        if AddBarType then
          Codes.Add(zbar_get_symbol_name(zbar_symbol_get_type(symbol)) + Codes.NameValueSeparator + zbar_symbol_get_data(symbol))
        else
          Codes.Add(zbar_symbol_get_data(symbol));

        // für's Debuggen markieren, was wo gefunden wurde
        SetLength(points, zbar_symbol_get_loc_size(symbol));
        if points <> nil then begin
          for i := 0 to Length(points) - 1 do begin
            points[i].X := zbar_symbol_get_loc_x(symbol, i);
            points[i].Y := bmp.Height - zbar_symbol_get_loc_y(symbol, i) - 1;
          end;
          bmp.Canvas.Brush.Style := bsDiagCross;
          bmp.Canvas.Brush.Color := clFuchsia;
          bmp.Canvas.Pen.Color := clFuchsia;
          bmp.Canvas.Pen.Width := 1;
          bmp.Canvas.Polyline(points);
          bmp.Canvas.Pen.Width := 4;
          bmp.Canvas.Ellipse(points[0].X - 15, points[0].Y - 15, points[0].X + 16, points[0].Y + 16);
          bmp.Canvas.Brush.Style := bsClear;
          bmp.Canvas.Font.Color := clRed;
          bmp.Canvas.Font.Size := 20;
          bmp.Canvas.TextOut(points[0].X + 14, points[0].Y + 14, zbar_symbol_get_data(symbol));
        end;

        symbol := zbar_symbol_next(symbol);
      end;
    end;

    // ebenfalls für's Debuggen
    bmp.SaveToFile(...);
  finally
    zbar_image_destroy(image);
    zbar_image_scanner_destroy(scanner);
  end;
finally
  bmp.Free;
end;

Die DLL wäre ja eigentlich recht schön, aber aktuell bin ich eher der Meinung, da es besser ist, wenn ich deren EXE aufrufe und dessen Ausgabe auslese.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (30. Jun 2011 um 13:12 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.142 Beiträge
 
Delphi 12 Athens
 
#10

AW: Barcode aus Bild auslesen

  Alt 30. Jun 2011, 13:21
So, hat mich etwas nerven gekostet, aber jetzt geht's

Delphi-Quellcode:
uses
  ZBar;

type
  TZbarSymbolTypes = set of zbar_symbol_type_e;

procedure ReadBarcode(Codes: TStrings; Source: TGraphic; AddBarType: Boolean = False;
  BarTypes: TZbarSymbolTypes = []; CheckDigit: Boolean = True; Density: Integer = 1);
var
  bmp: TBitmap;
  bytesPerLine, count, i: Integer;
  p, pg: PByte;
//processor: zbar_processor_t;
  scanner: zbar_image_scanner_t;
  image: zbar_image_t;
  stype: zbar_symbol_type_e;
  symbol: zbar_symbol_t;
  symboltype: zbar_symbol_type_t;
begin
  if BarTypes = [] then BarTypes := [ZBAR_EAN8, ZBAR_UPCE, ZBAR_ISBN10, ZBAR_UPCA, ZBAR_EAN13, ZBAR_ISBN13, ZBAR_I25, ZBAR_CODE39, ZBAR_CODE128];

  bmp := TBitmap.Create;
  bmp.PixelFormat := pf32bit;;
  try
    bmp.Width := Source.Width;
    bmp.Height := Source.Height;
    bmp.Canvas.Draw(0, 0, Source);

  //processor := zbar_processor_create(0);
  //Assert(Assigned(processor), 'zbar-processor');
  //try
  // if zbar_processor_init(processor, nil, Ord(False)) <> 0 then begin
  // zbar_processor_error_spew(processor, 0);
  // Assert(False, 'zbar-processor_init');
  // end;
  // zbar_processor_set_visible(processor, 0);

      scanner := zbar_image_scanner_create;
      Assert(Assigned(scanner), 'zbar-scanner');
      try
        zbar_image_scanner_set_config(scanner, ZBAR_NONE, ZBAR_CFG_ENABLE, 0);

        i := zbar_image_scanner_set_config(scanner, ZBAR_NONE, ZBAR_CFG_X_DENSITY, Density);
        Assert(i = 0, 'zbar-set_config');

        i := zbar_image_scanner_set_config(scanner, ZBAR_NONE, ZBAR_CFG_Y_DENSITY, Density);
        Assert(i = 0, 'zbar-set_config');

        for stype in BarTypes do begin
          i := zbar_image_scanner_set_config(scanner, stype, ZBAR_CFG_ENABLE, 1);
          Assert(i = 0, 'zbar-set_config');

          if CheckDigit then
            zbar_image_scanner_set_config(scanner, stype, ZBAR_CFG_ADD_CHECK, 1);
        end;

        image := zbar_image_create;
        Assert(Assigned(image), 'zbar-image');
        try
          bytesPerLine := bmp.Width;
          p := bmp.ScanLine[bmp.Height - 1]; // die Bildzeilen gehen von unten nach oben
          pg := GetMemory(bmp.Height * bytesPerLine);
          try
            for i := bmp.Height * bytesPerLine downto 0 do
              pg[i] := Round(p[i*4]*0.3 + p[i*4+1]*0.59 + p[i*4+2]*0.11);

            zbar_image_set_format(image, 'Y800');
            zbar_image_set_size(image, bmp.Width, bmp.Height);
            zbar_image_set_data(image, pg, bmp.Height * bytesPerLine, nil);

            count := zbar_scan_image(scanner, image);
          //zbar_process_image(processor, image); count := 1;
          finally
            FreeMemory(pg);
          end;

          if count > 0 then begin
            symbol := zbar_image_first_symbol(image);
            while Assigned(symbol) do begin
              symboltype := zbar_symbol_get_type(symbol);
              if AddBarType then
                Codes.Add(String(AnsiString(zbar_get_symbol_name(symboltype)) + AnsiString(zbar_get_addon_name(symboltype)))
                  + Codes.NameValueSeparator + String(AnsiString(zbar_symbol_get_data(symbol))))
              else
                Codes.Add(String(AnsiString(zbar_symbol_get_data(symbol))));

              symbol := zbar_symbol_next(symbol);
            end;
          end;
        finally
          zbar_image_destroy(image);
        end;
      finally
        zbar_image_scanner_destroy(scanner);
      end;
  //finally
  // zbar_processor_destroy(processor);
  //end;
  finally
    bmp.Free;
  end;
end;
Wer schräge Barcodes einscännen will/muß, der braucht einfach nur das Bild zu drehen, denn die ZBar-Barcode-Komponente scännt nur in 90°-Winkeln (wagerecht und senkrecht).
z.B. von 0° bis <90° in 10°-Schritten
oder einfach nur noch einmal 45°
oder 0°, 22°, 45° und 68°

Da könnte man z.B. direkt in den Block nach image := zbar_image_create; eine entsprechende Schleife einbauen.
Eventuell dann auch noch die StringListe mit .Sort:=True und .Duplicates:=dupIgnore .

Delphi-Quellcode:
procedure RotateBitmap(Dest, Source: TBitmap; Winkel: Double; Hintergrund: TColor = clWhite; GroesseAnpassen: Boolean = True);
type
//TArray = array[0..0] of Byte; {pf8bit}
//TArray = array[0..0] of array[0..1] of Byte; {pf16bit}
//TArray = array[0..0] of array[0..2] of Byte; {pf24bit}
  TArray = array[0..0] of array[0..3] of Byte; {pf32bit}
  PArray = ^TArray;
var
  rw: Boolean;
  CT, ST: Double;
  I, J, X, Y, SrcW, SrcH, SrcWD, SrcHD, SrcWD2, SrcHD2: Integer;
  ScanS, ScanD: array of PArray;
  XCT, XST: Integer;
  YCT, YST: array of Integer;
begin
//Source.PixelFormat := pf8bit;
//Source.PixelFormat := pf16bit;
//Source.PixelFormat := pf24bit;
  Source.PixelFormat := pf32bit;
  Dest.PixelFormat := Source.PixelFormat;
  Winkel := 360 - Winkel;
  while Winkel > 360 do Winkel := Winkel - 360;
  while Winkel < 0 do Winkel := Winkel + 360;
  Winkel := Winkel * PI / 180;
  ST := Sin(Winkel);
  CT := Cos(Winkel);
  rw := Frac(Winkel / 90) = 0;
  if not GroesseAnpassen then begin
    Dest.Width := Source.Width;
    Dest.Height := Source.Height;
  end else if ST * CT < 0 then begin
    Dest.Width := Round(Abs(Source.Width * CT - Source.Height * ST));
    Dest.Height := Round(Abs(Source.Width * ST - Source.Height * CT));
  end else begin
    Dest.Width := Round(Abs(Source.Width * CT + Source.Height * ST));
    Dest.Height := Round(Abs(Source.Width * ST + Source.Height * CT));
  end;
  with Dest.Canvas do begin
    Brush.Style := bsSolid;
    Brush.Color := Hintergrund;
    FillRect(ClipRect);
  end;
  SrcWD := Source.Width;
  SrcHD := Source.Height;
  SrcWD2 := Source.Width div 2;
  SrcHD2 := Source.Height div 2;
  if CT < 0 then Dec(SrcWD2);
  if ST < 0 then Dec(SrcHD2);
  SetLength(ScanS, Source.Height);
  SetLength(ScanD, Dest.Height);
  for I := Source.Height - 1 downto 0 do ScanS[I] := Source.ScanLine[I];
  for I := Dest.Height - 1 downto 0 do ScanD[I] := Dest.ScanLine[I];
  SetLength(YCT, Dest.Height);
  SetLength(YST, Dest.Height);
  for J := 0 to Dest.Height - 1 do begin
    if rw then
      Y := Trunc(J - Dest.Height / 2 + 0.5)
    else
      Y := J - Dest.Height div 2;
    YCT[J] := Round(Y * CT * 4 + 2);
    YST[J] := Round(Y * ST * 4 + 2);
  end;
  for I := 0 to Dest.Width - 1 do begin
    if rw then
      X := Trunc(I - Dest.Width / 2)
    else
      X := I - Dest.Width div 2;
    XCT := Round((X * CT + SrcWD2) * 4);
    XST := Round((X * ST + SrcHD2) * 4);
    for J := 0 to Dest.Height - 1 do begin
      SrcW := (XCT - YST[J]) shr 2; {... div 4}
      SrcH := (XST + YCT[J]) shr 2;
      if (SrcH >= 0) and (SrcH < SrcHD) and (SrcW >= 0) and (SrcW < SrcWD) then
        ScanD[J][I] := ScanS[SrcH][SrcW];
    end;
  end;
end;
Benötigt wird nur die angehängte Zbar.pas und die libzbar-0.dll von zbar.sourceforge.net, bzw. aus dem Anhang.


Das die Zbar.pas wurde natürlich auch gleich mit auf Unicode angepaßt ... läuft aber weiterhin auch mit ANSI.
Angehängte Dateien
Dateityp: pas ZBar.pas (66,4 KB, 459x aufgerufen)
Dateityp: zip zbar-0.10.zip (106,6 KB, 401x aufgerufen)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (30. Jun 2011 um 15:45 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


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 21:01 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