Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.170 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