Spaces:
Sleeping
Sleeping
| 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)}") | |
| async def root(): | |
| return {"message": "Barcode Scanner API is running!"} | |
| async def health_check(): | |
| return {"status": "healthy"} | |
| 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) |