Now that we have the main screen properly built with its main components anchored, we can work on the main functionality—recording moments! Using the same project as the previous recipes, we will finally develop the code to capture images:
- First, add a TImage component to your form and set its alignment to alClient, filling all layout content. We will use this TImage to display the photo. Now, do the same for a non-visual component, called ActionList. Enter this into the form. Change the TImage property and name it as ImgInsta.
- With the right-click on ActionList, open the ActionList Editor option.
With the keyboard, click Ctrl + Insert to open the dialog containing the options; you can also go with the mouse on the New button and insert the new action. The action we want is TTakePhotoFromCameraAction:
In this project, we will capture the image in two ways, the first with a standard action and the other using the IFMXCameraService interface.
- Let's create the DoDidFinish procedure:
procedure TForm1.DoDidFinish(Image: TBitmap); begin ImgInsta.Bitmap.Assign(Image); end;
- In this procedure, the image parameter, which will come from the camera, will be assigned to the TImage component in our form. Remember to assign this procedure to the OnDidFinishTaking event of TTakePhotoFromCameraAction:
procedure TForm1.TakePhotoFromCameraAction1DidFinishTaking(Image: TBitmap);
begin
DoDidFinish(Image);
end;
In the next few steps, you will understand why this is redundant.
- We can create a new default action, which will fetch images already saved in the device library. Repeat the process to add a new action to your ActionList; however, this time select the TTakeFromLibrary action.
If you want your application to automatically save the pictures taken by a device camera to the device photo library, set the TCustomTakePhotoAction.NeedSaveToAlbum property to True.
- When selecting the event of this new action, the code is exactly the same code that was made in TTakePhotoFromCameraAction:
procedure TForm1.TakePhotoFromLibraryAction1DidFinishTaking(Image: TBitmap);
begin
DoDidFinish(Image);
end;
Note that since the image comes from a parameter, which comes from the action, it allows you to use exactly the same line of code.
- Bind the respective actions to their execution buttons:
- Let's increase the project a bit more, including an extra button added to the top in the first toolbar, only this time, right-aligned. This button will also take a picture, but, using the IFMXCameraService interface. To perform such an act, include the following units in the uses clause of your form:
uses
FMX.MediaLibrary, FMX.Platform, System.Messaging;
- Add another procedure to capture the message coming from the device and thus identify an action to take photos:
procedure DoMessageListener(const Sender: TObject; const M: TMessage);
Its implementation is shown in the following code snippet:
procedure TForm1.DoMessageListener(const Sender: TObject; const M: TMessage);
begin
if M is TMessageDidFinishTakingImageFromLibrary then
ImgInsta.Bitmap.Assign(TMessageDidFinishTakingImageFromLibrary(M).Value);
end;
- Encode the FormCreate procedure:
procedure TForm1.FormCreate(Sender: TObject);
begin
TMessageManager.DefaultManager.SubscribeToMessage(
TMessageDidFinishTakingImageFromLibrary, DoMessageListener);
end;
- To conclude, let's encode the onClick event of the newly added button:
procedure TForm1.Button3Click(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;
Service.TakePhoto(Button3, Params);
end
else
ShowMessage('This device does not support the camera service');
end;
We divide this project into two parts, where, in the first part, we use an ActionList to take a picture. These actions require very little programming; however, they will not work on Windows platforms. In the second part, when using the IFMXCameraService interface, we have the freedom to implement our codes with a few more lines but greater freedom. We can also include parameters that allow us to, for example, set the minimum resolution and define whether we will save the image to the device as well.
You should also check the TCameraComponent component. You can take your photos without even directing them to your device's camera, including video recordings.