I have a JSON object which was extracted from an Image using AWS Textract after that I'm trying to draw same image using this textract data.
I'm trying to use Kendo Angular Drawing API for this and with limited documentation and usage examples I'm not completely sure about how to implement this from the geometry values in the JSON
Sample extracted object
{
"BlockType": "WORD",
"Confidence": 99.93840789794922,
"Text": "The",
"TextType": "PRINTED",
"Geometry": {
"BoundingBox": {
"Width": 0.036412131041288376,
"Height": 0.014151308685541153,
"Left": 0.13431107997894287,
"Top": 0.03131059184670448
},
"Polygon": [
{
"X": 0.13431107997894287,
"Y": 0.03131059184670448
},
{
"X": 0.17072321474552155,
"Y": 0.03131059184670448
},
{
"X": 0.17072321474552155,
"Y": 0.045461900532245636
},
{
"X": 0.13431107997894287,
"Y": 0.045461900532245636
}
]
},
"Id": "da6d85a6-3c79-484b-a07d-d84e968844ae",
"Page": 1,
"SearchKey": "The"
},
{
"BlockType": "WORD",
"Confidence": 99.77457427978516,
"Text": "Standard",
"TextType": "PRINTED",
"Geometry": {
"BoundingBox": {
"Width": 0.08427372574806213,
"Height": 0.013822372071444988,
"Left": 0.17733719944953918,
"Top": 0.03183155879378319
},
"Polygon": [
{
"X": 0.17733719944953918,
"Y": 0.03183155879378319
},
{
"X": 0.2616109251976013,
"Y": 0.03183155879378319
},
{
"X": 0.2616109251976013,
"Y": 0.04565393179655075
},
{
"X": 0.17733719944953918,
"Y": 0.04565393179655075
}
]
},
"Id": "e6587cca-2e7e-4231-9978-4b303241645b",
"Page": 1,
"SearchKey": "Standard"
},
{
"BlockType": "WORD",
"Confidence": 99.82964324951172,
"Text": "Bill",
"TextType": "PRINTED",
"Geometry": {
"BoundingBox": {
"Width": 0.035674601793289185,
"Height": 0.014618489891290665,
"Left": 0.26750874519348145,
"Top": 0.03160806745290756
},
"Polygon": [
{
"X": 0.26750874519348145,
"Y": 0.03160806745290756
},
{
"X": 0.30318334698677063,
"Y": 0.03160806745290756
},
{
"X": 0.30318334698677063,
"Y": 0.04622655734419823
},
{
"X": 0.26750874519348145,
"Y": 0.04622655734419823
}
]
},
"Id": "a6947531-ae08-40b3-8161-8fa78d430ad4",
"Page": 1,
"SearchKey": "Bill"
},
{
"BlockType": "WORD",
"Confidence": 99.97029876708984,
"Text": "of",
"TextType": "PRINTED",
"Geometry": {
"BoundingBox": {
"Width": 0.022517522796988487,
"Height": 0.014790677465498447,
"Left": 0.3098187744617462,
"Top": 0.03196505829691887
},
"Polygon": [
{
"X": 0.3098187744617462,
"Y": 0.03196505829691887
},
{
"X": 0.33233630657196045,
"Y": 0.03196505829691887
},
{
"X": 0.33233630657196045,
"Y": 0.04675573855638504
},
{
"X": 0.3098187744617462,
"Y": 0.04675573855638504
}
]
},
"Id": "53853140-e3c4-4f3a-a4b7-67ad39e1bb32",
"Page": 1,
"SearchKey": "of"
},
{
"BlockType": "WORD",
"Confidence": 99.88966369628906,
"Text": "Lading",
"TextType": "PRINTED",
"Geometry": {
"BoundingBox": {
"Width": 0.06747607886791229,
"Height": 0.01772529073059559,
"Left": 0.3355117440223694,
"Top": 0.032798975706100464
},
"Polygon": [
{
"X": 0.3355117440223694,
"Y": 0.032798975706100464
},
{
"X": 0.40298783779144287,
"Y": 0.032798975706100464
},
{
"X": 0.40298783779144287,
"Y": 0.0505242682993412
},
{
"X": 0.3355117440223694,
"Y": 0.0505242682993412
}
]
},
"Id": "5060d908-2318-48ad-bd6c-e4694501a8ce",
"Page": 1,
"SearchKey": "Lading"
},
{
"BlockType": "WORD",
"Confidence": 99.94490814208984,
"Text": "Form",
"TextType": "PRINTED",
"Geometry": {
"BoundingBox": {
"Width": 0.051753073930740356,
"Height": 0.014337458647787571,
"Left": 0.4095679521560669,
"Top": 0.033189330250024796
},
"Polygon": [
{
"X": 0.4095679521560669,
"Y": 0.033189330250024796
},
{
"X": 0.46132102608680725,
"Y": 0.033189330250024796
},
{
"X": 0.46132102608680725,
"Y": 0.04752678796648979
},
{
"X": 0.4095679521560669,
"Y": 0.04752678796648979
}
]
},
"Id": "3cf3fb15-e77f-48a5-bf76-be35d32f8be6",
"Page": 1,
"SearchKey": "Form"
},
Canvas drawing is completely new to me and I'm little lost about this implementation
Any recommendations will help me thanks
The retrieved data from AWS Textract are not exactly images.
The simplest way to say it is that they are blocks of recognized text, as stated at their webpage:
Amazon Textract makes it easy to add document text detection and analysis to your applications. The Amazon Textract Text Detection API can detect typed and handwritten text in a variety of documents including financial reports, medical records, and tax forms. For documents with structured data, you can use the Amazon Textract Document Analysis API to extract text, forms and tables. Furthermore, if you would like to process invoices and receipts, you can use the AnalyzeExpense API.
Those blocks are the results of the text-detection operation. A Block represents items that are recognized in a document within a group of pixels close to each other (see more here). They only represent something for the input you've sent to the API.
I've made the following snippet which does what you ask. However, the gathered response from the API is meant to be used as your implementation needs; and may not be the following way:
var data = [{
"BlockType": "WORD",
"Confidence": 99.93840789794922,
"Text": "The",
"TextType": "PRINTED",
"Geometry": {
"BoundingBox": {
"Width": 0.036412131041288376,
"Height": 0.014151308685541153,
"Left": 0.13431107997894287,
"Top": 0.03131059184670448
},
"Polygon": [
{
"X": 0.13431107997894287,
"Y": 0.03131059184670448
},
{
"X": 0.17072321474552155,
"Y": 0.03131059184670448
},
{
"X": 0.17072321474552155,
"Y": 0.045461900532245636
},
{
"X": 0.13431107997894287,
"Y": 0.045461900532245636
}
]
},
"Id": "da6d85a6-3c79-484b-a07d-d84e968844ae",
"Page": 1,
"SearchKey": "The"
},
{
"BlockType": "WORD",
"Confidence": 99.77457427978516,
"Text": "Standard",
"TextType": "PRINTED",
"Geometry": {
"BoundingBox": {
"Width": 0.08427372574806213,
"Height": 0.013822372071444988,
"Left": 0.17733719944953918,
"Top": 0.03183155879378319
},
"Polygon": [
{
"X": 0.17733719944953918,
"Y": 0.03183155879378319
},
{
"X": 0.2616109251976013,
"Y": 0.03183155879378319
},
{
"X": 0.2616109251976013,
"Y": 0.04565393179655075
},
{
"X": 0.17733719944953918,
"Y": 0.04565393179655075
}
]
},
"Id": "e6587cca-2e7e-4231-9978-4b303241645b",
"Page": 1,
"SearchKey": "Standard"
},
{
"BlockType": "WORD",
"Confidence": 99.82964324951172,
"Text": "Bill",
"TextType": "PRINTED",
"Geometry": {
"BoundingBox": {
"Width": 0.035674601793289185,
"Height": 0.014618489891290665,
"Left": 0.26750874519348145,
"Top": 0.03160806745290756
},
"Polygon": [
{
"X": 0.26750874519348145,
"Y": 0.03160806745290756
},
{
"X": 0.30318334698677063,
"Y": 0.03160806745290756
},
{
"X": 0.30318334698677063,
"Y": 0.04622655734419823
},
{
"X": 0.26750874519348145,
"Y": 0.04622655734419823
}
]
},
"Id": "a6947531-ae08-40b3-8161-8fa78d430ad4",
"Page": 1,
"SearchKey": "Bill"
},
{
"BlockType": "WORD",
"Confidence": 99.97029876708984,
"Text": "of",
"TextType": "PRINTED",
"Geometry": {
"BoundingBox": {
"Width": 0.022517522796988487,
"Height": 0.014790677465498447,
"Left": 0.3098187744617462,
"Top": 0.03196505829691887
},
"Polygon": [
{
"X": 0.3098187744617462,
"Y": 0.03196505829691887
},
{
"X": 0.33233630657196045,
"Y": 0.03196505829691887
},
{
"X": 0.33233630657196045,
"Y": 0.04675573855638504
},
{
"X": 0.3098187744617462,
"Y": 0.04675573855638504
}
]
},
"Id": "53853140-e3c4-4f3a-a4b7-67ad39e1bb32",
"Page": 1,
"SearchKey": "of"
},
{
"BlockType": "WORD",
"Confidence": 99.88966369628906,
"Text": "Lading",
"TextType": "PRINTED",
"Geometry": {
"BoundingBox": {
"Width": 0.06747607886791229,
"Height": 0.01772529073059559,
"Left": 0.3355117440223694,
"Top": 0.032798975706100464
},
"Polygon": [
{
"X": 0.3355117440223694,
"Y": 0.032798975706100464
},
{
"X": 0.40298783779144287,
"Y": 0.032798975706100464
},
{
"X": 0.40298783779144287,
"Y": 0.0505242682993412
},
{
"X": 0.3355117440223694,
"Y": 0.0505242682993412
}
]
},
"Id": "5060d908-2318-48ad-bd6c-e4694501a8ce",
"Page": 1,
"SearchKey": "Lading"
},
{
"BlockType": "WORD",
"Confidence": 99.94490814208984,
"Text": "Form",
"TextType": "PRINTED",
"Geometry": {
"BoundingBox": {
"Width": 0.051753073930740356,
"Height": 0.014337458647787571,
"Left": 0.4095679521560669,
"Top": 0.033189330250024796
},
"Polygon": [
{
"X": 0.4095679521560669,
"Y": 0.033189330250024796
},
{
"X": 0.46132102608680725,
"Y": 0.033189330250024796
},
{
"X": 0.46132102608680725,
"Y": 0.04752678796648979
},
{
"X": 0.4095679521560669,
"Y": 0.04752678796648979
}
]
},
"Id": "3cf3fb15-e77f-48a5-bf76-be35d32f8be6",
"Page": 1,
"SearchKey": "Form"
},
{
"BlockType": "WORD",
"Confidence": 99.93840789794922,
"Text": "The",
"TextType": "PRINTED",
"Geometry": {
"BoundingBox": {
"Width": 0.036412131041288376,
"Height": 0.014151308685541153,
"Left": 0.13431107997894287,
"Top": 0.03131059184670448
},
"Polygon": [
{
"X": 0.13431107997894287,
"Y": 0.03131059184670448
},
{
"X": 0.17072321474552155,
"Y": 0.03131059184670448
},
{
"X": 0.17072321474552155,
"Y": 0.045461900532245636
},
{
"X": 0.13431107997894287,
"Y": 0.045461900532245636
}
]
},
"Id": "da6d85a6-3c79-484b-a07d-d84e968844ae",
"Page": 1,
"SearchKey": "The"
},
{
"BlockType": "WORD",
"Confidence": 99.77457427978516,
"Text": "Standard",
"TextType": "PRINTED",
"Geometry": {
"BoundingBox": {
"Width": 0.08427372574806213,
"Height": 0.013822372071444988,
"Left": 0.17733719944953918,
"Top": 0.03183155879378319
},
"Polygon": [
{
"X": 0.17733719944953918,
"Y": 0.03183155879378319
},
{
"X": 0.2616109251976013,
"Y": 0.03183155879378319
},
{
"X": 0.2616109251976013,
"Y": 0.04565393179655075
},
{
"X": 0.17733719944953918,
"Y": 0.04565393179655075
}
]
},
"Id": "e6587cca-2e7e-4231-9978-4b303241645b",
"Page": 1,
"SearchKey": "Standard"
},
{
"BlockType": "WORD",
"Confidence": 99.82964324951172,
"Text": "Bill",
"TextType": "PRINTED",
"Geometry": {
"BoundingBox": {
"Width": 0.035674601793289185,
"Height": 0.014618489891290665,
"Left": 0.26750874519348145,
"Top": 0.03160806745290756
},
"Polygon": [
{
"X": 0.26750874519348145,
"Y": 0.03160806745290756
},
{
"X": 0.30318334698677063,
"Y": 0.03160806745290756
},
{
"X": 0.30318334698677063,
"Y": 0.04622655734419823
},
{
"X": 0.26750874519348145,
"Y": 0.04622655734419823
}
]
},
"Id": "a6947531-ae08-40b3-8161-8fa78d430ad4",
"Page": 1,
"SearchKey": "Bill"
},
{
"BlockType": "WORD",
"Confidence": 99.97029876708984,
"Text": "of",
"TextType": "PRINTED",
"Geometry": {
"BoundingBox": {
"Width": 0.022517522796988487,
"Height": 0.014790677465498447,
"Left": 0.3098187744617462,
"Top": 0.03196505829691887
},
"Polygon": [
{
"X": 0.3098187744617462,
"Y": 0.03196505829691887
},
{
"X": 0.33233630657196045,
"Y": 0.03196505829691887
},
{
"X": 0.33233630657196045,
"Y": 0.04675573855638504
},
{
"X": 0.3098187744617462,
"Y": 0.04675573855638504
}
]
},
"Id": "53853140-e3c4-4f3a-a4b7-67ad39e1bb32",
"Page": 1,
"SearchKey": "of"
},
{
"BlockType": "WORD",
"Confidence": 99.88966369628906,
"Text": "Lading",
"TextType": "PRINTED",
"Geometry": {
"BoundingBox": {
"Width": 0.06747607886791229,
"Height": 0.01772529073059559,
"Left": 0.3355117440223694,
"Top": 0.032798975706100464
},
"Polygon": [
{
"X": 0.3355117440223694,
"Y": 0.032798975706100464
},
{
"X": 0.40298783779144287,
"Y": 0.032798975706100464
},
{
"X": 0.40298783779144287,
"Y": 0.0505242682993412
},
{
"X": 0.3355117440223694,
"Y": 0.0505242682993412
}
]
},
"Id": "5060d908-2318-48ad-bd6c-e4694501a8ce",
"Page": 1,
"SearchKey": "Lading"
},
{
"BlockType": "WORD",
"Confidence": 99.94490814208984,
"Text": "Form",
"TextType": "PRINTED",
"Geometry": {
"BoundingBox": {
"Width": 0.051753073930740356,
"Height": 0.014337458647787571,
"Left": 0.4095679521560669,
"Top": 0.033189330250024796
},
"Polygon": [
{
"X": 0.4095679521560669,
"Y": 0.033189330250024796
},
{
"X": 0.46132102608680725,
"Y": 0.033189330250024796
},
{
"X": 0.46132102608680725,
"Y": 0.04752678796648979
},
{
"X": 0.4095679521560669,
"Y": 0.04752678796648979
}
]
},
"Id": "3cf3fb15-e77f-48a5-bf76-be35d32f8be6",
"Page": 1,
"SearchKey": "Form"
}
];
const zoom = 1400;
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const drawer = {
BoundingBox: drawBoundingBox,
Polygon: drawPolygon,
};
ctx.strokeStyle = "#0000ff";
ctx.lineWidth = 1;
data.forEach((args) => {
if (args.Geometry) {
for (var key in args.Geometry) {
if (typeof drawer[key] === 'function') {
drawer[key](args.Geometry[key], args.Text);
} else {
console.error('Unsupported object, you\'ll need to add support here!');
}
}
}
});
function drawBoundingBox(args, text) {
ctx.beginPath();
ctx.rect(args.Left * zoom, args.Top * zoom, args.Width * zoom, args.Height * zoom);
ctx.stroke();
ctx.font = (args.Height * zoom) + "px Arial";
ctx.fillText(text, (args.Left * zoom), (args.Top * zoom) + (args.Height * zoom));
}
function drawPolygon(args, text) {
ctx.beginPath();
ctx.moveTo(args[0].X * zoom, args[0].Y * zoom);
for (var i = 1; i < args.length; i++) {
ctx.lineTo(args[i].X * zoom, args[i].Y * zoom);
}
ctx.lineTo(args[0].X * zoom, args[0].Y * zoom);
ctx.stroke();
const h = ((args[args.length - 1].Y - args[0].Y) * zoom);
ctx.font = h + "px Arial";
ctx.strokeText(text, args[0].X * zoom, (args[0].Y + h) * zoom);
}
<canvas width="850" height="450" id="canvas"></canvas>
This is the output for the example JSON data you've provided by using the snippet code:
Canvas drawing is not that hard. To code the snippet I've shared to you, you only need knowledge on 3 subjects (Text, Rect and lineTo)
I've ported the vanilla code to Kendo Angular Drawing in this stackblitz sample, I'd like to let you know that vanilla is a lot easier to use than Kendo, this is the output:
In both cases, canvas and kendo; I had to add a zoom
variable because your X, Y
values were too small.