Werkzeug um Belege zu scannen, Texterkennung durchzuführen und Belege sortiert abzulegen
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

347 lines
8.7 KiB

unit scanner;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtDlgs,
StdCtrls, ExtCtrls, Calendar, Unix;
type
{ ScanThread }
ScanThread = class(TThread)
private
dbtn, sbtn : TButton;
folder,r :String;
s:TPoint;
p:TImage;
protected
procedure Execute; override;
public
constructor Create(scanButton: TButton; dir: String; size: TPoint; resolution: String; preview: TImage; dropButton: TButton);
end;
{ TScanForm }
TScanForm = class(TForm)
Swap: TButton;
DropButton: TButton;
Calendar: TCalendar;
PicSize: TComboBox;
Preview: TImage;
Stop: TComboBox;
DPI: TLabel;
BaseFolder: TLabel;
Resolution: TComboBox;
BaseFolderDialog: TSelectDirectoryDialog;
ScanButton: TButton;
Product: TComboBox;
Destination: TComboBox;
FolderName: TLabel;
Origin: TComboBox;
TypeSelector: TComboBox;
procedure BaseFolderClick(Sender: TObject);
procedure DropButtonClick(Sender: TObject);
procedure CalendarChange(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure ProductChange(Sender: TObject);
procedure DestinationChange(Sender: TObject);
procedure OriginChange(Sender: TObject);
procedure ScanButtonClick(Sender: TObject);
procedure StopChange(Sender: TObject);
procedure SwapClick(Sender: TObject);
procedure TypeSelectorChange(Sender: TObject);
function ExportConfig(): string;
function ExportOptions(dropDown: TComboBox): string;
procedure UpdateFolder();
procedure MixLocations(d1: TComboBox; d2: TComboBox; d3: TComboBox);
private
date: TDateTime;
function getSize(): TPoint;
public
end;
var
ScanForm: TScanForm;
implementation
{$R *.lfm}
{ ScanThread }
constructor ScanThread.Create(scanButton: TButton; dir: String; size: TPoint; resolution: String; preview: TImage; dropButton: TButton );
begin
sbtn := scanButton;
dbtn := dropButton;
folder:=dir;
s:=size;
r:=resolution;
p:=preview;
inherited Create(false);
end;
procedure ScanThread.Execute;
var
fname: String;
num: Integer;
pic: TPicture;
begin
ForceDirectories(folder);
num := 0;
repeat
num := num +1;
fname := 'scan_';
if (num<10) then fname:=fname+'0';
if (num<100) then fname:=fname+'0';
if (num<1000) then fname:=fname+'0';
fname := fname+IntToStr(num)+'.jpg';
until not FileExists(folder+fname);
fpSystem('scanimage -x '+IntToStr(s.x)+' -y '+IntToStr(s.y)+' --mode Color --resolution '+r+' --format jpeg > "'+folder+fname+'"');
try
pic:=TPicture.Create;
pic.LoadFromFile(folder+fname);
p.Picture:=pic;
p.Hint:=folder+fname;
finally
end;
dbtn.Hint:=folder+fname;
dbtn.Caption:=fname+' löschen';
dbtn.Enabled:=true;
sbtn.Enabled:=true;
end;
function allowed(s: String): boolean;
begin
Result := true;
if (s = '') then Result := false;
if (s = 'Start') then Result := false;
if (s = 'Ziel') then Result := false;
if (s = 'Zwischenhalt') then Result := false;
end;
procedure TScanForm.MixLocations(d1: TComboBox; d2: TComboBox; d3: TComboBox);
var
list: TStringList;
begin
list := TStringList.Create;
list.Sorted := True;
if (allowed(d1.Text)) then d1.Items.Add(d1.Text);
if (allowed(d2.Text)) then d2.Items.Add(d2.Text);
if (allowed(d3.Text)) then d3.Items.Add(d3.Text);
list.Assign(d1.Items);
list.AddStrings(d2.Items);
list.AddStrings(d3.Items);
d1.Items.Assign(list);
d2.Items.Assign(list);
d3.Items.Assign(list);
end;
function TScanForm.ExportConfig(): string;
begin
Result := 'folder:'+BaseFolder.Caption+#13;
Result := Result + 'types:' + ExportOptions(TypeSelector) + #13;
Result := Result + 'items:' + ExportOptions(Product) + #13;
MixLocations(Origin, Destination, Stop);
Result := Result + 'locations:' + ExportOPtions(Origin) + #13;
Result := Result + 'sizes:' + ExportOptions(PicSize) +#13;
end;
function TScanForm.ExportOptions(dropDown: TComboBox): string;
var
list: TStringList;
begin
// make sure the current text appears in future lists
dropDown.Items.Add(dropDown.Text);
// create a StringList to sort and concatenate
list := TStringList.Create;
list.StrictDelimiter := True;
list.Sorted := True;
// put all items in the list, will sort and remove duplicates
list.Assign(dropDown.Items);
// update dropdown
dropDown.Items.Assign(list);
// return json array
Result := list.DelimitedText
end;
procedure TScanForm.TypeSelectorChange(Sender: TObject);
var
state: boolean;
begin
TypeSelector.Tag := 1;
state := TypeSelector.Text = 'Ticket';
Origin.Enabled := state;
Origin.Visible := state;
Stop.Enabled := state;
Stop.Visible := state;
Destination.Enabled := state;
Destination.Visible := state;
Product.Enabled := not state;
Product.Visible := not state;
ScanButton.Enabled:=true;
UpdateFolder();
end;
procedure TScanForm.CalendarChange(Sender: TObject);
begin
date := Calendar.DateTime;
TypeSelector.Enabled := True;
UpdateFolder();
end;
procedure TScanForm.OriginChange(Sender: TObject);
begin
Origin.Tag := 1;
UpdateFolder();
end;
function TScanForm.getSize(): TPoint;
var
arr: TStringArray;
s: String;
w, h: Integer;
begin
s:=PicSize.Text;
arr:=s.Split(['x','m']);
w:=StrToInt(arr[0].Trim);
h:=StrToInt(arr[1].Trim);
PicSize.Caption:=IntToStr(w)+' x '+IntToStr(h)+' mm';
Result := TPoint.Create(w,h);
end;
procedure TScanForm.ScanButtonClick(Sender: TObject);
var
config: TFileStream;
filename: string;
json: string;
size: TPoint;
begin
ScanButton.Enabled:=false;
filename := GetEnvironmentVariable('HOME') + '/.config/belegscanner.conf';
size := getSize();
json := ExportConfig();
try
config := TFilestream.Create(filename, fmCreate);
config.Write(json[1], json.Length);
finally
config.Free;
end;
ScanThread.Create(ScanButton,BaseFolder.Caption+'/'+FolderName.Caption+'/',size,Resolution.Caption,Preview,DropButton);
end;
procedure TScanForm.StopChange(Sender: TObject);
begin
Stop.Tag := 1;
UpdateFolder();
end;
procedure TScanForm.SwapClick(Sender: TObject);
var
dummy: String;
begin
dummy:=Origin.Text;
Origin.Text := Destination.Text;
Destination.Text := dummy;
UpdateFolder();
end;
procedure TScanForm.DestinationChange(Sender: TObject);
begin
Destination.Tag := 1;
UpdateFolder();
end;
procedure TScanForm.ProductChange(Sender: TObject);
begin
Product.Tag := 1;
UpdateFolder();
end;
procedure TScanForm.FormCreate(Sender: TObject);
var
filename: String;
lines: TStringList;
line: String;
index: integer;
begin
BaseFolder.Caption:=GetEnvironmentVariable('HOME');
filename := GetEnvironmentVariable('HOME') + '/.config/belegscanner.conf';
lines := TStringList.Create;
try
lines.LoadFromFile(filename);
for index := 0 to lines.Count-1 do
begin
line:=lines.Strings[index];
if line.StartsWith('folder:') then
begin
line:=line.Substring(7);
BaseFolder.Caption:=line;
end;
if line.StartsWith('types:') then
begin
line := line.Substring(6);
TypeSelector.Items.AddStrings(line.Split(','));
end;
if line.StartsWith('items:') then
begin
line := line.Substring(6);
Product.Items.AddStrings(line.Split(','));
end;
if line.StartsWith('sizes:') then
begin
line := line.Substring(6);
PicSize.Items.AddStrings(line.Split(','));
end;
if line.StartsWith('locations:') then
begin
line := line.Substring(10);
Origin.Items.AddStrings(line.Split(','));
Destination.Items.AddStrings(line.Split(','));
Stop.Items.AddStrings(line.Split(','));
end;
end
finally
end;
end;
procedure TScanForm.BaseFolderClick(Sender: TObject);
begin
BaseFolderDialog.FileName:=BaseFolder.Caption;
BaseFolderDialog.Execute;
BaseFolder.Caption := BaseFolderDialog.FileName;
end;
procedure TScanForm.DropButtonClick(Sender: TObject);
begin
DeleteFile(DropButton.Hint);
Preview.Picture:=nil;
DropButton.Enabled:=false;
end;
procedure TScanForm.UpdateFolder();
var
tx: string;
begin
tx := FormatDateTime('YYYY-MM-DD', date) + ' - ';
if (Product.Enabled and (Product.Tag > 0) and not( Product.Text = '') and not (Product.Text = 'Produkt')) then
tx := tx + Product.Text + ' von ';
if (TypeSelector.Tag > 0) then
tx := tx + TypeSelector.Text;
if (Origin.Enabled and (Origin.Tag > 0)) then
tx := tx + ': ' + Origin.Text;
if (Stop.Enabled and (Stop.Tag > 0) and not (Stop.Text = '')and not (Stop.Text = 'Zwischenhalt')) then
tx := tx + ' - ' + Stop.Text;
if (Destination.Enabled and (Destination.Tag > 0)) then
tx := tx + ' - ' + Destination.Text;
FolderName.Caption := tx;
end;
end.