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
Add a comment  | 

1 Answer 1

Reset to default 0

I got what the problem was!

  1. When I upload an image it has the original size: Image Width: 4032 Image Height: 3024
  2. Based on that size Google Vision returns coordinates.
  3. But on display Preview image/canvas has a smaller size based on the screen: Preview Image: 391 293
  4. 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
Add a comment  | 

1 Answer 1

Reset to default 0

I got what the problem was!

  1. When I upload an image it has the original size: Image Width: 4032 Image Height: 3024
  2. Based on that size Google Vision returns coordinates.
  3. But on display Preview image/canvas has a smaller size based on the screen: Preview Image: 391 293
  4. 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