dd9fd62dcb
Le scanner du systeme demandait avec quoi ouvrir le lien. L'app ouvre la camera arriere, decode une image sur quatre et remplit URL + jeton des qu'un lien pmserver://sync est lu. Rien n'est enregistre avant Save. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
186 lines
4.4 KiB
ObjectPascal
186 lines
4.4 KiB
ObjectPascal
unit ZXing.ScanManager;
|
|
|
|
interface
|
|
|
|
uses
|
|
System.SysUtils,
|
|
System.Generics.Collections,
|
|
{$IFDEF FRAMEWORK_FMX}
|
|
FMX.Graphics,
|
|
{$ENDIF}
|
|
{$IFDEF FRAMEWORK_VCL}
|
|
VCL.Graphics,
|
|
{$ENDIF}
|
|
ZXing.LuminanceSource,
|
|
ZXing.RGBLuminanceSource,
|
|
ZXing.InvertedLuminanceSource,
|
|
ZXing.HybridBinarizer,
|
|
ZXing.BinaryBitmap,
|
|
ZXing.MultiFormatReader,
|
|
ZXing.BarcodeFormat,
|
|
ZXing.ResultPoint,
|
|
ZXing.ReadResult,
|
|
ZXing.DecodeHintType;
|
|
|
|
type
|
|
TScanManager = class
|
|
private
|
|
FEnableInversion: Boolean;
|
|
FHints: TDictionary<TDecodeHintType, TObject>;
|
|
FResultPointEvent: TResultPointCallback;
|
|
FMultiFormatReader: TMultiFormatReader;
|
|
listFormats: TList<TBarcodeFormat>;
|
|
|
|
function GetMultiFormatReader(const format: TBarcodeFormat)
|
|
: TMultiFormatReader;
|
|
|
|
procedure SetResultPointEvent(const AValue: TResultPointCallback);
|
|
public
|
|
destructor Destroy; override;
|
|
|
|
function Scan(const pBitmapForScan: TBitmap): TReadResult;
|
|
constructor Create(const format: TBarcodeFormat;
|
|
Hints: TDictionary<TDecodeHintType, TObject>);
|
|
|
|
property OnResultPoint: TResultPointCallback read FResultPointEvent
|
|
write SetResultPointEvent;
|
|
end;
|
|
|
|
implementation
|
|
|
|
constructor TScanManager.Create(const format: TBarcodeFormat;
|
|
Hints: TDictionary<TDecodeHintType, TObject>);
|
|
begin
|
|
inherited Create;
|
|
FEnableInversion := False;
|
|
FHints := Hints;
|
|
FMultiFormatReader := GetMultiFormatReader(format);
|
|
end;
|
|
|
|
destructor TScanManager.Destroy;
|
|
var
|
|
hint: TPair<TDecodeHintType, TObject>;
|
|
o: TObject;
|
|
begin
|
|
if Assigned(FHints) then
|
|
begin
|
|
|
|
for hint in FHints do
|
|
begin
|
|
o := hint.Value;
|
|
if Assigned(o) then
|
|
o.Free;
|
|
end;
|
|
|
|
FHints.Clear();
|
|
FreeAndNil(FHints);
|
|
end;
|
|
|
|
FreeAndNil(FMultiFormatReader);
|
|
inherited;
|
|
end;
|
|
|
|
procedure TScanManager.SetResultPointEvent(const AValue: TResultPointCallback);
|
|
var
|
|
ahKey: TDecodeHintType;
|
|
ahValue: TObject;
|
|
begin
|
|
FResultPointEvent := AValue;
|
|
|
|
ahKey := TDecodeHintType.NEED_RESULT_POINT_CALLBACK;
|
|
if Assigned(FResultPointEvent) then
|
|
begin
|
|
ahValue := TResultPointEventObject.Create(FResultPointEvent);
|
|
FHints.AddOrSetValue(ahKey, ahValue);
|
|
end
|
|
else
|
|
begin
|
|
if Fhints.TryGetValue(ahKey, ahValue) then
|
|
begin
|
|
ahValue.Free;
|
|
ahValue := nil;
|
|
FHints.Remove(ahKey);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TScanManager.GetMultiFormatReader(const format: TBarcodeFormat)
|
|
: TMultiFormatReader;
|
|
var
|
|
o: TObject;
|
|
|
|
begin
|
|
Result := TMultiFormatReader.Create;
|
|
listFormats := nil;
|
|
|
|
if FHints = nil then
|
|
FHints := TDictionary<TDecodeHintType, TObject>.Create();
|
|
|
|
if FHints.ContainsKey(ZXing.DecodeHintType.ENABLE_INVERSION) then
|
|
FEnableInversion := true;
|
|
|
|
if format <> TBarcodeFormat.Auto then
|
|
begin
|
|
if (FHints.TryGetValue(ZXing.DecodeHintType.POSSIBLE_FORMATS, o)) then
|
|
listFormats := o as TList<TBarcodeFormat>
|
|
else
|
|
begin
|
|
listFormats := TList<TBarcodeFormat>.Create();
|
|
FHints.Add(ZXing.DecodeHintType.POSSIBLE_FORMATS, listFormats);
|
|
end;
|
|
|
|
if (listFormats.Count = 0) then
|
|
listFormats.Add(format)
|
|
else
|
|
listFormats.Insert(0, format); // favor the format parameter
|
|
|
|
end;
|
|
|
|
Result.Hints := FHints;
|
|
end;
|
|
|
|
function TScanManager.Scan(const pBitmapForScan: TBitmap): TReadResult;
|
|
var
|
|
LuminanceSource, InvLuminanceSource: TLuminanceSource;
|
|
HybridBinarizer: THybridBinarizer;
|
|
BinaryBitmap: TBinaryBitmap;
|
|
begin
|
|
InvLuminanceSource := nil;
|
|
LuminanceSource := nil;
|
|
HybridBinarizer := nil;
|
|
BinaryBitmap := nil;
|
|
try
|
|
|
|
LuminanceSource := TRGBLuminanceSource.CreateFromBitmap(pBitmapForScan,
|
|
pBitmapForScan.Width, pBitmapForScan.Height);
|
|
HybridBinarizer := THybridBinarizer.Create(LuminanceSource);
|
|
BinaryBitmap := TBinaryBitmap.Create(HybridBinarizer);
|
|
Result := FMultiFormatReader.Decode(BinaryBitmap, true);
|
|
|
|
if (Result = nil) then
|
|
begin
|
|
if (FEnableInversion) then
|
|
begin
|
|
if (BinaryBitmap <> nil) then
|
|
FreeAndNil(BinaryBitmap);
|
|
|
|
if (HybridBinarizer <> nil) then
|
|
FreeAndNil(HybridBinarizer);
|
|
|
|
InvLuminanceSource := LuminanceSource.invert();
|
|
HybridBinarizer := THybridBinarizer.Create(InvLuminanceSource);
|
|
BinaryBitmap := TBinaryBitmap.Create(HybridBinarizer);
|
|
Result := FMultiFormatReader.Decode(BinaryBitmap, true);
|
|
|
|
end;
|
|
end;
|
|
finally
|
|
BinaryBitmap.Free;
|
|
HybridBinarizer.Free;
|
|
InvLuminanceSource.Free;
|
|
LuminanceSource.Free;
|
|
end;
|
|
end;
|
|
|
|
end.
|