1+ import uvicorn
12from fastapi import FastAPI , File , UploadFile , HTTPException , Form
2- from fastapi .responses import JSONResponse
33from typing import Optional , Union
44import base64
5- from .models import OCRRequest , SlideMatchRequest , DetectionRequest , APIResponse
6- from .services import ocr_service
5+ from app .models import OCRRequest , SlideMatchRequest , DetectionRequest , APIResponse
6+ from app .services import ocr_service
77
88app = FastAPI ()
99
10+ from starlette .datastructures import UploadFile as StarletteUploadFile
1011
11- def decode_image (image : Union [UploadFile , str , None ]) -> bytes :
12- if isinstance (image , UploadFile ):
13- return image .file .read ()
12+
13+ async def decode_image (image : Union [UploadFile , StarletteUploadFile , str , None ]) -> bytes :
14+ if image is None :
15+ raise HTTPException (status_code = 400 , detail = "No image provided" )
16+
17+ if isinstance (image , (UploadFile , StarletteUploadFile )):
18+ return await image .read ()
1419 elif isinstance (image , str ):
1520 try :
21+ # 检查是否是 base64 编码的图片
22+ if image .startswith (('data:image/' , 'data:application/' )):
23+ # 移除 MIME 类型前缀
24+ image = image .split (',' )[1 ]
1625 return base64 .b64decode (image )
1726 except :
1827 raise HTTPException (status_code = 400 , detail = "Invalid base64 string" )
19- elif image is None :
20- raise HTTPException (status_code = 400 , detail = "No image provided" )
2128 else :
2229 raise HTTPException (status_code = 400 , detail = "Invalid image input" )
2330
@@ -34,7 +41,7 @@ async def ocr_endpoint(
3441 if file is None and image is None :
3542 return APIResponse (code = 400 , message = "Either file or image must be provided" )
3643
37- image_bytes = decode_image (file or image )
44+ image_bytes = await decode_image (file or image )
3845 result = ocr_service .ocr_classification (image_bytes , probability , charsets , png_fix )
3946 return APIResponse (code = 200 , message = "Success" , data = result )
4047 except Exception as e :
@@ -53,8 +60,8 @@ async def slide_match_endpoint(
5360 if (target_file is None and target is None ) or (background_file is None and background is None ):
5461 return APIResponse (code = 400 , message = "Both target and background must be provided" )
5562
56- target_bytes = decode_image (target_file or target )
57- background_bytes = decode_image (background_file or background )
63+ target_bytes = await decode_image (target_file or target )
64+ background_bytes = await decode_image (background_file or background )
5865 result = ocr_service .slide_match (target_bytes , background_bytes , simple_target )
5966 return APIResponse (code = 200 , message = "Success" , data = result )
6067 except Exception as e :
@@ -70,8 +77,12 @@ async def detection_endpoint(
7077 if file is None and image is None :
7178 return APIResponse (code = 400 , message = "Either file or image must be provided" )
7279
73- image_bytes = decode_image (file or image )
80+ image_bytes = await decode_image (file or image )
7481 bboxes = ocr_service .detection (image_bytes )
7582 return APIResponse (code = 200 , message = "Success" , data = bboxes )
7683 except Exception as e :
7784 return APIResponse (code = 500 , message = str (e ))
85+
86+
87+ if __name__ == "__main__" :
88+ uvicorn .run (app , host = "0.0.0.0" , port = 8000 )
0 commit comments