admin管理员组文章数量:1026989
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=".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="/[email protected]/dist/css/bootstrap.min.css">
<script src="@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="/[email protected]/dist/js/bootstrap.min.js"></script>
<script src="/@popperjs/[email protected]/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="/[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>
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/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/npm/[email protected]/dist/css/bootstrap.min.css">
<script src="https://unpkg/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/npm/[email protected]/dist/js/bootstrap.min.js"></script>
<script src="https://cdn.jsdelivr/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/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>
Share
Improve this question
asked Nov 16, 2024 at 2:55
Azamat UzbekovAzamat Uzbekov
1501 silver badge14 bronze badges
1
- Your question is too vague and the snippet you posted is not useful. Consider providing an example with the image you're trying to draw on already loaded and specify what exactly works other than you expect it to. – tao Commented Nov 16, 2024 at 10:59
1 Answer
Reset to default 0I got what the problem was!
- When I upload an image it has the original size: Image Width: 4032 Image Height: 3024
- Based on that size Google Vision returns coordinates.
- But on display Preview image/canvas has a smaller size based on the screen: Preview Image: 391 293
- So when I tried to draw a polygon based on Original size coordinates it simply could not fit those coordinates into the Preview image size.
Conclusion: Check the image size!
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=".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="/[email protected]/dist/css/bootstrap.min.css">
<script src="@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="/[email protected]/dist/js/bootstrap.min.js"></script>
<script src="/@popperjs/[email protected]/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="/[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>
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/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/npm/[email protected]/dist/css/bootstrap.min.css">
<script src="https://unpkg/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/npm/[email protected]/dist/js/bootstrap.min.js"></script>
<script src="https://cdn.jsdelivr/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/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>
Share
Improve this question
asked Nov 16, 2024 at 2:55
Azamat UzbekovAzamat Uzbekov
1501 silver badge14 bronze badges
1
- Your question is too vague and the snippet you posted is not useful. Consider providing an example with the image you're trying to draw on already loaded and specify what exactly works other than you expect it to. – tao Commented Nov 16, 2024 at 10:59
1 Answer
Reset to default 0I got what the problem was!
- When I upload an image it has the original size: Image Width: 4032 Image Height: 3024
- Based on that size Google Vision returns coordinates.
- But on display Preview image/canvas has a smaller size based on the screen: Preview Image: 391 293
- So when I tried to draw a polygon based on Original size coordinates it simply could not fit those coordinates into the Preview image size.
Conclusion: Check the image size!
本文标签: canvashow to draw polygons on image with vuejavascriptsStack Overflow
版权声明:本文标题:canvas - how to draw polygons on image with vuejavascripts - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745667751a2162273.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论