FNC

Implementing a facial recognition library in a TMS WEB Core project

Trying to implement facial recognition in your applications can be a daunting task. With the use of TMS Web Core and the vast amount of available JavaScript libraries, this can be made much easier. There is no need for complex functions or algorithms. Just include the library in your HTML and you can access all the functionality. To showcase this, we’ve made a demo with the following library: face-api. This library contains a lot of different functionality that you can use. You can detect faces and match them with previously created models. But you can also use it to detect the age, sex and expressions of the person. You can even draw landmarks on the detected face. You can find the demo here (requires a webcam installed). WebGL vs WebAssembly The library that we used, gives us the option to use WebGL or WebAssembly. whilst WebGL is really fast it does have a initial warm-up time. the first detection of a face will take 5000-6000ms and every subsequent detection will be around 100ms. Performance is also heavily dependent on the installed GPU, as having a dedicated GPU really boosts the performance. Meanwhile, WebAssembly uses the CPU. We recently did some experimentation with this technology. You can read all about it in this blogpost. WebAssembly doesn’t have the initial warm-up time, but every detection takes about 700-900ms. As we only do one detection when logging in, we’ve opted to use WebAssembly .  In the following chart we only used one model to start face recognition (the demo uses 7 models to get all necessary data). this chart also doesn’t take the warm-up time in account. But it should give you a fair comparison between different systems and set-ups.  picture taken from Tensorflow.js which is used in the back-end of the face-api library. Integrating the Face-Api using external classes People who use TMS WEB Core will already know that you can use asm blocks to write JavaScript in Pascal methods. But you can also use the external keyword to wrap classes and functions from libraries. These external classes and methods can then be used directly in your Pascal code, negating the need to use asm blocks. This makes it also very easy to integrate these libraries in different applications as you’ll only need to include the pas file in your project.  Here you can find an example of a procedure: procedure LoadAgeGenderNetModel(AURL: string); async; external name ‘faceapi.nets.ageGenderNet.load’; And this is a example of such a class: TFaceMatcher = class external name ‘faceapi.FaceMatcher’ (TJSObject) public constructor new; overload; constructor new(AInput: TJSObject); overload; labeledDescriptors: TJSArray; function FindBestMatch(Descriptor: TJSObject): TFaceMatch; external name ‘findBestMatch’; function ToJSON: JSValue; external name ‘toJSON’; class function FromJSON(AJSON: TJSObject): TFaceMatcher; external name ‘fromJSON’; end To use this method you also need to add the following code right under the interface {$mode objfpc} {$modeswitch externalclass} Demo For our demo we have used facial recognition to use as authentication. When we can’t match the face, the application will ask to register yourself. This data will be saved in an indexedDb. The model to test against will be updated and stored in local storage. When a face is recognized, we will fetch the data of that person and display it in another form. except for opening forms and writing/reading from the databases, the actual detecting […]

Read More

TMS WEB Core v2.0 has landed

We’re excited that after many months of hard development work, TMS WEB Core v2.0 is available for you!  All active registered TMS WEB Core v2.0 users get this new release free. TMS WEB Core brings improvements to the web client development experience from your Delphi IDE in many areas! pas2js compiler update & RTL update The latest version of the pas2js compiler, responsible for transpiling the Object Pascal code to JavaScript running in the browser, and updated RTL is integrated now, bringing even better Delphi compatibility New components Various new components have been added: – TWebDropDownControl, TWebEditDropDownControl: flexible control that can be used to show any other control in its dropdown part– TWebCheckListBox: VCL-like check listbox– TWebDBListControl: DB-aware Bootstrap styled list control with optional DB field template– TWebSearchEdit: edit control with embedded search and clear button– TWebEditBtn: edit control with attached button– TCountryComboBox, TWebCountryListBox,TWebCountryDropDown: various controls to show list of countries in the world to pick from, including list of countries with official country flagsTWebXLSX: Microsoft Excel XLSX file import & export component Component enhancementsThere is too much to list here in detail. Many new features have been added to existing components, the most important shown here: – Add controls checkbox/button/progressbar in TWebStringGrid, TWebTableControl cells– Add nodes with checkbox or radiobutton in TWebTreeView– Perform filtering on items in the TWebListControl– New ListSource/ListField property in TWebDBComboBox to load items from a dataset– Row selection in TWebTableControl+ many more… Framework improvementsThe underlying framework has been enhanced and extended: – TCanvas VCL compatible brush style support added,– Material icons style support– Touch & wheel events in TWebElementActionList– Multi-language support in TWebMessageDlg()+ many more… IDE integration improvements Improved interaction with web projects from the Delphi IDE:– Improved live-preview from context menu on form units in the IDE project manager– Delete entire folder from project via IDE project manager New browser APIs exposedNew web browser APIs easily accessible from your Object Pascal code:– Speech recognition component: TWebSpeechRecognition– Classes for multi-screen API use In the coming days and weeks, we’ll unveil via video more details about the new features in TMS WEB Core v2.0. Today, you can already learn about the new dropdown controls, the new country list controls and the TWebCheckListBox in the video from our chief evangelist Dr. Holger Flick: Another interesting source of information is the replay of the recently held webinar with CTO Bruno Fierens walking through all new features of TMS WEB Core v2.0: Meanwhile, our team is also hard at work to bring all new components, new features of TMS WEB Core for Delphi to TMS WEB Core for Visual Studio Code v2.0. You can expect this update also very soon! If you are interested in web client development using Delphi, also have a look at the recent series of blogs from Andrew Simard that covers how to use external JavaScript libraries easily from TMS WEB Core. In the past weeks, Andrew covered how to integrate the impressive Tabulator JavaScript control in a TMS WEB Core project. The series starts here. TMS WEB Core v2.0 couldn’t have been created without all your valuable feedback in the past months and years! We are extremely thankful for all your help steering the development. And we continue to count on you driving further future developments of TMS WEB Core! We invite experienced TMS WEB Core developers having […]

Read More

Extend TMS WEB Core with JS Libraries with Andrew: Tabulator Part 7: Performance

In our final outing in this miniseries about using Tabulator in your TMS WEB Core projects, we’re going to focus primarily on one area – performance.  While Tabulator in its simplest form is amazingly quick, there is a lot more to the performance equation than just Tabulator itself.  We’ll also look at one way to implement image lazy loading, potentially applicable to any TMS WEB Core project.  And we’ll even explore one way to monitor the progress of downloading data from an XData server. By the time we’re done, you should be well-equipped to build not only functional projects, but highly performant projects as well. Motivation. One of the defining characteristics of any application, whether it is a web app, a phone app or a Windows desktop app or any other app, is how much time the user spends waiting.  Waiting for the app to load.  Waiting for the app to display data.  Waiting for the app to respond to some kind of interaction. For example, clicking a button should ideally provide some kind of feedback, even if the action being triggered cannot be completed immediately.  Scrolling should also be as fast as possible.  “Buttery smooth” as one famous person in our field liked to describe it. There are plenty of statistics to be found (naturally, with varying degrees of applicability) that relate app performance to user retention.  If an app is slow, they’ll quickly move on to something else. So we owe it to our users (and ourselves!) to make things as absolutely performant as we can. There’s almost always something that can be done to make an app faster. But is it worth it? Tabulator. Just How Fast Is It? One of the first questions to address, then, is about Tabulator itself.  There are many JS grid libraries around.  Which one is fastest?  Well, we’re not the first to come up with that question.  In fact, there’s a GitHub project focused on exactly this – JavaScript Data Grid Performance Comparison. Unfortunately, the Tabulator figures are not yet included in their results, though a PR is pending. You can read more about it here, though. The news is good – the current version of Tabulator is easily among the top performers in this comparison in every respect.  So we’re already starting out strong in the performance department. While using Tabulator with all its defaults is great, one of the benefits to many of these JS grid libraries is the ability to customize what it is doing, as we’ve been seeing over these last several posts.  And sometimes, that customization can come at a cost if we’re not paying close attention.  As an example of this, in a previous outing, we made some changes to include the row count in the column header of our tables.  We implemented this using Tabulator’s own updateColumnDefinition() function, which did exactly what we wanted. However, it turns out that this function essentially drops and recreates the entire column (so it can be sure that all the column definition parameters are accounted for). When doing this with a column filled with images, this ended up being enormously expensive. And it also triggers a table refresh, which interferes with the live filtering function.  This particular issue is something that is being addressed by the Tabulator team […]

Read More

Hands-on: Delphi Web Services with TMS XData online course – 20% RAD discount!

Creating Secure and Manageable Database-driven Web Services with TMS XData and Delphi With great pleasure we announce another great collaboration with Wagner Landgraf, architect TMS Business tools and Holger Flick, TMS evangelist and Embarcadero MVP. As of today, this new course is available for those who are interested. The course will also have a RAD purchase option which will give you 20% off! Click on the link below or use the coupon code RADPURCHASE. All information can be found here. This course will teach you step-by-step how to create TMS XData Web services in Delphi. First, the main focus is to create a template that you will be able to use in all your future TMS XData projects. The template will get you set up to create Web services with: configurable database connectivity, server parameters in a resource file, a modern UI with tray icon, switching to deployment as a Windows service, logging access control using JSON Web Token (JWT) This template will then be used to great a Web service for an example scenario. In this scenario, you will design a database, connect it to the template, implement the Web service backend, and then implement three clients. One VCL client to upload data from a CSV file into the Web service, and another VCL client to browse data from the Web service in a data grid and visualize it in a chart. The last client will be written in TMS WEB Core as an example for a Web client. All clients will implement user access control using JWT and a login dialog. The course is grouped into the following sections: Introduction Detailed introduction to the course. Some videos are free to watch before purchase which will allow you to determine if this course hits “all the marks” for you. I will start by giving an overview of all the course topics, describe the example scenarios, but will also motivate this course by giving examples for real-world Web services. Finally, we will prepare the development environment installing all the products and learning about TMS project wizards. Create a new TMS XData project Jump right into the development of a Web service with Delphi! You will learn how to create a new server and its associated project structure, get a glimpse at using version control, and where to download the source code of this course The section will close with a detailed look at the different components of an XData server and how to set up Windows to host a server. Updating the server container The server container is the core part of an XData server and will be discussed in detail. In particular, we will introduce the Singleton pattern to facilitate its accessibility in the server application. Adding services to the server Services are the means how you can add functionality to your Web services. An XData server can hold as many services as you design. In this section, you will implement your first service and its endpoints. Lots of examples will be given. Focus will be how to look at the data that is returned, how the data is formatted, how you define the data that is returned, and how you can easily browse your XData server using SwaggerUI. Adding database connectivity Using databases with Web services is an […]

Read More

Extend TMS WEB Core with JS Libraries with Andrew: Tabulator Part 6: Getting Data Out Of Tabulator

Last time, we took a look at some of the ways that we can edit data in Tabulator in our TMS WEB Core projects. And that was just the most basic introduction to a very large and complex topic overall.  This time out, in our penultimate stop in this Tabulator miniseries, we’re going to look at how to get those changes out of Tabulator and back into our databases or wherever else we need to send it.  We’ll also augment our example from last time with a proper navigator and clean up a couple of the editing options.  And then we’ll look at how to create PDF, XLS and CSV files directly from Tabulator. Motivation. Having any comprehensive JavaScript grid control is great, and Tabulator is just one of many such controls.  Having a grid control that can do almost everything all by itself is also great.  But there may come a time, specifically if your grid supports editing, when it has to give up its data, or at least its changes, so you can send it elsewhere. And giving the user some degree of control over that process, or at the very least, some level of confirmation, then everyone benefits.  The plan for this post, then, is to offer up some ideas, both on how to implement the actual data transfer-type mechanisms and on how to keep the user informed. Navigator. When doing database work in a traditional Delphi application, there’s a handy little DBNavigator component that you can link to your TDataSource that provides a consistent set of buttons for things like next/previous or save/cancel operations.  In TMS WEB Core, there’s also a TWebNavigator that can be linked to a TWebDataSource in the same way.  But a Tabulator table isn’t really a TWebDataSource, so they can’t be linked in that way.  So let’s start out by making our own navigator for Tabulator. The underlying purpose is to help become more familiar with how Tabulator tells us what is going on in the UI, via events and so on, so that we’ll be better able to understand how it does the same thing when data is changing. As a bonus, we’ll have a handy place to put some of the other things that we’ll need a spot for as well.  So to start with, we’re going to pretty up our example from last time and add a placeholder for the navigator.  We’ve covered some of these design items previously, so I’ll just list them here for reference purposes.  But by all means, please post a comment if you’d like a bit more information on any of them. Bit of styling for the whole Tabulator – rounded corners, new font, darker column headers. Added a CSS for the styling that we don’t handle in code. Put Tabulator inside another DIV, with some additional styling for the outer DIV. Added Interact.js so the DIV can be moved around and resized. Drag from the navigator. Added ‘selectable’ option, so we can visually see what record is currently active. Added a placeholder DIV below the table where the navigator will be Adjusted columns and layouts to be more ‘responsive’ – give it a try! Numerous adjustments to the individual columns and editors.  Check the code for details. So our starting point for today […]

Read More

Extend TMS WEB Core with JS Libraries with Andrew: Tabulator Part 5: Editing Data in Tabulator

In our continuing Tabulator adventures, last time out we barely scraped the surface when it comes to interactions.  We had a little side adventure into tooltips, potentially applicable to many TMS WEB Core projects.  And we got quite a bit further down the path of making our example project, Actorious, more useful. Grid-type controls are a natural fit for effectively organizing and displaying all kinds of data.  But in some cases, we’ll actually want to give the user the ability to make changes to the data, either by editing it directly or by using other elements on the page.  In this article, we’re going to primarily be looking at this special subcategory of interactions and how to get the most out of Tabulator when building editing interfaces into your TMS WEB Core projects. Motivation. As we discussed at the outset of this Tabulator miniseries, the basic concept behind it and similar JavaScript grids is that they ultimately have a bit of a self-centered view of the world. Meaning that they are, in effect, the entire package of data and UI elements.  As developers, we’re basically connecting them up at a pretty high level, providing them with data and letting them do as much of the work as possible from that point on.  When it comes to editing data, this doesn’t really change. Tabulator, in particular, has many options related to editing data, which we’ll get into shortly.  The potential problem, though, is in keeping track of what it is doing in case you need to take those changes and apply them elsewhere, like in the actual data source that you’re using. From a Delphi standpoint, it might help to think of a JavaScript grid as a disconnected TClientDataSet.  You’re basically giving it a block of data.  And when it’s done, you’re getting a block of data (the changes) back.  What format that communication takes is entirely up to you, and we’ve got a few options, as usual. The mechanisms that you ultimately end up using will hopefully result in a very cohesive and highly integrated and performant product.  So let’s have a look at some of those options. Column Definitions. Again. As with so many things in Tabulator, the easiest way to get started is by adding some options to the Tabulator column definitions.  By default, columns are not editable at all, but can easily be set to be editable.  The only question is what kind of editor do you want?  Let’s start with a simple new example project, TabulatorEditor, and then work our way first through a few of the built-in editors.  Quick and easy.  The usual Project.html additions can be used to load the Tabulator library.  If you’re using the JSDelivr CDN, it also offers the ability to combine many libraries into a single request.  We’re going to end up using the latest version of Bootstrap, Luxon and FlatPickr, so why not combine them all.  Here’s what it looks like.             In our WebFormCreate procedure, we can then create a basic Tabulator setup similar to what we’ve done previously. In this case, there are just a bunch of different field data types, so we can play around with how the editors might work. The Tabulator Documentation has plenty of examples, so we’re not […]

Read More

Chart data import in Delphi

TMS FNC Chart v2.0 is a major milestone and we are already collecting feedback and thinking about new features for the next version. We listed some of the top requested features in this blog post, but if you have other exciting ideas, please let us know in the comments. The blog post also gives an overview of what v2.0 brings alongside some very interesting chart related topics! Data Import This specific blog post however, focuses on a very important aspect of application development: data import. TMS FNC Chart is designed with one thing in mind: flexibility. The main goal in the FNC architecture has always been flexibility, and in TMS FNC Chart, this is no different. TMS FNC Chart is capable of importing JSON, CSV & custom data arrays. While designing these specific features, we aimed for loading data with a single line of code, but with the ability to customize the details. After running through installation process, you’ll find a demo which focuses on data import and demonstrates how to bring out the maximum potential of the chart. As a small code snippet, you’ll see how easy it is to add & append data. procedure TForm1.LoadInitialData; var loadOptions: TTMSFNCChartLoadOptions; begin loadOptions := TTMSFNCChartLoadOptions.Create; try loadOptions.YRange := arEnabledZeroBased; TMSFNCBarChart1.LoadFromDataArray(loadOptions, 0, [123, 98, 54, 154, 128, 87, 103], nil, [‘Apple’, ‘Watermelon’, ‘Pineapple’, ‘Pear’, ‘Banana’, ‘Lemon’,’Grapefruit’, ‘Peach’]).LegendText := ‘Sold’; finally loadOptions.Free; end; end; The above code snippet loads the initial data. procedure TForm1.AppendData; var s: TTMSFNCChartSerie; begin s := TMSFNCBarChart1.AddSeriesFromDataArray([0.88, 1.32, 2.43, 0.76, 0.44, 1.03, 1.10]); s.YValues.Positions := [ypLeft]; s.LegendText := ‘Price’; end; Afterwards, we can append data and add new series without having to clear the ones that already exist. Code snippets are great to get started, but what’s even better is a video, explaining the capabilities in detail. Feedback In the coming weeks, we’ll bring out more videos, so stay tuned! Anything you wish to see covered in a video or blog post? Please let us know.

Read More

Extend TMS WEB Core with JS Libraries with Andrew: Tabulator Part 4: Interacting with Tabulator

Last time, we looked at many possible customizations for Tabulator and other parts of a TMS WEB Core Project that were generally focused on the “look” of the application.  This included a handful of customizations to the content and format of the tables, as well as to other elements like images, fonts, and buttons.  The overall theme was changed a few times, resulting in the styling we have now, with a handful of CSS customizations to tweak every little detail.  This time out, we’re going to dig a bit deeper into the “feel” of the application.  Interacting with various elements, particularly with Tabulator, breathing a little more life into the application. Motivation. While there are many JavaScript grids available that work great within TMS WEB Core projects, and even when considering elements beyond grids and projects beyond TMS WEB Core, there are aesthetic properties (what we can see) but also interactive properties (what we can do) of the elements we select, as developers.  The aesthetic properties are perhaps easier to see and adjust, and in the TMS WEB Core project we’ve been creating, now called Actorious, we’ve seen how easy it is to use CSS to override the appearance of very nearly anything we want, from scrollbars to cell padding to fonts to borders.  Customizing interactions for a particular element is potentially more difficult, however, and we’re generally more reliant on an element’s built-in capabilities to help us out. But a web application has enormous potential for customizations even in this area.  We can add functionality and change element behaviors at will, with the goal of making the user experience as enjoyable as possible.  So in this post, we’re going to explore a bunch of these kinds of enhancements, while striving for a certain level of consistency and performance, filing off some rough edges along the way. Tooltips. Let’s ease into this topic with something that seems simple enough.  Tooltips.  In Delphi, they’re called hints.  And they work the same way straight out of the box in a TMS WEB Core application.  Add a button to a form. Add something to the Hint property. Hovering your mouse over the button produces a tooltip. We’re done, right?  Well, if you’ve been following along, you must know by now that we’re certainly not done at all.  We’ve not even really started! When it comes to tooltips generally, there are quite a few things you can customize to make them more useful or, alternatively, to get them out of your way.  The properties we’re going to address here are the overall look of the tooltip, the placement (relative to what it is linked to), as well as the delay – how quickly a tooltip appears and disappears.  For some tooltips, we actually want them to be almost instant.  And for others, we’d rather not see them at all most of the time.  Also keep in mind that tooltips might have varying levels of usefulness under different conditions.  Having a tooltip that shows “Biography” when you have a button that is clearly labeled “Biography” probably doesn’t make much sense, initially.  But later, when that row of buttons shrinks to just an icon if the form is displayed on a narrower display, suddenly the tooltip might be more useful. The look of a tooltip is […]

Read More

Extend TMS WEB Core with JS Libraries with Andrew: Tabulator Part 3: Viewing Data in Tabulator

In this third stop on our Tabulator adventure, we’re going to focus mostly on the options available for how data is displayed.  But in order to help narrow our focus a little further, we’re going to take the TMS WEB Core project from last time, what we were calling ActorInfo, and explore ways we can view the data we have available, covering many Tabulator options along the way.  Styling and theming a modern web application potentially involves some amount of CSS work, so we’ll cover a bit of that as well.  And to keep it interesting for those not all that keen on Tabulator specifically, we’ll also cover how such a TMS WEB Core app might be deployed in a production setting. Motivation. As we discussed in the first of these Tabulator posts, having a grid control that does what you want, as a developer, makes for an enormously powerful tool. And for web applications, what developers are often after is the ability to customize, as much as possible, anything that is visible to the user.  This may arise from a need for a responsive interface that is accessible to everyone on every device. Or it may come from a desire to apply a specific style or theme, including color, logos, iconography, and that sort of thing.  Or some level of customization may be needed to address certain mechanical aspects of the interface or the underlying data.  Or it can be any combination of these, or other considerations entirely.  Point being, more options for customization are generally better for the developer.  Better still if there are reasonable defaults to start with and a consistent approach to customization that is not overly difficult to implement. The approach I’m going to take here is perhaps a little less organized than I’d like but reflects more accurately how this has come together.  We’ll start with where we ended up last time, and then systematically make changes to implement whatever customization is desired, outlining the steps and the thought-process along the way.  By the time we’re done today, we’ll have a pretty functional app, deployed and ready for users. And while I don’t expect anyone to particularly agree with my styling or theming or layout choices, the main takeaway should be, as usual, that you’ve got options!    Starting Point Two Disclaimers.  Just a couple of things to point out before we get too immersed in our work here.  First, there countless ways a developer can choose to implement any particular bit of functionality. And the same developer, facing the same choices, in the same app, may even implement the same thing in different ways.  And there are some examples of that on display here.  Sometimes, this is because I learned something new and haven’t gone back and updated the original code.  Sometimes, it’s because I’m lazy and cut and paste code where it isn’t really important (code executed infrequently, say), but might spend more time on the same thing in another spot where it is more important (code executed frequently in a loop, for example).  So don’t be too harsh when looking at any of this code.  I’ve tried to clean up the worst examples, but I’m sure some are lingering still.  Case in point, in the XData application, in the service endpoint, […]

Read More