All Blog Posts  |  Next Post  |  Previous Post

The Story of an intern at TMSSoftware


Monday, May 6, 2019

Hello, this is the intern speaking (or writing) about his experience at TMSSoftware. I’m a second year graduate student in programming-informatics who has been given the opportunity to do my internship here at TMSSoftware.

Getting started

My first week starting here was interesting as I had no real background experience in Delphi or Object Pascal, as the primary languages I learned at school were Java and C#. Thankfully, I had a lot of resources available, which includes the Object Pascal Handbook by Marcu Cantù. So getting started went smooth.

My internship was split up into three parts, were the first part was to study and test different REST services. The second part was based on implementing the APIs such as Google Translate and Microsoft Vision. The third part involved using the implementation in an application called TMS Vision.

TMS Vision should allow visually impaired people to be informed about their environment by simply tapping on their mobile phone and getting a spoken response in the native language. That response can be a series of keywords, or a short description on the object that has been recognized by the camera.

Used technologies

Doing my internship at TMSSoftware, I got access to the newest tools TMS had to offer. With the TMS FNC Cloud Pack I had the foundation to build a set of classes that implement the services needed to send and receive data via REST. For the GUI, I used FNC. For those not yet familiar with 'FNC' , these are what we call Framework Neutral Components. This means that these components can be simultaneously used with different frameworks, are fully cross platform, can be used from Delphi, C++Builder and Lazarus and most spectacularly can be used to create web applications with TMS WEB Core. Read more about FNC for the web here.

TMS FNC Controls can be simultaneously used on these frameworks:

TMS FNC Controls can be simultaneously used on these operating systems/browsers:

TMS FNC Controls can be simultaneously used on these IDE's:

Because TMS FNC Cloud Pack contains a core layer to handle asynchronous REST request, it became really easy to send and receive data.

Example of translating text via the Google Translate API. In the code below, the TTMSFNCSimpleCloudBase class allows you to quickly send and receive data via REST without OAuth 2.0 authentication flow requirements.
// form class private variables
  c: TTMSFNCSimpleCloudBase;
  target : string;

procedure TGoogleTranslateForm.Button1Click(Sender: TObject);
  c.Request.Host := '';
  c.Request.Path := '/language/translate/v2';
  c.Request.Query := 'q=' + TTMSFNCUtils.URLEncode(Edit1.Text) +'&format=text'+
   '&target=' + target + '&key=' + c.Authentication.Key;
  c.Request.Method := rmGET;

Also parsing the request result data was very easy with TMS FNC Core, which exposes a set of ready to use functions for parsing JSON.
procedure TGoogleTranslateForm.DoGetList(const ARequestResult: TTMSFNCCloudBaseRequestResult);
  j, jd, ja, jav: TJSONValue;
  I: Integer;
  siso, sname: string;
  l: TLanguage;
  if ARequestResult.ResultString <> ''  then
    j := TTMSFNCUtils.ParseJSON(ARequestResult.ResultString);
      jd := TTMSFNCUtils.GetJSONValue(j, 'data');
      if Assigned(jd) then
        ja := TTMSFNCUtils.GetJSONValue(jd, 'languages');
        if Assigned(ja) and (ja is TJSONArray) then
          for I := 0 to TTMSFNCUtils.GetJSONArraySize (ja as TJSONArray) - 1do
            jav := TTMSFNCUtils.GetJSONArrayItem(ja as TJSONArray, I);
            if Assigned(jav) then
              siso := TTMSFNCUtils.GetJSONProp(jav, 'language');
              sname := TTMSFNCUtils.GetJSONProp(jav, 'name');

(Code snippets were written for Google Translate in the first week of the internship) Here is an example to test the REST API for Google Translate.

Starting on components

After getting used to the different platforms, investigating and testing the various cloud services to be implemented in TMS Vision, I got started on transferring the sample code into components that work cross-platform. Doing the internship here, made this easy as the TMS FNC Cloud Pack already provided a solid base to work on, and additionally my colleagues were eager to lend their advice when I needed help.

Here is an example of how the final code looks with the Google Translate component.
procedure TGoogleTranslateForm.FormCreate(Sender: TObject);
  c := TTMSFNCCloudGoogleTranslate.Create;
  TLanguage := TStringList.Create;
  c.Authentication.Key := 'My-API-Key';
  c.OnIsoLanguageList  := doLanguageList;
  c.OnTranslate := DoTranslate;

procedure TGoogleTranslateForm.Button1Click(Sender: TObject);
  if FTarget <> '' then 
    c.Translate(Edit1.Text, FTarget)
    c.Translate(Edit1.Text) ;

This shows how compact your final code can be.

TMS Vision

I decided to use the knowledge I collected to make an application that works cross-framework and cross-platform to assist people who are visually impaired. The application allowed them to be informed about the environment around them. There were some critical parts in TMS Vision related to the Google Vision and Microsoft Vision APIs that involved uploading the picture taken from the camera. The data required by Google Vision, for example, needed to be in a base64 string. This was handled by the TTMSFNCUtils.FileToBase64 function included in TMS FNC Core. Below you can see a code snippet that uses this functionality to upload the picture data to Google Vision.

procedure TTMSFNCCustomCloudGoogleVision.AnalysePicture(const AFile: TTMSFNCUtilsFile);
 basestring :String;
    basestring := TTMSFNCUtils.FileToBase64(AFile);
    Request.Host := Service.BaseURL;
    Request.Path := '/v1/images:annotate';
    Request.Method := rmPOST;
    Request.AddHeader('Content-Type','application/json; charset=utf-8');
    Request.Query := 'key='+Authentication.Key;
    Request.PostData := '{"requests": [{"image": {"content":"'+      
    basestring+'"}'+',"features": [{"type": "LABEL_DETECTION"},{"type":    
    "OBJECT_LOCALIZATION","maxResults": 5},{"type": "WEB_DETECTION"}]}]}' ;
    ExecuteRequest({$IFDEF LCLWEBLIB}@{$ENDIF}DoRequestAnalyse);

Example of how the application looks now. The layout of the app has been created with the TMS FNC UI Pack, and runs on TMS WEB Core. The application is a PWA that is installable on the device.


Right now I'm in my second half of my internship and can say I enjoyed every moment of it, gaining access to the tools of TMSSoftware and the wide variety of FNC components, made programming in Delphi or Pascal a lot easier than I thought.

I’m still expanding my knowledge of Delphi and Object Pascal and I plan to expand the TMS Vision application with other API services such as Google speech to text to remove the need to interact with the screen manually by implementing voice commands.

Author: Brutin Bjorn

Masiha Zemarai


This blog post has received 4 comments.

1. Monday, May 6, 2019 at 5:34:30 PM

Amazing! Great job! Can we access the PWA on a public server yet?

Holger Flick

2. Monday, May 6, 2019 at 5:35:53 PM

Comming soon, some small cleanup todo of UI and we''ll publish it.

Bruno Fierens

3. Tuesday, May 7, 2019 at 1:36:59 PM

Wow, great work Bjorn! It’s pretty amazing to see what you can do with the FNC Components as an intern - automatic text translation and advance image recognition in only a few lines of code. Even more amazing that it’s cross-platform too.

It’s really great to see you using Delphi like this. I always tell people Delphi is my super-power. It powers so many programs and systems around the well with so little fuss and so efficiently that people just don’t realize it and TMS are the leading component developers in that world.

I hope the rest of your internship goes as well - good luck in your future career.

Ian Barker

4. Friday, May 24, 2019 at 8:03:22 AM

Great works!

Carlomagno Antonello

Add a new comment

You will receive a confirmation mail with a link to validate your comment, please use a valid email address.
All fields are required.

All Blog Posts  |  Next Post  |  Previous Post