File size: 3,138 Bytes
7129810
 
 
2382cc9
 
 
4336a2c
 
 
7129810
2382cc9
7129810
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4336a2c
7129810
 
 
 
4336a2c
7129810
 
4336a2c
7129810
 
4336a2c
7129810
 
4336a2c
7129810
 
4336a2c
7129810
2382cc9
7129810
 
 
38bfe3c
7129810
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ff3b583
7129810
 
 
 
2382cc9
7129810
2382cc9
7129810
 
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
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
import cv2
import zxingcpp
import numpy as np
from PIL import Image
import base64
import io
from typing import Dict, Any

app = FastAPI(title="Barcode Scanner API", version="1.0.0")

# Add CORS middleware
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # In production, specify your frontend domain
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

class ImageRequest(BaseModel):
    image: str  # Base64 encoded image

class ScanResponse(BaseModel):
    status: str
    text: str = None
    format: str = None
    message: str = None

def decode_base64_image(base64_string: str) -> np.ndarray:
    """Decode base64 image to numpy array"""
    try:
        # Handle data URI format
        if base64_string.startswith('data:image'):
            # Remove the data:image/jpeg;base64, prefix
            base64_string = base64_string.split(',')[1]
        
        # Decode base64
        image_bytes = base64.b64decode(base64_string)
        
        # Convert to PIL Image
        pil_image = Image.open(io.BytesIO(image_bytes))
        
        # Convert to numpy array
        image_array = np.array(pil_image)
        
        return image_array
    
    except Exception as e:
        raise HTTPException(status_code=400, detail=f"Invalid image format: {str(e)}")

@app.get("/")
async def root():
    return {"message": "Barcode Scanner API is running!"}

@app.get("/health")
async def health_check():
    return {"status": "healthy"}

@app.post("/scan", response_model=ScanResponse)
async def scan_barcode(request: ImageRequest):
    """Scan barcode from base64 encoded image"""
    try:
        # Decode the base64 image
        image_array = decode_base64_image(request.image)
        
        # Convert RGB to BGR for OpenCV (if needed)
        if len(image_array.shape) == 3 and image_array.shape[2] == 3:
            bgr_image = cv2.cvtColor(image_array, cv2.COLOR_RGB2BGR)
        elif len(image_array.shape) == 3 and image_array.shape[2] == 4:
            # Handle RGBA images
            rgb_image = cv2.cvtColor(image_array, cv2.COLOR_RGBA2RGB)
            bgr_image = cv2.cvtColor(rgb_image, cv2.COLOR_RGB2BGR)
        else:
            bgr_image = image_array
        
        # Scan for barcodes
        results = zxingcpp.read_barcodes(bgr_image)
        
        if results:
            # Return the first barcode found
            barcode = results[0]
            return ScanResponse(
                status="success",
                text=barcode.text,
                format=str(barcode.format)
            )
        else:
            return ScanResponse(
                status="error",
                message="No barcode detected"
            )
    
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Processing error: {str(e)}")

# For HuggingFace Spaces, you might need this
if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=7860)