File size: 4,781 Bytes
8dee667
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import streamlit as st
import os
from PIL import Image
import random
import string

def generate_access_code():
    """Generate a random access code consisting of 3 characters."""
    return ''.join(random.choices(string.ascii_uppercase + string.digits, k=3))

def check_access_code(input_code):
    """Check if the entered access code matches the generated access code."""
    return input_code == st.session_state.access_code

def initialize_session_state():
    """Initialize session state variables."""
    if 'coordinates' not in st.session_state:
        st.session_state.coordinates = []
    if 'image' not in st.session_state:
        st.session_state.image = None
    if 'access_code' not in st.session_state:
        st.session_state.access_code = generate_access_code()

def render_canvas(image_width, image_height):
    """Render the HTML canvas for recording mouse coordinates."""
    canvas_html = f"""
    <script>
    let canvas = document.getElementById('canvas');
    let ctx = canvas.getContext('2d');
    let coordinates = [];

    canvas.addEventListener('mousedown', function(event) {{
        let rect = canvas.getBoundingClientRect();
        let x = event.clientX - rect.left;
        let y = event.clientY - rect.top;
        coordinates.push({{x: x, y: y}});
        updateCoordinates();
        ctx.fillStyle = "red";
        ctx.fillRect(x - 2, y - 2, 4, 4);
    }});

    function updateCoordinates() {{
        let coordsDiv = document.getElementById('coordinates');
        coordsDiv.innerHTML = '';
        coordinates.forEach((coord, index) => {{
            coordsDiv.innerHTML += `<li>${{index + 1}}. X: ${{coord.x}}, Y: ${{coord.y}}</li>`;
        }});
    }}

    function clearCoordinates() {{
        coordinates = [];
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        updateCoordinates();
    }}

    window.clearCoordinates = clearCoordinates;
    </script>
    """
    st.markdown(f"""
    <canvas id="canvas" width="{image_width}" height="{image_height}" style="border:1px solid #000000;"></canvas>
    {canvas_html}
    <button onclick="window.clearCoordinates()">Clear Coordinates</button>
    """, unsafe_allow_html=True)

def main():
    """Main function to run the Streamlit app."""
    st.title("Record XY Mouse Coordinates on an Uploaded Image")

    # Initialize session state variables
    initialize_session_state()

    # Image upload section
    uploaded_file = st.file_uploader("Upload an image (Max 500 KB):", type=["jpg", "jpeg", "png"])

    # Access code section
    st.write("To prevent automated submissions, an Access Code has been implemented for this tool.")
    st.image(f"https://dummyimage.com/60x30/000/fff&text={st.session_state.access_code}", caption="Access Code")
    access_code_input = st.text_input("Enter Access Code:")
    if st.button("Validate Access Code"):
        if check_access_code(access_code_input):
            st.success("Access Code is correct.")
        else:
            st.error("Access Code is incorrect.")

    # Display canvas if image is uploaded and access code is correct
    if uploaded_file and check_access_code(access_code_input):
        st.session_state.image = Image.open(uploaded_file)
        st.image(st.session_state.image, caption="Uploaded Image")

        # Display the canvas for coordinate recording
        render_canvas(st.session_state.image.width, st.session_state.image.height)

        # Display coordinates list
        st.markdown("<h3>Recorded Coordinates:</h3>", unsafe_allow_html=True)
        st.markdown("<ul id='coordinates'></ul>", unsafe_allow_html=True)

        # Show image details
        st.write(f"Image width = {st.session_state.image.width} px")
        st.write(f"Image height = {st.session_state.image.height} px")
        st.write(f"Number of coordinates = {len(st.session_state.coordinates)}")

    # Add, Change, and Delete coordinates sections
    st.markdown("<h3>Modify Coordinates:</h3>", unsafe_allow_html=True)
    x_val = st.number_input("X-coord:", min_value=0, max_value=st.session_state.image.width if st.session_state.image else 0)
    y_val = st.number_input("Y-coord:", min_value=0, max_value=st.session_state.image.height if st.session_state.image else 0)
    action = st.selectbox("Action:", ["Add", "Change", "Delete"])
    if st.button("Execute"):
        if action == "Add":
            st.session_state.coordinates.append((x_val, y_val))
        elif action == "Change":
            if len(st.session_state.coordinates) > 0:
                st.session_state.coordinates[-1] = (x_val, y_val)
        elif action == "Delete":
            if len(st.session_state.coordinates) > 0:
                st.session_state.coordinates.pop()
        st.experimental_rerun()

if __name__ == "__main__":
    main()