重新激活时 Firemonkey TCameraComponent 质量发生变化
Firemonkey TCameraComponent quality change when reactivated
我正在 Delphi 10.1 Berlin 中使用 Android 的 firemonkey 构建条形码 reader 应用程序。基于CameraComponent sample and using the ZXing library,可以读取条码。
为了初始化相机,我使用了这段代码:
procedure TfrmMain.btnOpenReaderClick(Sender: TObject);
begin
CameraComponent.Active := False;
CameraComponent.FocusMode := FMX.Media.TFocusMode.ContinuousAutoFocus;
CameraComponent.Quality := TVideoCaptureQuality.MediumQuality;
CameraComponent.Active := True;
CameraComponent.SampleBufferToBitmap(imgCamera.Bitmap, True);
end;
要扫描条形码,我是运行这个:
procedure TfrmMain.GetImage;
var
ReadResult: TReadResult;
begin
CameraComponent.SampleBufferToBitmap(imgCamera.Bitmap, True);
if (FScanInProgress) then
Exit;
{ This code will take every 4 frames. }
inc(FFrameTake);
if (FFrameTake mod 4 <> 0) then
Exit;
ReadResult := nil;
ITask(TTask.Create(
procedure
begin
try
FScanInProgress := True;
ReadResult := FScanManager.Scan(imgCamera.Bitmap);
TThread.Synchronize(nil,
procedure
begin
try
if (ReadResult <> nil) then
begin
Label1.Text := ReadResult.text;
CameraComponent.Active := False;
end;
except
on E: Exception do
ShowMessage(E.Message);
end;
end);
finally
ReadResult.Free;
imgCamera.Bitmap.Free;
FScanInProgress := false;
end;
end)).Start;
end;
读取条码后,当我设置CameraComponent.Active := True;
开始读取新条码时,CameraComponent质量自动设置为高质量,即使属性开始时设置为中等质量组件。这会导致相机预览以低帧率显示。有没有办法在重新激活 CameraComponent 时将默认捕获设置设置为中等?
是的,您必须在激活相机之前对其进行设置。喜欢:
CameraComponent1.Quality := TVideoCaptureQuality.MediumQuality;
CameraComponent1.Active := true;
顺便说一句:我只在 Android 而不是 IOS 停止相机。那太慢了。我将在应用程序停止时使用 IOS 关闭相机。 canvas 就不再更新了。
procedure TdmGetBarcodeStatus.StopCamera();
begin
CameraIsActivated := false;
{$IFDEF ANDROID}
CameraComponent1.Active := false;
{$ENDIF}
end;
同时在 Dave 提供的 link 中实现相机优化技术。 它极大地加快了相机帧速率。
一点,我认为更好的扫描策略可以运行连续任务中的图像扫描进度。
这是如何完成的:
FParseImagesInProgress 是一个标志,它控制来自 TRectangle (RectImage.Fill.Bitmap.Bitmap) 的图像的解析。在停止相机之前,将 FParseImagesInProgress 设置为 false。
procedure TFormCamera.StartParseImageTaskService();
var
ReadResult: TReadResult;
begin
if FParseImagesInProgress then
Exit;
FParseImagesInProgress := true;
TTask.Run(
procedure
var
hints: TDictionary<TDecodeHintType, TObject>;
PossibleFormats: TList<TBarcodeFormat>;
ScanManager: TScanManager;
scanBitmap: TBitmap;
begin
PossibleFormats := TList<TBarcodeFormat>.Create();
PossibleFormats.Add(TBarcodeFormat.QR_CODE);
hints := TDictionary<TDecodeHintType, TObject>.Create();
hints.Add(TDecodeHintType.POSSIBLE_FORMATS, PossibleFormats);
ScanManager := TScanManager.Create(TBarcodeFormat.CODE_128, hints);
scanBitmap := TBitmap.Create();
try
while (FParseImagesInProgress) do
begin
ReadResult := nil;
try
TThread.Synchronize(nil,
procedure
begin
scanBitmap.Assign(RectImage.Fill.Bitmap.Bitmap);
end);
ReadResult := ScanManager.Scan(scanBitmap);
except
if Assigned(ReadResult) then
FreeAndNil(ReadResult);
end;
if Assigned(ReadResult) then
begin
TThread.Synchronize(nil,
procedure
begin
// PlaySound(TATSounds.Good);
MarkBarcode(ReadResult, TalphaColors.Deepskyblue);
if WasNotLastBarcodeInTimeWindow(ReadResult.Text) then
FBarcodeRequestManager.RequestBarcodeStatus(ReadResult.Text, HotMember, 'myDevice', HotUser,
HotPassword);
FLastBarcode := ReadResult.Text;
end);
FreeAndNil(ReadResult);
end;
Sleep(MS_BETWEEN_SCAN_FRAMES);
end; // while
finally
if Assigned(scanBitmap) then
scanBitmap := nil;
FreeAndNil(ScanManager);
if Assigned(PossibleFormats) then
begin
PossibleFormats.Clear;
PossibleFormats := nil;
end;
if Assigned(ReadResult) then
FreeAndNil(ReadResult);
end;
end); // end TTask
end;
真快。
总之,希望对您有所帮助!
我正在 Delphi 10.1 Berlin 中使用 Android 的 firemonkey 构建条形码 reader 应用程序。基于CameraComponent sample and using the ZXing library,可以读取条码。
为了初始化相机,我使用了这段代码:
procedure TfrmMain.btnOpenReaderClick(Sender: TObject);
begin
CameraComponent.Active := False;
CameraComponent.FocusMode := FMX.Media.TFocusMode.ContinuousAutoFocus;
CameraComponent.Quality := TVideoCaptureQuality.MediumQuality;
CameraComponent.Active := True;
CameraComponent.SampleBufferToBitmap(imgCamera.Bitmap, True);
end;
要扫描条形码,我是运行这个:
procedure TfrmMain.GetImage;
var
ReadResult: TReadResult;
begin
CameraComponent.SampleBufferToBitmap(imgCamera.Bitmap, True);
if (FScanInProgress) then
Exit;
{ This code will take every 4 frames. }
inc(FFrameTake);
if (FFrameTake mod 4 <> 0) then
Exit;
ReadResult := nil;
ITask(TTask.Create(
procedure
begin
try
FScanInProgress := True;
ReadResult := FScanManager.Scan(imgCamera.Bitmap);
TThread.Synchronize(nil,
procedure
begin
try
if (ReadResult <> nil) then
begin
Label1.Text := ReadResult.text;
CameraComponent.Active := False;
end;
except
on E: Exception do
ShowMessage(E.Message);
end;
end);
finally
ReadResult.Free;
imgCamera.Bitmap.Free;
FScanInProgress := false;
end;
end)).Start;
end;
读取条码后,当我设置CameraComponent.Active := True;
开始读取新条码时,CameraComponent质量自动设置为高质量,即使属性开始时设置为中等质量组件。这会导致相机预览以低帧率显示。有没有办法在重新激活 CameraComponent 时将默认捕获设置设置为中等?
是的,您必须在激活相机之前对其进行设置。喜欢:
CameraComponent1.Quality := TVideoCaptureQuality.MediumQuality;
CameraComponent1.Active := true;
顺便说一句:我只在 Android 而不是 IOS 停止相机。那太慢了。我将在应用程序停止时使用 IOS 关闭相机。 canvas 就不再更新了。
procedure TdmGetBarcodeStatus.StopCamera();
begin
CameraIsActivated := false;
{$IFDEF ANDROID}
CameraComponent1.Active := false;
{$ENDIF}
end;
同时在 Dave 提供的 link 中实现相机优化技术。 它极大地加快了相机帧速率。
一点,我认为更好的扫描策略可以运行连续任务中的图像扫描进度。
这是如何完成的:
FParseImagesInProgress 是一个标志,它控制来自 TRectangle (RectImage.Fill.Bitmap.Bitmap) 的图像的解析。在停止相机之前,将 FParseImagesInProgress 设置为 false。
procedure TFormCamera.StartParseImageTaskService();
var
ReadResult: TReadResult;
begin
if FParseImagesInProgress then
Exit;
FParseImagesInProgress := true;
TTask.Run(
procedure
var
hints: TDictionary<TDecodeHintType, TObject>;
PossibleFormats: TList<TBarcodeFormat>;
ScanManager: TScanManager;
scanBitmap: TBitmap;
begin
PossibleFormats := TList<TBarcodeFormat>.Create();
PossibleFormats.Add(TBarcodeFormat.QR_CODE);
hints := TDictionary<TDecodeHintType, TObject>.Create();
hints.Add(TDecodeHintType.POSSIBLE_FORMATS, PossibleFormats);
ScanManager := TScanManager.Create(TBarcodeFormat.CODE_128, hints);
scanBitmap := TBitmap.Create();
try
while (FParseImagesInProgress) do
begin
ReadResult := nil;
try
TThread.Synchronize(nil,
procedure
begin
scanBitmap.Assign(RectImage.Fill.Bitmap.Bitmap);
end);
ReadResult := ScanManager.Scan(scanBitmap);
except
if Assigned(ReadResult) then
FreeAndNil(ReadResult);
end;
if Assigned(ReadResult) then
begin
TThread.Synchronize(nil,
procedure
begin
// PlaySound(TATSounds.Good);
MarkBarcode(ReadResult, TalphaColors.Deepskyblue);
if WasNotLastBarcodeInTimeWindow(ReadResult.Text) then
FBarcodeRequestManager.RequestBarcodeStatus(ReadResult.Text, HotMember, 'myDevice', HotUser,
HotPassword);
FLastBarcode := ReadResult.Text;
end);
FreeAndNil(ReadResult);
end;
Sleep(MS_BETWEEN_SCAN_FRAMES);
end; // while
finally
if Assigned(scanBitmap) then
scanBitmap := nil;
FreeAndNil(ScanManager);
if Assigned(PossibleFormats) then
begin
PossibleFormats.Clear;
PossibleFormats := nil;
end;
if Assigned(ReadResult) then
FreeAndNil(ReadResult);
end;
end); // end TTask
end;
真快。
总之,希望对您有所帮助!