Uploading images to the cloud with BaaS in RAD Studio XE6

Posted by on in Blogs
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.
About
Gold User, Rank: 5, Points: 558
Senior Product Manager, RAD Studio

Comments

  • luis H14769
    luis H14769 Tuesday, 23 August 2016

    Hola no puedo hacer andar el ejemplo, subi la imagen y no devuelve el path de la imagen, q puede ser, gracias

  • Guest
    Charles Stack Sunday, 22 June 2014

    Great stuff, Sarina! Enjoy the articles you have been writing and find them useful in what I am currently doing.

    One thing that would be really interesting (and, useful) would be articles on HOW to wrap other features of iOS. I have heard a lot of rumblings about iBeacons - Can somebody show us how to go about this (like what was done to get push notifications working)?

    R/,

    Charles

  • Guest
    sarinadupont Wednesday, 25 June 2014

    Hi Charles,

    Thanks! I would recommend having a look at Brian Long's CodeRage sessions on accessing the iOS API.
    The session looks at how you can access the iOS Objective-C classes via the Objective-C bridge, looking at classes that have Delphi representations and, perhaps more importantly, those which do not, as well as demonstrating how Objective-C classes can be extended in Delphi.

    http://www.youtube.com/watch?v=Yf9LxQYl5LA

    Regards,
    Sarina

  • Guest
    Charles Stack Monday, 30 June 2014

    Interesting video, Sarina. The only problem with it was that it demonstrated using iOS components for which headers have already been translated. Maybe I missed something - will have to watch it again when I have some time.

    It would be nice to have a definitive guide or a tool that can translate the iOS headers into Delphi-speak.

    I don't know if the header converter developed for FPC will work or not. Why is there no tool for Delphi/RadStudio capable of automating this process?

  • Guest
    sarinadupont Wednesday, 02 July 2014

    Hi Charles,

    I would suggest attending tomorrow's skill sprint session on 'Integrate More iOS with an Objective-C Call in your App': http://forms.embarcadero.com/DeveloperSkillSprintsWebinarSeries

    Regards,
    Sarina

  • Guest
    Alex Wednesday, 23 July 2014

    Hi.


    I ran this application on android and got the following error:

    "No mapping for the Unicode character exist in the target multi-byte code page"

    in the line:

    BackEndFiles1.Files.UploadFile('mypicture3.png',LStream, 'image/png',LFile);

    how to solve this error?

  • Guest
    sarinadupont Wednesday, 23 July 2014

    Hi Alex,

    Are you using Update 1? This requires Update 1 to be installed.

    Regards,
    Sarina

  • Please login first in order for you to submit comments
  • Page :
  • 1