Skip to content

Commit d8acb34

Browse files
committed
Update
1 parent 2f0afc2 commit d8acb34

File tree

5 files changed

+176
-140
lines changed

5 files changed

+176
-140
lines changed

examples/official/fastapi/backend.py

Lines changed: 24 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -1,179 +1,63 @@
1-
# backend.py
2-
from fastapi import FastAPI, File, UploadFile, Form
3-
from fastapi.responses import HTMLResponse, JSONResponse
1+
from fastapi import FastAPI, File, UploadFile
2+
from fastapi.responses import JSONResponse
43
from fastapi.staticfiles import StaticFiles
54
from fastapi.middleware.cors import CORSMiddleware
5+
from fastapi.templating import Jinja2Templates
6+
from fastapi.requests import Request
67
from dynamsoft_capture_vision_bundle import *
7-
import io
88
import os
99

1010
app = FastAPI()
1111

12-
# Initialize Dynamsoft components
12+
# License setup
1313
license_key = "DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ=="
14-
error_code, error_message = LicenseManager.init_license(license_key)
14+
LicenseManager.init_license(license_key)
1515
cvr_instance = CaptureVisionRouter()
1616

17-
# Configure CORS
17+
# CORS middleware
1818
app.add_middleware(
1919
CORSMiddleware,
2020
allow_origins=["*"],
2121
allow_methods=["*"],
2222
allow_headers=["*"],
2323
)
2424

25-
# Mount static files
26-
# app.mount("/static", StaticFiles(directory="static"), name="static")
25+
# Static and template folders
26+
app.mount("/static", StaticFiles(directory="static"), name="static")
27+
templates = Jinja2Templates(directory="templates")
2728

28-
@app.get("/", response_class=HTMLResponse)
29-
async def upload_page():
30-
return """
31-
<!DOCTYPE html>
32-
<html>
33-
<head>
34-
<title>Barcode Scanner</title>
35-
<style>
36-
.container { max-width: 600px; margin: 2rem auto; padding: 2rem; }
37-
.preview { max-width: 300px; margin: 1rem 0; }
38-
.progress { display: none; color: blue; }
39-
</style>
40-
</head>
41-
<body>
42-
<div class="container">
43-
<h1>Upload Barcode Image</h1>
44-
<input type="file" id="fileInput" accept="image/*" capture="camera">
45-
<img class="preview" id="preview">
46-
<div class="progress" id="progress">Processing...</div>
47-
<div id="result"></div>
48-
49-
<script>
50-
const fileInput = document.getElementById('fileInput');
51-
const preview = document.getElementById('preview');
52-
const progress = document.getElementById('progress');
53-
const resultDiv = document.getElementById('result');
54-
55-
fileInput.addEventListener('change', async (e) => {
56-
const file = e.target.files[0];
57-
if (!file) return;
58-
59-
// Display preview
60-
preview.src = URL.createObjectURL(file);
61-
preview.style.display = 'block';
62-
63-
// Show progress
64-
progress.style.display = 'block';
65-
66-
const formData = new FormData();
67-
formData.append('file', file);
68-
69-
try {
70-
const response = await fetch('/scan', {
71-
method: 'POST',
72-
body: formData
73-
});
74-
75-
const data = await response.json();
76-
if (data.success) {
77-
let resultHTML = `
78-
<h3>Found ${data.count} barcode(s)</h3>
79-
<div class="results-container">
80-
`;
81-
82-
data.items.forEach((item, index) => {
83-
resultHTML += `
84-
<div class="barcode-result">
85-
<h4>Barcode #${index + 1}</h4>
86-
<p><strong>Type:</strong> ${item.format}</p>
87-
<p><strong>Content:</strong> ${item.text}</p>
88-
<div class="location">
89-
<span>Coordinates:</span>
90-
<ul>
91-
<li>Point 1: (${item.location.x1}, ${item.location.y1})</li>
92-
<li>Point 2: (${item.location.x2}, ${item.location.y2})</li>
93-
<li>Point 3: (${item.location.x3}, ${item.location.y3})</li>
94-
<li>Point 4: (${item.location.x4}, ${item.location.y4})</li>
95-
</ul>
96-
</div>
97-
</div>
98-
`;
99-
});
100-
101-
resultHTML += `</div>`;
102-
resultDiv.innerHTML = resultHTML;
103-
} else {
104-
resultDiv.innerHTML = `Error: ${data.error}`;
105-
}
106-
} catch (err) {
107-
resultDiv.innerHTML = 'Request failed';
108-
} finally {
109-
progress.style.display = 'none';
110-
}
111-
});
112-
</script>
113-
</div>
114-
</body>
115-
</html>
116-
"""
29+
@app.get("/")
30+
async def upload_page(request: Request):
31+
return templates.TemplateResponse("index.html", {"request": request})
11732

11833
@app.post("/scan")
11934
async def scan_barcode(file: UploadFile = File(...)):
12035
try:
121-
# Read image file
12236
image_data = await file.read()
123-
124-
# # Decode barcodes
12537
result = cvr_instance.capture(image_data, EnumPresetTemplate.PT_READ_BARCODES.value)
126-
38+
12739
if result.get_error_code() != EnumErrorCode.EC_OK:
128-
return JSONResponse(
129-
{"success": False, "error": "No barcode detected"},
130-
status_code=400
131-
)
40+
return JSONResponse({"success": False, "error": "No barcode detected"}, status_code=400)
13241

133-
# Get and return results
13442
items = result.get_items()
13543
return_items = []
13644
for item in items:
137-
format_type = item.get_format()
138-
text = item.get_text()
139-
14045
location = item.get_location()
141-
x1 = location.points[0].x
142-
y1 = location.points[0].y
143-
x2 = location.points[1].x
144-
y2 = location.points[1].y
145-
x3 = location.points[2].x
146-
y3 = location.points[2].y
147-
x4 = location.points[3].x
148-
y4 = location.points[3].y
149-
del location
150-
15146
return_items.append({
152-
"format": format_type,
153-
"text": text,
47+
"format": item.get_format(),
48+
"text": item.get_text(),
15449
"location": {
155-
"x1": x1,
156-
"y1": y1,
157-
"x2": x2,
158-
"y2": y2,
159-
"x3": x3,
160-
"y3": y3,
161-
"x4": x4,
162-
"y4": y4
50+
"x1": location.points[0].x, "y1": location.points[0].y,
51+
"x2": location.points[1].x, "y2": location.points[1].y,
52+
"x3": location.points[2].x, "y3": location.points[2].y,
53+
"x4": location.points[3].x, "y4": location.points[3].y,
16354
}
16455
})
16556

166-
return {
167-
"success": True,
168-
"count": len(items),
169-
"items": return_items
170-
}
171-
57+
return {"success": True, "count": len(items), "items": return_items}
17258
except Exception as e:
173-
return JSONResponse(
174-
{"success": False, "error": str(e)},
175-
status_code=500
176-
)
59+
return JSONResponse({"success": False, "error": str(e)}, status_code=500)
60+
17761

17862
if __name__ == "__main__":
17963
import uvicorn
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
fastapi
2+
uvicorn
3+
dynamsoft-capture-vision-bundle
4+
python-multipart
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
const fileInput = document.getElementById('fileInput');
2+
const preview = document.getElementById('preview');
3+
const overlay = document.getElementById('overlay');
4+
const progress = document.getElementById('progress');
5+
const resultDiv = document.getElementById('result');
6+
7+
fileInput.addEventListener('change', async (e) => {
8+
const file = e.target.files[0];
9+
if (!file) return;
10+
11+
// Load the image preview
12+
const imageURL = URL.createObjectURL(file);
13+
preview.src = imageURL;
14+
15+
// Wait for image to load fully before proceeding
16+
preview.onload = async () => {
17+
// Set canvas size to match the displayed image size
18+
overlay.width = preview.naturalWidth;
19+
overlay.height = preview.naturalHeight;
20+
21+
const formData = new FormData();
22+
formData.append('file', file);
23+
24+
progress.style.display = 'block';
25+
resultDiv.innerHTML = '';
26+
const ctx = overlay.getContext('2d');
27+
ctx.clearRect(0, 0, overlay.width, overlay.height);
28+
29+
try {
30+
const response = await fetch('/scan', {
31+
method: 'POST',
32+
body: formData
33+
});
34+
35+
const data = await response.json();
36+
if (data.success) {
37+
let resultHTML = `<h3>Found ${data.count} barcode(s)</h3><div class="results-container">`;
38+
39+
data.items.forEach((item, index) => {
40+
const loc = item.location;
41+
42+
// Scale coordinates from original image to displayed image
43+
const x1 = loc.x1;
44+
const y1 = loc.y1;
45+
const x2 = loc.x2;
46+
const y2 = loc.y2;
47+
const x3 = loc.x3;
48+
const y3 = loc.y3;
49+
const x4 = loc.x4;
50+
const y4 = loc.y4;
51+
52+
// Draw the polygon
53+
ctx.beginPath();
54+
ctx.moveTo(x1, y1);
55+
ctx.lineTo(x2, y2);
56+
ctx.lineTo(x3, y3);
57+
ctx.lineTo(x4, y4);
58+
ctx.closePath();
59+
ctx.lineWidth = 2;
60+
ctx.strokeStyle = 'red';
61+
ctx.stroke();
62+
63+
// Draw the text near first point
64+
ctx.font = '16px Arial';
65+
ctx.fillStyle = 'blue';
66+
ctx.fillText(item.text, x1 + 5, y1 - 5);
67+
68+
resultHTML += `
69+
<div class="barcode-result">
70+
<h4>Barcode #${index + 1}</h4>
71+
<p><strong>Type:</strong> ${item.format}</p>
72+
<p><strong>Content:</strong> ${item.text}</p>
73+
</div>
74+
`;
75+
});
76+
77+
resultHTML += `</div>`;
78+
resultDiv.innerHTML = resultHTML;
79+
} else {
80+
resultDiv.innerHTML = `Error: ${data.error}`;
81+
}
82+
} catch (err) {
83+
resultDiv.innerHTML = 'Request failed';
84+
} finally {
85+
progress.style.display = 'none';
86+
}
87+
};
88+
});
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
.container {
2+
max-width: 600px;
3+
margin: 2rem auto;
4+
padding: 2rem;
5+
}
6+
7+
#imageview {
8+
position: relative;
9+
display: block;
10+
width: 100%;
11+
max-width: 80%;
12+
}
13+
14+
#imageview img {
15+
width: 100%;
16+
height: auto;
17+
object-fit: contain;
18+
display: block;
19+
}
20+
21+
#overlay {
22+
position: absolute;
23+
top: 0;
24+
left: 0;
25+
pointer-events: none;
26+
width: 100%;
27+
height: 100%;
28+
}
29+
30+
31+
.progress {
32+
display: none;
33+
color: blue;
34+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<!-- templates/index.html -->
2+
<!DOCTYPE html>
3+
<html>
4+
5+
<head>
6+
<title>Barcode Scanner</title>
7+
<link rel="stylesheet" href="/static/style.css">
8+
</head>
9+
10+
<body>
11+
<div class="container">
12+
<h1>Upload Barcode Image</h1>
13+
<input type="file" id="fileInput" accept="image/*" capture="camera">
14+
<div id="imageview">
15+
<img id="preview">
16+
<canvas id="overlay"></canvas>
17+
</div>
18+
<div class="progress" id="progress">Processing...</div>
19+
<div id="result"></div>
20+
</div>
21+
22+
23+
<script src="/static/script.js"></script>
24+
</body>
25+
26+
</html>

0 commit comments

Comments
 (0)