FireMonkey インターフェイスを使用して写真を撮る
モバイル チュートリアル:写真を撮って共有する、テキストを共有する(iOS および Android) への移動
このチュートリアルでは、IFMXPhotoLibrary および IFMXCameraService インターフェイスを使用して、モバイル デバイスで写真を撮って処理する方法を説明します。
目次
アプリケーションのユーザー インターフェイスの構築
フォーム デザイナに以下のコンポーネントをドロップします。
- TToolBar コンポーネント
- このツールバー上に 2 つの TSpeedButton コンポーネントを配置します。このボタンを使用して、デバイスのカメラで写真を撮ったり、デバイスのフォト ライブラリから写真を選択します。
- [オブジェクト インスペクタ]で、ボタンの以下のプロパティを指定します。
- StyleLookup プロパティを、それぞれ cameratoolbuttonbordered と searchtoolbuttonbordered に設定します。
- Align プロパティを、それぞれ Left と Right に設定します。
- TImage コンポーネント
- Align プロパティを Client に設定します。
このサンプル アプリケーションのフォームは、次の図のようになります。ここではまだ、フォーム デザイナの[スタイル]や[ビュー]は設定していません。
メモ: スタイルとビューの選択に関する詳細については、「スタイル セレクタ」および「FireMonkey ビューの利用」を参照してください。
デバイス カメラでの写真の撮影
モバイル デバイスのカメラで写真を撮るには、IFMXCameraService インターフェイスを使用します。手順は以下のとおりです。
-
コード エディタを開き、以下の行がコードに含まれていない場合には追加します。
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>
- フォーム定義の private セクションに次の手続きヘッダーを追加します。
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);
-
implementation セクションで、DoDidFinish と DoMessageListener を次のように定義します。
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); } }
-
フォーム デザイナで SpeedButton1 ボタンをダブルクリックし、コード エディタで onClick イベント ハンドラを次のように実装します。
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"); } }
CAMERA
使用権限が宣言されるとすぐに、IFMXCameraService プラットフォーム サービスに対する予期しない要求された使用権限となります。アプリケーションが不要な使用権限を要求しないように、Camera project オプションを無効にすることを検討してください。アプリケーションを実行する
F9 を押すか[実行|実行]を選択して、モバイル デバイス上でアプリケーションを実行します。デバイスのカメラを起動するには、アプリケーションのツールバーにあるカメラ アイコンをタップします。
iOS | Android |
---|---|
この写真を使用するには:
- Android デバイスでは[OK]をクリックします。
- iOS デバイスでは[Use]をクリックします。
デバイスのフォト ライブラリに写真を保存する
デバイス カメラで撮った写真をアプリケーションで自動的にデバイスのフォト ライブラリに保存する場合には、TakePhoto メソッドの第2パラメータの NeedSaveToAlbum を True
に設定します(上記手順のステップ 4のコード スニペットを参照)。
そうすると、アプリケーションはデバイスのフォト ライブラリ内のアルバムに写真を保存します。このアルバムの名前は、デバイスのオペレーティング システムによって異なります。
OS バージョン | アルバム名 |
---|---|
iOS | カメラ ロール |
Android | カメラ |
デバイスのフォト ライブラリの写真の選択
FireMonkey で定義されている IFMXTakenImageService インターフェイスを使用すると、デバイスのフォト ライブラリから写真を選択することができます。
アプリケーションでデバイスのフォト ライブラリから写真を選択する手順は以下のとおりです。
-
フォーム デザイナで SpeedButton2 ボタン(写真選択用のボタン)をダブルクリックし、コード エディタで onClick イベント ハンドラを次のように実装します。
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"); } }
-
[構造]ビューで Form1 を選択し、[オブジェクト インスペクタ]で[イベント]タブを開いて、OnCreate の隣の空のフィールドをダブルクリックします。その後、onFormCreate イベント ハンドラを次のように実装します。
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)); }
- アプリケーションをコンパイルして実行します。写真を選択するには、検索ボタンをタップし、デバイスのフォト ライブラリから目的の写真を選択します。
iOS Android メモ: iPad デバイスでは、アプリケーションはサムネイル画像を、TakeImageFromLibrary メソッドの第1パラメータで指定されたコントロール要素の横にあるポップアップ ウィンドウに表示します。サンプル プロジェクトでは、SpeedButton2 は検索ボタンを参照しています。