I have an image with boxes and codes on each pox. I send it to Google Vision and get a response.
Then I display the list of buttons for each “product code”. On click, it should use “product code” to find its coordinates from the response list and draw a polygon on the image to highlight the box with that “product code”.
I follow mdn documentation on how to draw polygons but it does not work. Please help.
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.5.4/vue.global.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<title>Scan</title>
<style>
.form-group {
margin-bottom: 1rem;
}
.code-button {
margin: 5px;
}
</style>
</head>
<body>
<div id="scan" class="container">
<div class="row">
<div class="col-md-12">
<h1>Scan</h1>
<div class="form-group">
<label for="image">Image</label>
<input type="file" accept="image/*" class="form-control" id="image" name="image" @change="handleFileUpload">
</div>
<div class="form-group">
<button v-if="isImageSelected" class="btn btn-warning" @click="restartImage">Restart Image</button>
<button class="btn btn-success" @click="sendImage">Submit</button>
</div>
<div style="position: relative; width: 640px; height: 480px;">
<canvas id="canvas" width="640" height="480" style="position: absolute; top: 0; left: 0; z-index: 1;"></canvas>
<img id="preview" src="" alt="Preview" class="img-fluid" style="position: absolute; top: 0; left: 0; z-index: 0;">
</div>
<div id="results"></div>
<div id="code-buttons">
<button v-for="code in codeList" :key="code" class="code-button" @click="highlightBox(code)">
[[ code ]]
</button>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script>
<script>
const response = {
"product_codes": [
{
"code": "697902",
"bounding_poly": [
[574, 1250],
[766, 1256],
[765, 1282],
[573, 1276]
]
},
{
"code": "697902",
"bounding_poly": [
[762, 1390],
[960, 1384],
[961, 1413],
[763, 1419]
]
},
{
"code": "697902",
"bounding_poly": [
[673, 1570],
[880, 1579],
[878, 1612],
[672, 1603]
]
},
{
"code": "697902",
"bounding_poly": [
[364, 1792],
[573, 1796],
[572, 1825],
[364, 1821]
]
},
{
"code": "697902",
"bounding_poly": [
[640, 1796],
[848, 1779],
[851, 1811],
[643, 1828]
]
},
{
"code": "697902",
"bounding_poly": [
[1066, 1390],
[1248, 1388],
[1248, 1412],
[1066, 1414]
]
},
{
"code": "697902",
"bounding_poly": [
[942, 1784],
[1150, 1770],
[1152, 1800],
[944, 1814]
]
},
{
"code": "697902",
"bounding_poly": [
[631, 2039],
[848, 2024],
[850, 2053],
[633, 2068]
]
},
{
"code": "697902",
"bounding_poly": [
[1231, 1807],
[1445, 1809],
[1445, 1840],
[1231, 1838]
]
},
{
"code": "697902",
"bounding_poly": [
[1221, 2047],
[1439, 2032],
[1442, 2069],
[1224, 2084]
]
},
{
"code": "697902",
"bounding_poly": [
[591, 2295],
[811, 2275],
[814, 2309],
[594, 2329]
]
},
{
"code": "697902",
"bounding_poly": [
[904, 2296],
[1126, 2294],
[1126, 2327],
[904, 2329]
]
},
{
"code": "697902",
"bounding_poly": [
[216, 2572],
[444, 2543],
[449, 2581],
[221, 2611]
]
},
{
"code": "697902",
"bounding_poly": [
[561, 2558],
[788, 2546],
[790, 2582],
[563, 2594]
]
},
{
"code": "697902",
"bounding_poly": [
[897, 2559],
[1119, 2547],
[1121, 2586],
[899, 2598]
]
},
{
"code": "697902",
"bounding_poly": [
[2159, 2223],
[2384, 2237],
[2381, 2271],
[2157, 2257]
]
},
{
"code": "697902",
"bounding_poly": [
[3293, 2021],
[3513, 2024],
[3513, 2056],
[3293, 2053]
]
},
{
"code": "697902",
"bounding_poly": [
[3411, 2289],
[3641, 2289],
[3641, 2321],
[3411, 2321]
]
},
{
"code": "697902",
"bounding_poly": [
[2133, 2490],
[2361, 2509],
[2358, 2543],
[2130, 2525]
]
},
{
"code": "697902",
"bounding_poly": [
[3801, 2508],
[4030, 2503],
[4031, 2537],
[3802, 2542]
]
},
{
"code": "697902",
"bounding_poly": [
[3464, 2534],
[3698, 2541],
[3697, 2577],
[3463, 2570]
]
}
]
};
const { createApp } = Vue;
createApp({
delimiters: ['[[', ']]'],
data() {
return {
canvas: null,
context: null,
isImageSelected: false,
capturedImage: null,
response: response,
codeList: [...new Set(response.product_codes.map(item => item.code))]
}
},
methods: {
handleFileUpload(event) {
const file = event.target.files[0];
const reader = new FileReader();
reader.onload = (e) => {
this.capturedImage = e.target.result;
document.getElementById('preview').src = this.capturedImage;
document.getElementById('preview').style.display = 'block';
this.isImageSelected = true;
};
reader.readAsDataURL(file);
},
sendImage() {
this.drawPolygons();
},
restartImage() {
// Clear states
this.isImageSelected = false;
document.getElementById('preview').src = '';
document.getElementById('preview').style.display = 'none';
document.getElementById('results').innerHTML = '';
this.capturedImage = null;
},
drawPolygons() {
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
if (!ctx) {
console.error('Failed to get canvas context');
return;
}
const preview = document.getElementById('preview');
canvas.width = preview.width;
canvas.height = preview.height;
canvas.style.display = 'block'; // Ensure canvas is visible
this.response.product_codes.forEach(item => {
this.drawPolygon(item.bounding_poly, 'rgba(0, 255, 0, 0.5)');
});
},
drawPolygon(points, color) {
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
if (!ctx) {
console.error('Failed to get canvas context');
return;
}
ctx.fillStyle = color;
ctx.beginPath();
ctx.moveTo(points[0][0], points[0][1]);
points.slice(1).forEach(point => {
ctx.lineTo(point[0], point[1]);
});
ctx.closePath();
ctx.fill();
},
highlightBox(code) {
console.log('Highlighting box for code:', code);
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
if (!ctx) {
console.error('Failed to get canvas context');
return;
}
ctx.clearRect(0, 0, canvas.width, canvas.height);
this.drawPolygons();
const pointsArray = this.response.product_codes
.filter(item => item.code === code)
.map(item => item.bounding_poly);
console.log('Points array:', pointsArray);
pointsArray.forEach(points => {
this.drawPolygon(points, 'rgba(255, 0, 0, 0.5)');
});
}
}
}).mount('#scan');
</script>
</body>
</html>