Uploading images to the cloud with BaaS in RAD Studio XE6

by Jun 20, 2014

In Delphi, C++Builder and RAD Studio XE6, we integrate with leading Backend as a Service (BaaS) providers to add functionality and platform services to your applications. With BaaS, you get easy access to common services in the cloud without having to build or maintain the backend services yourself. This includes support for being able to upload images to your BaaS account using RAD Studio XE6.

Today, I thought I would create a demo that shows you how to load an image from the gallery, upload it to your Parse.com account (you will need to sign up for an account), display the image URL in an Edit control and then download the uploaded image and display it in your app.

I used the following BaaS components:

  • TBackendFiles

  • TParseProvider  (you could also use TKinveyProvider)
I wanted to be able to select images from the photo album on my device using either the 'Access Gallery' button or by clicking on the TImage. I used the built-in action (TActionList) for accessing an image from the library and then executed that action again on button click. In addition, the URL of my image location is assigned to an Edit control after I upload the image to Parse. I also set up an on-click event to download the image using the provided URL and then assign it to a TImage.

The user interface of my application consists of a toolbar with a parented TLabel for the title, a TListbox with several listbox items and two TListbox Groupheaders for displaying the titles.

Here is the Object Pascal Code for my application:

unit ImageUploadBaaS_OP;

interface

uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, IPPeerClient,
REST.Backend.ServiceTypes, REST.Backend.MetaTypes,
REST.Backend.KinveyServices, System.JSON, REST.OpenSSL,
REST.Backend.KinveyProvider, REST.Backend.Providers,
REST.Backend.ServiceComponents, FMX.Objects, FMX.StdCtrls, FMX.Edit, REST.Client,
FMX.TabControl, System.Actions, FMX.ActnList, FMX.StdActns,
FMX.MediaLibrary.Actions, REST.Backend.ParseServices,
REST.Backend.ParseProvider, FMX.ListBox, FMX.Layouts;

type
TForm1 = class(TForm)
BackendFiles1: TBackendFiles;
btnUploadImage: TButton;
Image1: TImage;
Image2: TImage;
btnDownloadImage: TButton;
Edit1: TEdit;
ActionList1: TActionList;
TakePhotoFromCameraAction1: TTakePhotoFromCameraAction;
TakePhotoFromLibraryAction1: TTakePhotoFromLibraryAction;
ParseProvider1: TParseProvider;
ToolBar2: TToolBar;
Label2: TLabel;
ListBox1: TListBox;
ListBoxGroupHeader1: TListBoxGroupHeader;
ListBoxItem1: TListBoxItem;
ListBoxItem2: TListBoxItem;
imagedownload: TListBoxGroupHeader;
ListBoxItem3: TListBoxItem;
btnAccessGallery: TButton;
procedure btnUploadImageClick(Sender: TObject);
procedure btnDownloadImageClick(Sender: TObject);
procedure TakePhotoFromLibraryAction1DidFinishTaking(Image: TBitmap);
procedure Image1Click(Sender: TObject);
procedure Image2Click(Sender: TObject);
private
function SaveImage: TStream;
procedure DownloadImage(const AUrl: string);
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.btnUploadImageClick(Sender: TObject);
var
LStream: TStream;
LFile: TBackendEntityValue;
begin
LStream := SaveImage;
try
BackEndFiles1.Files.UploadFile('mypicture3.png',LStream, 'image/png',LFile);
ShowMessage('Image has been uploaded');
Edit1.Text := LFile.DownloadURL;
finally
LStream.Free;
end;
end;

procedure TForm1.DownloadImage(const AUrl: string);
var
LStream: TMemoryStream;
begin
LStream := TMemoryStream.Create;
try
REST.Client.TDownloadURL.DownloadRawBytes(AUrl, LStream);
Image2.Bitmap.LoadFromStream(LStream);
finally
LStream.Free;
end;
end;

procedure TForm1.Image1Click(Sender: TObject);
begin
TakePhotoFromLibraryAction1.ExecuteTarget(btnAccessGallery);
end;


procedure TForm1.Image2Click(Sender: TObject);
begin
DownloadImage(Edit1.Text);
end;

procedure TForm1.btnDownloadImageClick(Sender: TObject);
begin
DownloadImage(Edit1.Text);
end;

function TForm1.SaveImage: TStream;
begin
Result := nil;
begin
Result := TMemoryStream.Create;
try
Image1.Bitmap.SaveToStream(Result);
except
Result.Free;
raise;
end;
end;
end;

procedure TForm1.TakePhotoFromLibraryAction1DidFinishTaking(Image: TBitmap);
begin
Image1.Bitmap.Assign(Image);
end;

end.

Note: This requires XE6 Update 1 to be installed.