안녕하세요
로로봉입니다 : )
오늘은 델파이 모바일 앱 개발 중 카메라를 이용해 바코드를 인식하는 법을 포스팅하겠습니다.
카메라에서 바코드를 제어하기 위해선 ZXing 라이브러리를 사용해야 합니다.
ZXing 라이브러리는 아래 사이트에서 다운받을 수 있습니다.
라이브러리는 설치하는 것이 아닌 Pas만 이용하면 되기 때문에 Tools – Options – Language – Delphi – Library 메뉴에 Library path만 등록해주면 됩니다.
ZXing 라이브러리 사용을 위해 interface uses에 3가지 pas를 추가해줍니다.
ZXing.BarcodeFormat, ZXing.ReadResult, ZXing.ScanManager
다음으로는 카메라를 사용해야 하기 때문에 폼 위에 TCameraComponent를 올려줍니다.
private에 아래 변수를 선언합니다.
FusBarcode : String;
FbScan : Boolean;
FScanManager : TScanManager;
FScanInProgress : Boolean;
FormCreate 함수에 아래와 같이 초기화를 해줍니다.
if TPlatformServices.Current.SupportsPlatformService(IFMXApplicationEventService, IInterface(AppEventSvc)) then
AppEventSvc.SetApplicationEventHandler(AppEvent);
FScanManager := TScanManager.Create(TBarcodeFormat.Auto, nil);
바코드 포맷은 Auto가 아닌 Code39나 EAN13 등 다른 포맷을 지정해 줄 수도 있으며, Auto를 지정해 주면 자동으로 포맷을 인식 하게 됩니다.
최신 버전의 Android API는 권한을 요청하는 매커티즘을 변경했다고 합니다. 카메라를 사용하기 전에 아래와 같이 권한을 요청하는 프로세스를 추가해 주어야 해당 앱에 카메라 접근 권한이 수락되는 경우에만 카메라를 사용할 수 있습니다.
DisplayRationale 함수와 ActivateCameraPermissionRequestResult 함수를 정의해줍니다.
procedure TfrmMain.DisplayRationale(Sender: TObject; const APermissions: TArray<string>; const APostRationaleProc: TProc);
begin
// 카메라 권한 허용/거절 창 실행
APostRationaleProc;
end;
procedure TfrmMain.ActivateCameraPermissionRequestResult(Sender: TObject; const APermissions: TArray<string; const AGrantResults: TArray<TPermissionStatus>);
begin
if (Length(AGrantResults) = 1) and (AGrantResult[0] = TPermissionStatus.Granted) then
begin
// 카메라 권한 허용 시 카메라 실행 처리
CameraComponent.Active := False;
CameraComponent.Kind := FMX.Media.TCameraKind.BackCamera;
CameraComponent.FocusMode := TFocusMode.ContinuousAutoFocus;
CameraComponent.CaptureSettingPriority := TVideoCaptureSettingPriority.Resolution;
CameraComponent.Quality := TVideoCaptureQuality.LowQuality;
CameraComponent.Quality := TVideoCaptureQuality.MediumQuality;
FusBarcode := '';
KeyboardHide;
CameraComponent.Active := True;
end
else
ToastMessage('카메라 접근 권한이 없습니다.');
end;
위 함수를 정의해주시고 아래와 같이 호출하면 DisplayRaionale 함수가 호출됩니다.
PermissionsService.RequestPermissions([PermissionCamera], ActivateCameraPermissionRequestResult, DisplayRationale);
DisplayRationale 함수가 실행되면 카메라 권한을 사용하시겠냐는 안내창이 표시되고, ActivateCameraPermissionRequestResult 함수로 권한 허용 유무 결과가 리턴되는 것을 볼 수 있습니다.
다음으로는 카메라로부터 들어오는 데이터를 처리하는 함수를 선언해 주어야 합니다.
우선 화면상에는 TImage 컴포넌트를 올려주어 카메라 이미지가 TImage에 표시되도록 합니다.
추가한 TImage 컴포넌트를 imgCamera로 이름을 변경하고 GetImage 함수를 아래와 같이 선언해주었습니다.
procedure TfrmMain.GetImage;
var
scanBitmap, tempBitmap: TBitmap;
ReadResult : TReadResult;
iNewHeight : Integer;
ARect : TRect;
Task : ITask;
begin
tempBitmap := TBitmap.Create;
try
CameraComponent.SampleBufferToBitmap(tempBitmap, True);
iNewHeight := Trunc(tempBitmap.Width * imgCamera.Size.Height / imgCamera.Size.Width);
ARect := Rect(0, (tempBitmap.Height-iNewHeight) div 2, tempBitmap.Width, tempBitmap.Height - (tempBitmap.Height-iNewHeight) div 2);
imgCamera.Bitmap.SetSize(ARect.Width, ARect.Height);
imgCamera.Bitmap.CopyFromBitmap(tempBitmap, ARect, 0, 0);
finally
tempBitmap.Free;
end;
if (FScanInProgress) then exit;
scanBitmap := TBitmap.Create;
scanBitmap.Assign(imgCamera.Bitmap);
ReadResult := nil;
Task := TTask.Create(
procedure
begin
try
try
FScanInProgress := True;
ReadResult := FScanManager.Scan(scanBitmap);
FScanInProgress := False;
except
exit;
end;
if ReadResult <> nil then
begin
FScanInProgress := True;
TThread.Synchronize(TThread.CurrentThread, procedure()
begin
// 바코드 값 저장
FusBarcode := ReadResult.text;
end);
end;
finally
FreeAndNil(ReadResult);
FreeAndNil(scanBitmap);
FScanInProgress := False;
end;
end);
Task.Start;
end;
카메라 컴포넌트의 이벤트인 OnSampleBufferReady 함수를 추가해주고 아래와 같이 GetImage 함수가 호출되도록 합니다.
procedure TfrmMain.CameraComponentSampleBufferReady(Sender: TObject; const ATime: TMediaTime);
begin
TThread.Synchronize(TThread.CurrentThread, GetImage);
end;
이렇게 되면 카메라로 들어오는 Image가 GetImage 함수로 넘어가게 되고, GetImage 함수에서는 ScanManager를 통해 바코드 데이터를 추출할 수 있게 됩니다.
좋아요 ♥ + 구독 부탁드립니다 : )
'개발 정보 > 델파이' 카테고리의 다른 글
[Delphi] 델파이 안드로이드/iOS 에서 FCM(Firebase Cloud Messaging) 사용하기 (23) | 2021.02.02 |
---|---|
[Delphi] 델파이 FMX 키보드 표시, 숨기기 (3) | 2021.01.19 |
[Delphi] 델파이 Datasnap 서버 클라이언트 통신 방법 (4) | 2021.01.06 |
[Delphi] 델파이 안드로이드 메시지 창 처리 (2) | 2021.01.05 |
[Delphi] 델파이 안드로이드 커스텀 폰트 사용 (2) | 2021.01.04 |
댓글