feat(apk): scanner le QR du poste depuis l'app (ZXing.Delphi, Apache 2.0)
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>
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
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.
|
||||
Reference in New Issue
Block a user