【问题标题】:Firemonkey TCameraComponent quality change when reactivated重新激活时 Firemonkey TCameraComponent 质量发生变化
【发布时间】:2018-08-13 20:24:52
【问题描述】:

我正在使用适用于 Android 的 firemonkey 在 Delphi 10.1 Berlin 中构建条形码阅读器应用程序。基于CameraComponent sample,使用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 时将默认捕获设置设置为中等?

【问题讨论】:

  • 如果它自动设置为高,您可能需要在运行时创建组件,并在每次需要将其设置为活动时重新创建它。根据对此报告的评论:quality.embarcadero.com/browse/RSP-10592,将 Active 设置为 False “不会禁用导致高功率使用的相机”,因此无论如何销毁/重新创建它可能是明智的

标签: android delphi firemonkey


【解决方案1】:

是的,您必须在激活相机之前对其进行设置。喜欢:

CameraComponent1.Quality := TVideoCaptureQuality.MediumQuality;
CameraComponent1.Active := true;

顺便说一句:我只在 Android 上停止摄像头,而不是在 IOS 上。那太慢了。我将在应用程序停止时使用 IOS 关闭相机。画布不再更新。

procedure TdmGetBarcodeStatus.StopCamera();
begin
    CameraIsActivated := false;
{$IFDEF ANDROID}
    CameraComponent1.Active := false;
{$ENDIF}
end;

在 Dave 提供的链接中也实现了相机优化技术。它极大地加快了相机帧率。

我认为更好的扫描策略可以在连续任务中运行图像扫描进度。

这是可以做到的:

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;

真的很快。

不管怎样,希望对你有帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-07
    • 2011-08-26
    • 2022-07-29
    • 1970-01-01
    • 2015-07-24
    • 2016-11-08
    • 1970-01-01
    • 2023-02-26
    相关资源
    最近更新 更多