Aufnehmen von Bildern mit FireMonkey-Interfaces

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu Mobile-Tutorial: Aufnehmen und Teilen von Bildern und Teilen von Texten (iOS und Android)


In diesem Tutorial wird erklärt, wie Bilder auf Ihren mobilen Geräten mit den Interfaces IFMXPhotoLibrary und IFMXCameraService aufgenommen und verwaltet werden.

Erstellen der Benutzeroberfläche für Ihre Anwendung

Ziehen Sie die folgenden Komponenten in den Formular-Designer:

  • TToolBar-Komponente
    • Ziehen Sie zwei TSpeedButton-Komponenten auf die Symbolleiste. Über diese Schaltflächen werden Bilder mit der Gerätekamera aufgenommen und aus der Fotobibliothek des Geräts ausgewählt.
    • Legen Sie im Objektinspektor die folgenden Eigenschaften dieser Schaltflächen fest:
      • Setzen Sie die Eigenschaft StyleLookup auf cameratoolbuttonbordered bzw. auf searchtoolbuttonbordered.
      • Setzen Sie die Eigenschaft Align auf Left bzw. Right.
  • TImage-Komponente
    • Setzen Sie die Eigenschaft Align auf Client.

Bevor Sie den Stil oder die Ansicht im Formular-Designer festlegen, sollte das Formular dieser Beispielanwendung wie der folgende Screenshot aussehen:

AppMasterUserInterface.png

Hinweis: Weitere Informationen zur Auswahl des Stils und der Ansichten finden Sie unter Stilauswahl und Verwenden von FireMonkey-Ansichten.

Aufnehmen eines Fotos mit der Gerätekamera

Zum Aufnehmen von Bildern mit der Kamera eines mobilen Geräts können Sie das Interface IFMXCameraService verwenden. Gehen Sie dazu folgendermaßen vor:

  1. Öffnen Sie den Quelltext-Editor, und fügen Sie die folgenden Zeilen in den Code ein, falls sie noch nicht vorhanden sind:
    Delphi:
    uses
      System.Messaging, System.Permissions, FMX.MediaLibrary, FMX.Platform;
    
    C++:
    #include <System.Messaging.hpp>
    #include <System.Permissions.hpp>
    #include <FMX.MediaLibrary.hpp>
    #include <FMX.Platform.hpp>
    
  2. Fügen Sie dem private-Abschnitt der Formulardefinition den folgenden Prozeduren-Header hinzu:
    Delphi:
     procedure DoDidFinish(Image: TBitmap);
     procedure DoMessageListener(const Sender: TObject; const M: TMessage);
    
    C++:
    void __fastcall DoDidFinish(TBitmap *Image);
    void __fastcall DoMessageListener(const TObject *Sender, TMessage const *M);
    
  3. Definieren Sie im implementation-Abschnitt DoDidFinish und DoMessageListener wie folgt:
    Delphi:
     procedure TForm1.DoDidFinish(Image: TBitmap);
    begin
      Image1.Bitmap.Assign(Image);
    end;
    
    procedure TForm1.DoMessageListener(const Sender: TObject; const M: TMessage);
    begin
      if M is TMessageDidFinishTakingImageFromLibrary then
        Image1.Bitmap.Assign(TMessageDidFinishTakingImageFromLibrary(M).Value);
    end;
    
    C++:
    void __fastcall TForm1::DoDidFinish(TBitmap *Image) {
    	Image1->Bitmap->Assign(Image);
    }
    
    void __fastcall TForm1::DoMessageListener(const TObject *Sender, TMessage const *M) {
    	TMessageDidFinishTakingImageFromLibrary const *v = dynamic_cast<TMessageDidFinishTakingImageFromLibrary const *>(M);
    	if (v) {
    		Image1->Bitmap->Assign(v->Value);
    	}
    }
    
  4. Doppelklicken Sie im Formular-Designer auf die Schaltfläche SpeedButton1, und implementieren Sie dann im Quelltext-Editor die folgende onClick-Ereignisbehandlungsroutine:
    Delphi:
    procedure TForm1.SpeedButton1Click(Sender: TObject);
    var
      Service: IFMXCameraService;
      Params: TParamsPhotoQuery;
    begin
      if TPlatformServices.Current.SupportsPlatformService(IFMXCameraService, Service) then
      begin
        Params.Editable := True;
        // Specifies whether to save a picture to device Photo Library
        Params.NeedSaveToAlbum := True;
        Params.RequiredResolution := TSize.Create(640, 640);
        Params.OnDidFinishTaking := DoDidFinish;
    {$IF Defined(ANDROID)}
        if TOSVersion.Check(11) then
          Service.TakePhoto(SpeedButton1, Params)
        else
          PermissionsService.RequestPermissions(['android.permission.WRITE_EXTERNAL_STORAGE'],
            procedure(const Permissions: TClassicStringDynArray; const GrantResults: TClassicPermissionStatusDynArray)
            begin
              if (Length(GrantResults) = 1) and (GrantResults[0] = TPermissionStatus.Granted) then
                Service.TakePhoto(SpeedButton1, Params)
              else
                ShowMessage('Cannot take a photo because the required permission has not been granted')
            end);
    {$ELSE}
        Service.TakePhoto(SpeedButton1, Params);
    {$ENDIF}
      end
      else
        ShowMessage('This device does not support the camera service');
    end;
    
    C++:
    void __fastcall TForm1::SpeedButton1Click(TObject *Sender) {
        _di_IFMXCameraService service;
        TParamsPhotoQuery params;
        if (TPlatformServices::Current->SupportsPlatformService(__uuidof(IFMXCameraService), &service)) {
            params.Editable = true;
            // Specifies whether to save a picture to device Photo Library
            params.NeedSaveToAlbum = true;
            params.RequiredResolution = TSize(640, 640);
            params.OnDidFinishTaking = DoDidFinish;
    #if defined(_PLAT_ANDROID)
            if (TOSVersion::Check(11)) {
                service->TakePhoto(SpeedButton1, params);
            } else {
                PermissionsService()->RequestPermissions({ "android.permission.WRITE_EXTERNAL_STORAGE" },
                    [this, service, params](const TClassicStringDynArray Permissions, const TClassicPermissionStatusDynArray GrantResults) {
                        if (GrantResults.Length == 1 && GrantResults[0] == TPermissionStatus::Granted) {
                            service->TakePhoto(SpeedButton1, params);
                        } else {
                            ShowMessage("Cannot take a photo because the required permission has not been granted");
                        }
                    });
            }
    #else
            service->TakePhoto(SpeedButton1, params);
    #endif
        } else {
            ShowMessage("This device does not support the camera service");
        }
    }
    
Hinweis: Beim Erstellen eines FireMonkey-Anwendungsprojekts hat die Option Camera project unter Projekt > Optionen > Anwendung > Verwendet Berechtigungen, die standardmäßig aktiviert ist, eine unerwartete Auswirkung auf das Verhalten der Anwendung. Selbst wenn die Anwendung nicht direkt auf die Kamera zugreift (z. B. über die Komponente TCameraComponent) und stattdessen eine andere Anwendung dazu auffordert (z. B. die integrierte Kamera-Anwendung), wird die Berechtigung, sobald die Verwendet-Berechtigung CAMERA in der Manifestdatei deklariert ist, zu einer unerwarteten erforderlichen Verwendet-Berechtigung für den Plattformdienst IFMXCameraService. Erwägen Sie, die Option Camera project zu deaktivieren, um die Anforderung einer unnötigen Verwendet-Berechtigung zu verhindern.
Hinweis: Die den Plattformdiensten IFMXCameraService und IFMXTakenImageService zugrunde liegenden aktualisierten Implementierungen unterstützen die Bearbeitung des abgerufenen Bildes nicht mehr, da die Android-Plattform über keine integrierte Unterstützung für diese Operation verfügt. Das bedeutet, dass das Feld TParamsPhotoQuery.Editable jetzt ignoriert wird.

Ausführen der Anwendung

Führen Sie die Anwendung auf Ihrem mobilen Gerät aus, indem Sie F9 drücken oder Start > Start wählen. Um die Gerätekamera einzuschalten, tippen Sie in der Symbolleiste Ihrer Anwendung auf das Kamera-Symbol:

iOS Android

TakePicture IOS.png

TakePicture Android.png

Um dieses Foto zu verwenden:

  • Klicken Sie auf Android-Geräten auf OK.
  • Klicken Sie auf iOS-Geräten auf Verwenden.

Speichern eines Fotos in der Fotobibliothek des Geräts

Wenn Sie möchten, dass Ihre Anwendung die von einer Gerätekamera aufgenommenen Bilder automatisch in der Fotobibliothek des Geräts speichert, setzen Sie das Feld NeedSaveToAlbum des zweiten Parameters der Methode TakePhoto auf True (siehe die Codefragmente in Schritt 4 der obigen Anleitung).

Die Bilder werden von Ihrer Anwendung in ein Album in der Fotobibliothek des Geräts gespeichert. Der Name des Albums ist folgendermaßen vom Betriebssystem des Geräts abhängig:

BS-Version   Name des Albums  
iOS Aufnahmen
Android Kamera

Auswählen eines Fotos aus der Fotobibliothek des Geräts

FireMonkey definiert das Interface IFMXTakenImageService, mit dem Sie ein Bild aus der Fotobibliothek des Geräts auswählen können.

Führen Sie die folgenden Schritte aus, um mit Ihrer Anwendung ein Bild aus der Fotobibliothek des Geräts auszuwählen:

  1. Doppelklicken Sie im Formular-Designer auf die Schaltfläche SpeedButton2 (zum Auswählen eines Bildes), und implementieren Sie dann im Quelltext-Editor die folgende onClick-Ereignisbehandlungsroutine:
    Delphi:
    procedure TForm1.SpeedButton2Click(Sender: TObject);
    var
      Service: IFMXTakenService;
      Params: TParamsPhotoQuery;
    begin
      if TPlatformServices.Current.SupportsPlatformService(IFMXTakenService, Service) then
      begin
        Params.RequiredResolution := TSize.Create(640, 640);
        Params.OnDidFinishTaking := DoDidFinish;
        Service.TakeImageFromLibrary(SpeedButton2, Params);
      end;
    end;
    
    C++:
    void __fastcall TForm1::SpeedButton2Click(TObject *Sender) {
        _di_IFMXTakenImageService service;
        TParamsPhotoQuery params;
        if (TPlatformServices::Current->SupportsPlatformService(__uuidof(IFMXTakenImageService), &service) {
            params.RequiredResolution = TSize(640, 640);
            params.OnDidFinishTaking = DoDidFinish;
            service->TakeImageFromLibrary(SpeedButton2, params);
        } else {
            ShowMessage("This device does not support the photo library service");
        }
    }
    
  2. Wählen Sie in der Strukturansicht Form1 aus, öffnen Sie im Objektinspektor die Registerkarte Ereignisse, doppelklicken Sie auf ein leeres Feld neben OnCreate, und implementieren Sie dann die folgende onFormCreate-Ereignisbehandlungsroutine:
    Delphi:
     procedure TForm1.FormCreate(Sender: TObject);
    begin
    TMessageManager.DefaultManager.SubscribeToMessage(TMessageDidFinishTakingImageFromLibrary, DoMessageListener);
    end;
    
    C++:
    void __fastcall TForm1::FormCreate(TObject *Sender) {
    	TMessageManager::DefaultManager->SubscribeToMessage(__classid(TMessageDidFinishTakingImageFromLibrary),
    		TMessageListenerMethod(&DoMessageListener));
    }
    
  3. Compilieren Sie Ihre Anwendung, und führen Sie sie aus. Um ein Bild auszuwählen, tippen Sie auf die Suchen-Schaltfläche, und wählen Sie dann das gewünschte Bild aus der Fotobibliothek des Geräts aus.
    iOS Android

    TakePhotoFromLibraryAction.PNG

    Android SelectfromLibrary.png

    Hinweis: Auf iPads zeigt die Anwendung Miniaturansichten der Bilder in einem Popup-Fenster neben dem im ersten Parameter der Methode TakeImageFromLibrary angegebenen Steuerelement an. In dem Beispielprojekt verweist SpeedButton2 auf die Such-Schaltfläche.
Hinweis: Die den Plattformdiensten IFMXCameraService und IFMXTakenImageService zugrunde liegenden aktualisierten Implementierungen unterstützen die Bearbeitung des abgerufenen Bildes nicht mehr, da die Android-Plattform über keine integrierte Unterstützung für diese Operation verfügt. Das bedeutet, dass das Feld TParamsPhotoQuery.Editable jetzt ignoriert wird.

Siehe auch