Microsoft’s Azure has a broad collection of services you can access with an easy-to-use API.
Azure is Microsoft’s cloud hosting and computing platform with a catalog of more than 200 different products. It also includes products that allow you to implement Machine Learning services. Those services all have an API that you can access using client access libraries or a REST client. Delphi, an IDE software, takes this ease of use one step further by providing a TAzureConnectionInfo
to implement some of those services quickly and with a minimal amount of code. Also, we can access the services using Delphi’s built-in REST client.
Table of Contents
Is Azure Read Client Free?
No, the Azure Read Client is not free, but the good news is when you first register you will get some free 12 month services and a free-tier allowance for services so you can try things out as you develop, test, and launch your app. Some Azure services have very generous ‘always free’ levels. The service we are going to use in our OCR application is “Cognitive Search” which is one of those which is always free. It has a permanent limit of 10,000 documents, but that’s more than enough for our testing purposes.
How do we get API credentials for the “Computer Vision” service resources?
For our OCR application, we are going to use the “Cognitive Services->Computer Vision” resource. First, you must have an “Azure subscription”. Go to the link below and create an “Azure subscription” if you don’t have one. It’s free to start!
https://azure.microsoft.com/en-us/free/cognitive-services/
Once you have the subscription, you can create the required service links. Go to this link to create a “Computer Vision” resource.
https://portal.azure.com/#create/Microsoft.CognitiveServicesComputerVision
Make sure you select the correct region because you can’t go back and change it later. Now go to the resource you created and choose “Keys and Endpoint” from the left-hand menu. Now, copy one of the keys and the location. We need those in our application.
How to connect to the Cognitive Services REST API?
We need TRESTClient
, TRESTRequest
and a TRESTResponse
components to connect to the cognitive services REST Api. Lets drag and drop TRESTClient
in to the forum and do some basic property changes. Make sure the “Accept” property has “application/json
” type. Set the content type to “application/json
“.
Then drop a TRESTRequest
component into the forum and set client property to the client we created earlier. Set the method to “rmPOST
“.
Place a TRESTResponse
component and set the response property in the request component to this response object.
Add some edit boxes, buttons and a memo box to complete our interface.
How do we use the API to post the image for processing?
We cannot post the image to cognitive services and get the result in one call. The image processing takes time, although usually this is less than five seconds. So, first we need to submit our image to the cognitive service and get the “Operation-Location” and check the status until it’s “succeeded”. If the server is still processing the image, status will be “running” instead.
For each and every call to cognitive service API, we need to provide our subscription key through the HTTP Header. It’s the key we copied earlier from the resource we created. To do that, add a new parameter to TRESTRequest
component, set the ‘kind’ to “pkHTTPHEADER
“, set name to “Ocp-Apim-Subscription-Key
” and set the the value to your key.
We must provide the image URL we want to process in a JSON format. To do that, add new parameter with the name to “data”. Set content type to “ctAPPLICATION_JSON
“, set kind to “pkGETorPOST
“, and set value to something like this:
1 |
{"url":"URL_OF_YOUR_IMAGE"} |
We need to set the base URL of our REST client. To make the base URL, we need to know the location of your resource which we copied earlier. Replace the “LOCATION” with the location of your resource.
1 |
https://LOCATION.api.cognitive.microsoft.com/vision/v3.2/read/analyze |
Now your are ready to post the request. Make sure the request method is “rmpost” and execute. If the request is success without any error, you will get a response with empty content but with some headers. The header wee need for the next request is “Operation-Location”. This is the location to to our request results once it’s finished. As it’s mentioned earlier, the request can take some times (Usually 1-3 seconds) to process. But it’s hard to predict. So we must check weather it’s finished or not.
How do we get the OCR results from the Operation-Location?
To request the OCR reading results, we need to send a GET request to the URL of “Operation-Location”. But we need to pass the “Subscription key” in the header as earlier. Please create a parameter and add the Subscription key as earlier. Now send the GET request and you will get a response with JSON body. The “status” object value will be “running” it it’s still running. Then you have to request it in a later time. If it succeeded you will get the OCR reading in a JSON format. All you need to do is parse the JSON and you’re done!
You can download the demo application source code from this GitHub link.
https://github.com/checkdigits/OCRReadClient_example
Also the source code for the post button is like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
procedure TfrmMain.btnStartClick(Sender: TObject); var lparam : Trestrequestparameter; imgProcessed: bool; jsonObj, jsonStatus: TJSONObject; begin memResponse.Lines.Clear; RESTClient.BaseURL := edAPIURL.Text; RESTRequest.Method:=rmpost; imgProcessed := false; try RESTRequest.Params.Clear; RESTResponse.RootElement := ''; lparam := RESTRequest.Params.AddItem; lparam.name := 'Ocp-Apim-Subscription-Key'; lparam.Value := edSubKey.Text; lparam.ContentType := ctNone; lparam.Kind := pkHTTPHEADER; //This one is Important otherwise the '==' will get url encoded lparam.Options := [poDoNotEncode]; lparam := RESTRequest.Params.AddItem; lparam.name := 'data'; lparam.Value := '{"url":"' + edImgURL.Text + '"}'; lparam.ContentType := ctAPPLICATION_JSON; lparam.Kind := pkGETorPOST; RESTRequest.Execute; if not RESTResponse.Status.Success then showmessage(RESTResponse.StatusText + ' ' + inttostr(RESTResponse.StatusCode)) else begin edOpLocation.Text := RESTResponse.Headers.Values['Operation-Location']; RESTClient.BaseURL := RESTResponse.Headers.Values['Operation-Location']; RESTRequest.Method:=rmget; RESTRequest.Params.Clear; RESTResponse.RootElement := ''; lparam := RESTRequest.Params.AddItem; lparam.name := 'Ocp-Apim-Subscription-Key'; lparam.Value := edSubKey.Text; lparam.ContentType := ctNone; lparam.Kind := pkHTTPHEADER; //This one is Important otherwise the '==' will get url encoded lparam.Options := [poDoNotEncode]; lparam := RESTRequest.Params.AddItem; lparam.name := 'data'; lparam.Value := '{body}'; lparam.ContentType := ctAPPLICATION_JSON; lparam.Kind := pkGETorPOST; while not imgProcessed do begin RESTResponse.RootElement := ''; RESTRequest.Execute; if RESTResponse.Status.Success then begin jsonObj := RESTResponse.JSONValue as TJSONObject; if trim(jsonObj.Values['status'].Value).ToLower = 'succeeded' then imgProcessed := true; end else showmessage(RESTResponse.StatusText + ' ' + inttostr(RESTResponse.StatusCode)) end; memResponse.Lines.Add(RESTResponse.JSONText); end; finally end; end; |
Are you ready to add computer vision to your applications?
Design. Code. Compile. Deploy.
Start Free Trial Upgrade Today
Free Delphi Community Edition Free C++Builder Community Edition