Skip to content

Commit df89d90

Browse files
committed
first
0 parents  commit df89d90

File tree

3 files changed

+124
-0
lines changed

3 files changed

+124
-0
lines changed

README.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# WinOCR
2+
3+
# Installation
4+
```powershell
5+
pip install winocr
6+
```
7+
8+
# Usage
9+
## Pillow
10+
```python
11+
import winocr
12+
from PIL import Image
13+
14+
img = Image.open('test.jpg')
15+
print((await winocr.recognize_pil(img, 'ja')).text)
16+
```
17+
18+
## OpenCV
19+
```python
20+
import winocr
21+
import cv2
22+
23+
img = cv2.imread('test.jpg')
24+
print((await winocr.recognize_cv2(img, 'ja')).text)
25+
```
26+
27+
## Web API
28+
Run server
29+
```powershell
30+
winocr_serve
31+
```
32+
33+
### curl
34+
```bash
35+
curl localhost:8000?lang=ja --data-binary @test.jpg
36+
```
37+
38+
### Python
39+
```python
40+
import requests
41+
42+
bytes = open('test.jpg', 'rb').read()
43+
requests.post('http://localhost:8000/?lang=ja', bytes).json()['text']
44+
```
45+
46+
### JavaScript
47+
```javascript
48+
// File
49+
const file = document.querySelector('[type=file]').files[0]
50+
await fetch('http://localhost:8000/', {method: 'POST', body: file}).then(r => r.json())
51+
52+
// Blob
53+
const blob = await fetch('https://image.itmedia.co.jp/ait/articles/1706/15/news015_16.jpg').then(r=>r.blob())
54+
await fetch('http://localhost:8000/?lang=ja', {method: 'POST', body: blob}).then(r => r.json())
55+
```

setup.cfg

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
[metadata]
2+
name = winocr
3+
version = 0.0.1
4+
author = Tomofumi Inoue
5+
author_email = funaox@gmail.com
6+
description = Windows.Media.Ocr
7+
long_description = file: README.md
8+
long_description_content_type = text/markdown
9+
url = https://github.com/GitHub30/winocr
10+
project_urls =
11+
Bug Tracker = https://github.com/GitHub30/winocr/issues
12+
classifiers =
13+
Programming Language :: Python :: 3
14+
License :: OSI Approved :: MIT License
15+
Operating System :: Microsoft :: Windows :: Windows 10
16+
17+
[options]
18+
py_modules = winocr
19+
install_requires =
20+
winrt
21+
22+
[options.entry_points]
23+
console_scripts =
24+
winocr_serve = winocr:serve

winocr.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
from winrt.windows.media.ocr import OcrEngine
2+
from winrt.windows.globalization import Language
3+
from winrt.windows.storage.streams import DataWriter
4+
from winrt.windows.graphics.imaging import SoftwareBitmap, BitmapPixelFormat
5+
6+
def recognize_bytes(bytes, width, height, lang='en'):
7+
cmd = 'Add-WindowsCapability -Online -Name "Language.OCR~~~en-US~0.0.1.0"'
8+
assert OcrEngine.is_language_supported(Language(lang)), cmd
9+
writer = DataWriter()
10+
writer.write_bytes(list(bytes))
11+
sb = SoftwareBitmap.create_copy_from_buffer(writer.detach_buffer(), BitmapPixelFormat.RGBA8, width, height)
12+
return OcrEngine.try_create_from_language(Language(lang)).recognize_async(sb)
13+
14+
def recognize_pil(img, lang='en'):
15+
if img.mode != 'RGBA':
16+
img = img.convert('RGBA')
17+
return recognize_bytes(img.tobytes(), img.width, img.height, lang)
18+
19+
def recognize_cv2(img, lang='en'):
20+
import cv2
21+
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGBA)
22+
return recognize_bytes(img.tobytes(), img.shape[1], img.shape[0], lang)
23+
24+
def _serializer(o):
25+
from winrt.windows.foundation.collections import IVectorView
26+
return list(o) if isinstance(o, IVectorView) else dict([(n, getattr(o, n)) for n in dir(o) if not n.startswith('_')])
27+
28+
def serve():
29+
import json
30+
import uvicorn
31+
from PIL import Image
32+
from io import BytesIO
33+
from fastapi import FastAPI, Request, Response
34+
from fastapi.middleware.cors import CORSMiddleware
35+
36+
app = FastAPI()
37+
app.add_middleware(CORSMiddleware, allow_origins=['*'], allow_credentials=True, allow_methods=['*'], allow_headers=['*'])
38+
@app.post('/')
39+
async def recognize(request: Request, lang: str = 'en'):
40+
result = await recognize_pil(Image.open(BytesIO(await request.body())), lang)
41+
return Response(json.dumps(result, default=_serializer, indent=2, ensure_ascii=False), media_type='application/json')
42+
uvicorn.run(app, host='0.0.0.0')
43+
44+
if __name__ == '__main__':
45+
serve()

0 commit comments

Comments
 (0)