chrome-lens-py 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- chrome_lens_py-1.0.0/LICENSE +21 -0
- chrome_lens_py-1.0.0/PKG-INFO +204 -0
- chrome_lens_py-1.0.0/README.md +185 -0
- chrome_lens_py-1.0.0/setup.cfg +4 -0
- chrome_lens_py-1.0.0/setup.py +39 -0
- chrome_lens_py-1.0.0/src/chrome_lens_py/__init__.py +1 -0
- chrome_lens_py-1.0.0/src/chrome_lens_py/constants.py +49 -0
- chrome_lens_py-1.0.0/src/chrome_lens_py/image_processing.py +16 -0
- chrome_lens_py-1.0.0/src/chrome_lens_py/lens_api.py +36 -0
- chrome_lens_py-1.0.0/src/chrome_lens_py/main.py +59 -0
- chrome_lens_py-1.0.0/src/chrome_lens_py/request_handler.py +108 -0
- chrome_lens_py-1.0.0/src/chrome_lens_py/text_processing.py +116 -0
- chrome_lens_py-1.0.0/src/chrome_lens_py/utils.py +15 -0
- chrome_lens_py-1.0.0/src/chrome_lens_py.egg-info/PKG-INFO +204 -0
- chrome_lens_py-1.0.0/src/chrome_lens_py.egg-info/SOURCES.txt +17 -0
- chrome_lens_py-1.0.0/src/chrome_lens_py.egg-info/dependency_links.txt +1 -0
- chrome_lens_py-1.0.0/src/chrome_lens_py.egg-info/entry_points.txt +2 -0
- chrome_lens_py-1.0.0/src/chrome_lens_py.egg-info/requires.txt +6 -0
- chrome_lens_py-1.0.0/src/chrome_lens_py.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Bropines
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: chrome_lens_py
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Library to use Google Lens OCR via API used in Chromium.
|
|
5
|
+
Home-page: https://github.com/bropines/chrome-lens-py
|
|
6
|
+
Author: Bropines
|
|
7
|
+
Author-email: bropines@gmail.com
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Requires-Dist: requests
|
|
14
|
+
Requires-Dist: Pillow
|
|
15
|
+
Requires-Dist: filetype
|
|
16
|
+
Requires-Dist: lxml
|
|
17
|
+
Requires-Dist: json5
|
|
18
|
+
Requires-Dist: rich
|
|
19
|
+
|
|
20
|
+
# Chrome Lens API for Python
|
|
21
|
+
|
|
22
|
+
[English](/README.md) | [Русский](/README_RU.md)
|
|
23
|
+
|
|
24
|
+
This project provides a Python library and CLI tool for interacting with Google Lens's OCR functionality via the API used in Chromium. This allows you to process images and extract text data, including full text, coordinates, and stitched text using various methods.
|
|
25
|
+
|
|
26
|
+
## Features
|
|
27
|
+
|
|
28
|
+
- **Full Text Extraction**: Extract the complete text from an image.
|
|
29
|
+
- **Coordinates Extraction**: Extract text along with its coordinates.
|
|
30
|
+
- **Stitched Text**: Reconstruct text from blocks using various methods:
|
|
31
|
+
- **Default Full Text**: Basic method for stitching text blocks.
|
|
32
|
+
- **Old Method**: Sequential text stitching.
|
|
33
|
+
- **New Method**: Enhanced text stitching.
|
|
34
|
+
|
|
35
|
+
PS. Lens has a problem with the way it displays full text, which is why methods have been added that stitch text from coordinates.
|
|
36
|
+
|
|
37
|
+
## Installation
|
|
38
|
+
|
|
39
|
+
You can install the package using `pip`:
|
|
40
|
+
|
|
41
|
+
### From PyPI (SOON)
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pip install chrome-lens-py
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### From GIT
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pip install git+https://github.com/bropines/chrome-lens-py.git
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### From source
|
|
54
|
+
|
|
55
|
+
Clone the repository and install the package:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
git clone https://github.com/bropines/chrome-lens-api-py.git
|
|
59
|
+
cd chrome-lens-api-py
|
|
60
|
+
pip install -r requirements.txt
|
|
61
|
+
pip install .
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Usage
|
|
65
|
+
|
|
66
|
+
You can use the `lens_scan` command from the CLI to process images and extract text data, or you can use the Python API to integrate this functionality into your own projects.
|
|
67
|
+
|
|
68
|
+
### CLI Usage
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
lens_scan <image_file> <data_type>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
#### Data Types
|
|
75
|
+
|
|
76
|
+
- **all**: Get all data (full text, coordinates, and stitched text using both methods).
|
|
77
|
+
- **full_text_default**: Get only the default full text.
|
|
78
|
+
- **full_text_old_method**: Get stitched text using the old sequential method.
|
|
79
|
+
- **full_text_new_method**: Get stitched text using the new enhanced method.
|
|
80
|
+
- **coordinates**: Get text along with coordinates.
|
|
81
|
+
|
|
82
|
+
#### Example
|
|
83
|
+
|
|
84
|
+
To extract text using the new method for stitching:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
lens_scan path/to/image.jpg full_text_new_method
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
To get all available data:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
lens_scan path/to/image.jpg all
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
#### CLI Help
|
|
97
|
+
|
|
98
|
+
You can use the `-h` or `--help` option to display usage information:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
lens_scan -h
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Programmatic API Usage
|
|
105
|
+
|
|
106
|
+
In addition to the CLI tool, this project provides a Python API that can be used in your scripts.
|
|
107
|
+
|
|
108
|
+
#### Basic Programmatic Usage
|
|
109
|
+
|
|
110
|
+
First, import the `LensAPI` class:
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
from chrome_lens_py import LensAPI
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
#### Example Programmatic Usage
|
|
117
|
+
|
|
118
|
+
1. **Instantiate the API**:
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
api = LensAPI()
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
2. **Process an image**:
|
|
125
|
+
|
|
126
|
+
- **Get all data**:
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
result = api.get_all_data('path/to/image.jpg')
|
|
130
|
+
print(result)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
- **Get the default full text**:
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
result = api.get_full_text('path/to/image.jpg')
|
|
137
|
+
print(result)
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
- **Get stitched text using the old method**:
|
|
141
|
+
|
|
142
|
+
```python
|
|
143
|
+
result = api.get_stitched_text_sequential('path/to/image.jpg')
|
|
144
|
+
print(result)
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
- **Get stitched text using the new method**:
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
result = api.get_stitched_text_smart('path/to/image.jpg')
|
|
151
|
+
print(result)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
- **Get text with coordinates**:
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
result = api.get_text_with_coordinates('path/to/image.jpg')
|
|
158
|
+
print(result)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
#### Programmatic API Methods
|
|
162
|
+
|
|
163
|
+
- **`get_all_data(image_path)`**: Returns all available data for the given image.
|
|
164
|
+
- **`get_full_text(image_path)`**: Returns only the full text from the image.
|
|
165
|
+
- **`get_text_with_coordinates(image_path)`**: Returns text along with its coordinates in JSON format.
|
|
166
|
+
- **`get_stitched_text_smart(image_path)`**: Returns stitched text using the enhanced method.
|
|
167
|
+
- **`get_stitched_text_sequential(image_path)`**: Returns stitched text using the basic sequential method.
|
|
168
|
+
|
|
169
|
+
## Project Structure
|
|
170
|
+
|
|
171
|
+
```
|
|
172
|
+
/chrome-lens-api-py
|
|
173
|
+
│
|
|
174
|
+
├── /src
|
|
175
|
+
│ ├── /chrome_lens_py
|
|
176
|
+
│ │ ├── __init__.py # Package initialization
|
|
177
|
+
│ │ ├── constants.py # Constants used in the project
|
|
178
|
+
│ │ ├── utils.py # Utility functions
|
|
179
|
+
│ │ ├── image_processing.py # Image processing module
|
|
180
|
+
│ │ ├── request_handler.py # API request handling module
|
|
181
|
+
│ │ ├── text_processing.py # Text processing module
|
|
182
|
+
│ │ ├── lens_api.py # API interface for use in other scripts
|
|
183
|
+
│ │ └── main.py # CLI tool entry point
|
|
184
|
+
│
|
|
185
|
+
├── setup.py # Installation setup
|
|
186
|
+
├── README.md # Project description and usage guide
|
|
187
|
+
└── requirements.txt # Project dependencies
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Acknowledgments
|
|
191
|
+
|
|
192
|
+
Special thanks to [dimdenGD](https://github.com/dimdenGD) for the method of text extraction used in this project. You can check out their work on the [chrome-lens-ocr](https://github.com/dimdenGD/chrome-lens-ocr) repository. This project is inspired by their approach to leveraging Google Lens OCR functionality.
|
|
193
|
+
|
|
194
|
+
## License
|
|
195
|
+
|
|
196
|
+
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for more details.
|
|
197
|
+
|
|
198
|
+
## Disclaimer
|
|
199
|
+
|
|
200
|
+
This project is intended for educational purposes only. The use of Google Lens OCR functionality must comply with Google's Terms of Service. The author of this project is not responsible for any misuse of this software or for any consequences arising from its use. Users are solely responsible for ensuring that their use of this software complies with all applicable laws and regulations.
|
|
201
|
+
|
|
202
|
+
## Author
|
|
203
|
+
|
|
204
|
+
### Bropines - [Mail](mailto:bropines@gmail.com) / [Telegram](https://t.me/bropines)
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# Chrome Lens API for Python
|
|
2
|
+
|
|
3
|
+
[English](/README.md) | [Русский](/README_RU.md)
|
|
4
|
+
|
|
5
|
+
This project provides a Python library and CLI tool for interacting with Google Lens's OCR functionality via the API used in Chromium. This allows you to process images and extract text data, including full text, coordinates, and stitched text using various methods.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Full Text Extraction**: Extract the complete text from an image.
|
|
10
|
+
- **Coordinates Extraction**: Extract text along with its coordinates.
|
|
11
|
+
- **Stitched Text**: Reconstruct text from blocks using various methods:
|
|
12
|
+
- **Default Full Text**: Basic method for stitching text blocks.
|
|
13
|
+
- **Old Method**: Sequential text stitching.
|
|
14
|
+
- **New Method**: Enhanced text stitching.
|
|
15
|
+
|
|
16
|
+
PS. Lens has a problem with the way it displays full text, which is why methods have been added that stitch text from coordinates.
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
You can install the package using `pip`:
|
|
21
|
+
|
|
22
|
+
### From PyPI (SOON)
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install chrome-lens-py
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### From GIT
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install git+https://github.com/bropines/chrome-lens-py.git
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### From source
|
|
35
|
+
|
|
36
|
+
Clone the repository and install the package:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
git clone https://github.com/bropines/chrome-lens-api-py.git
|
|
40
|
+
cd chrome-lens-api-py
|
|
41
|
+
pip install -r requirements.txt
|
|
42
|
+
pip install .
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Usage
|
|
46
|
+
|
|
47
|
+
You can use the `lens_scan` command from the CLI to process images and extract text data, or you can use the Python API to integrate this functionality into your own projects.
|
|
48
|
+
|
|
49
|
+
### CLI Usage
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
lens_scan <image_file> <data_type>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
#### Data Types
|
|
56
|
+
|
|
57
|
+
- **all**: Get all data (full text, coordinates, and stitched text using both methods).
|
|
58
|
+
- **full_text_default**: Get only the default full text.
|
|
59
|
+
- **full_text_old_method**: Get stitched text using the old sequential method.
|
|
60
|
+
- **full_text_new_method**: Get stitched text using the new enhanced method.
|
|
61
|
+
- **coordinates**: Get text along with coordinates.
|
|
62
|
+
|
|
63
|
+
#### Example
|
|
64
|
+
|
|
65
|
+
To extract text using the new method for stitching:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
lens_scan path/to/image.jpg full_text_new_method
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
To get all available data:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
lens_scan path/to/image.jpg all
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
#### CLI Help
|
|
78
|
+
|
|
79
|
+
You can use the `-h` or `--help` option to display usage information:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
lens_scan -h
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Programmatic API Usage
|
|
86
|
+
|
|
87
|
+
In addition to the CLI tool, this project provides a Python API that can be used in your scripts.
|
|
88
|
+
|
|
89
|
+
#### Basic Programmatic Usage
|
|
90
|
+
|
|
91
|
+
First, import the `LensAPI` class:
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
from chrome_lens_py import LensAPI
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
#### Example Programmatic Usage
|
|
98
|
+
|
|
99
|
+
1. **Instantiate the API**:
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
api = LensAPI()
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
2. **Process an image**:
|
|
106
|
+
|
|
107
|
+
- **Get all data**:
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
result = api.get_all_data('path/to/image.jpg')
|
|
111
|
+
print(result)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
- **Get the default full text**:
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
result = api.get_full_text('path/to/image.jpg')
|
|
118
|
+
print(result)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
- **Get stitched text using the old method**:
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
result = api.get_stitched_text_sequential('path/to/image.jpg')
|
|
125
|
+
print(result)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
- **Get stitched text using the new method**:
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
result = api.get_stitched_text_smart('path/to/image.jpg')
|
|
132
|
+
print(result)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
- **Get text with coordinates**:
|
|
136
|
+
|
|
137
|
+
```python
|
|
138
|
+
result = api.get_text_with_coordinates('path/to/image.jpg')
|
|
139
|
+
print(result)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
#### Programmatic API Methods
|
|
143
|
+
|
|
144
|
+
- **`get_all_data(image_path)`**: Returns all available data for the given image.
|
|
145
|
+
- **`get_full_text(image_path)`**: Returns only the full text from the image.
|
|
146
|
+
- **`get_text_with_coordinates(image_path)`**: Returns text along with its coordinates in JSON format.
|
|
147
|
+
- **`get_stitched_text_smart(image_path)`**: Returns stitched text using the enhanced method.
|
|
148
|
+
- **`get_stitched_text_sequential(image_path)`**: Returns stitched text using the basic sequential method.
|
|
149
|
+
|
|
150
|
+
## Project Structure
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
/chrome-lens-api-py
|
|
154
|
+
│
|
|
155
|
+
├── /src
|
|
156
|
+
│ ├── /chrome_lens_py
|
|
157
|
+
│ │ ├── __init__.py # Package initialization
|
|
158
|
+
│ │ ├── constants.py # Constants used in the project
|
|
159
|
+
│ │ ├── utils.py # Utility functions
|
|
160
|
+
│ │ ├── image_processing.py # Image processing module
|
|
161
|
+
│ │ ├── request_handler.py # API request handling module
|
|
162
|
+
│ │ ├── text_processing.py # Text processing module
|
|
163
|
+
│ │ ├── lens_api.py # API interface for use in other scripts
|
|
164
|
+
│ │ └── main.py # CLI tool entry point
|
|
165
|
+
│
|
|
166
|
+
├── setup.py # Installation setup
|
|
167
|
+
├── README.md # Project description and usage guide
|
|
168
|
+
└── requirements.txt # Project dependencies
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Acknowledgments
|
|
172
|
+
|
|
173
|
+
Special thanks to [dimdenGD](https://github.com/dimdenGD) for the method of text extraction used in this project. You can check out their work on the [chrome-lens-ocr](https://github.com/dimdenGD/chrome-lens-ocr) repository. This project is inspired by their approach to leveraging Google Lens OCR functionality.
|
|
174
|
+
|
|
175
|
+
## License
|
|
176
|
+
|
|
177
|
+
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for more details.
|
|
178
|
+
|
|
179
|
+
## Disclaimer
|
|
180
|
+
|
|
181
|
+
This project is intended for educational purposes only. The use of Google Lens OCR functionality must comply with Google's Terms of Service. The author of this project is not responsible for any misuse of this software or for any consequences arising from its use. Users are solely responsible for ensuring that their use of this software complies with all applicable laws and regulations.
|
|
182
|
+
|
|
183
|
+
## Author
|
|
184
|
+
|
|
185
|
+
### Bropines - [Mail](mailto:bropines@gmail.com) / [Telegram](https://t.me/bropines)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
import pathlib
|
|
3
|
+
|
|
4
|
+
# The directory containing this file
|
|
5
|
+
HERE = pathlib.Path(__file__).parent
|
|
6
|
+
|
|
7
|
+
# The text of the README file
|
|
8
|
+
README = (HERE / "README.md").read_text()
|
|
9
|
+
|
|
10
|
+
setup(
|
|
11
|
+
name='chrome_lens_py',
|
|
12
|
+
version='1.0.0',
|
|
13
|
+
packages=find_packages(where="src"),
|
|
14
|
+
package_dir={"": "src"},
|
|
15
|
+
install_requires=[
|
|
16
|
+
'requests',
|
|
17
|
+
'Pillow',
|
|
18
|
+
'filetype',
|
|
19
|
+
'lxml',
|
|
20
|
+
'json5',
|
|
21
|
+
'rich',
|
|
22
|
+
],
|
|
23
|
+
entry_points={
|
|
24
|
+
'console_scripts': [
|
|
25
|
+
'lens_scan=chrome_lens_py.main:main',
|
|
26
|
+
],
|
|
27
|
+
},
|
|
28
|
+
description='Library to use Google Lens OCR via API used in Chromium.',
|
|
29
|
+
long_description=README,
|
|
30
|
+
long_description_content_type='text/markdown', # Указание типа содержимого
|
|
31
|
+
author='Bropines',
|
|
32
|
+
author_email='bropines@gmail.com',
|
|
33
|
+
url='https://github.com/bropines/chrome-lens-py',
|
|
34
|
+
classifiers=[
|
|
35
|
+
'Programming Language :: Python :: 3',
|
|
36
|
+
'License :: OSI Approved :: MIT License',
|
|
37
|
+
'Operating System :: OS Independent',
|
|
38
|
+
],
|
|
39
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .lens_api import LensAPI
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# constants.py
|
|
2
|
+
|
|
3
|
+
LENS_ENDPOINT = 'https://lens.google.com/v3/upload'
|
|
4
|
+
|
|
5
|
+
SUPPORTED_MIMES = [
|
|
6
|
+
'image/x-icon',
|
|
7
|
+
'image/bmp',
|
|
8
|
+
'image/jpeg',
|
|
9
|
+
'image/png',
|
|
10
|
+
'image/tiff',
|
|
11
|
+
'image/webp',
|
|
12
|
+
'image/heic'
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
MIME_TO_EXT = {
|
|
16
|
+
'image/x-icon': 'ico',
|
|
17
|
+
'image/bmp': 'bmp',
|
|
18
|
+
'image/jpeg': 'jpg',
|
|
19
|
+
'image/png': 'png',
|
|
20
|
+
'image/tiff': 'tiff',
|
|
21
|
+
'image/webp': 'webp',
|
|
22
|
+
'image/heic': 'heic'
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
HEADERS = {
|
|
26
|
+
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
|
|
27
|
+
'Accept-Encoding': 'gzip, deflate, br',
|
|
28
|
+
'Accept-Language': 'en-US,en;q=0.9',
|
|
29
|
+
'Cache-Control': 'max-age=0',
|
|
30
|
+
'Origin': 'https://lens.google.com',
|
|
31
|
+
'Referer': 'https://lens.google.com/',
|
|
32
|
+
'Sec-Ch-Ua': '"Not A(Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"',
|
|
33
|
+
'Sec-Ch-Ua-Arch': '"x86"',
|
|
34
|
+
'Sec-Ch-Ua-Bitness': '"64"',
|
|
35
|
+
'Sec-Ch-Ua-Full-Version': '"91.0.4472.124"',
|
|
36
|
+
'Sec-Ch-Ua-Full-Version-List': '"Not A(Brand";v="99.0.0.0", "Google Chrome";v="91", "Chromium";v="91"',
|
|
37
|
+
'Sec-Ch-Ua-Mobile': '?0',
|
|
38
|
+
'Sec-Ch-Ua-Model': '""',
|
|
39
|
+
'Sec-Ch-Ua-Platform': '"Windows"',
|
|
40
|
+
'Sec-Ch-Ua-Platform-Version': '"15.0.0"',
|
|
41
|
+
'Sec-Ch-Ua-Wow64': '?0',
|
|
42
|
+
'Sec-Fetch-Dest': 'document',
|
|
43
|
+
'Sec-Fetch-Mode': 'navigate',
|
|
44
|
+
'Sec-Fetch-Site': 'same-origin',
|
|
45
|
+
'Sec-Fetch-User': '?1',
|
|
46
|
+
'Upgrade-Insecure-Requests': '1',
|
|
47
|
+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
|
|
48
|
+
'X-Client-Data': 'CIW2yQEIorbJAQipncoBCIH+ygEIlaHLAQj1mM0BCIWgzQEI3ezNAQji+s0BCOmFzgEIponOAQj1ic4BCIeLzgEY1d3NARjS/s0BGNiGzgE='
|
|
49
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# image_processing.py
|
|
2
|
+
|
|
3
|
+
import io
|
|
4
|
+
from PIL import Image
|
|
5
|
+
from .utils import is_supported_mime
|
|
6
|
+
from .constants import MIME_TO_EXT
|
|
7
|
+
|
|
8
|
+
def resize_image(image_path, max_size=(1000, 1000)):
|
|
9
|
+
"""Изменяет размер изображения и конвертирует его в формат без альфа-канала."""
|
|
10
|
+
with Image.open(image_path) as img:
|
|
11
|
+
img.thumbnail(max_size)
|
|
12
|
+
if img.mode == 'RGBA':
|
|
13
|
+
img = img.convert('RGB')
|
|
14
|
+
buffer = io.BytesIO()
|
|
15
|
+
img.save(buffer, format="JPEG")
|
|
16
|
+
return buffer.getvalue(), img.size
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# lens_api.py
|
|
2
|
+
|
|
3
|
+
from .request_handler import Lens
|
|
4
|
+
from .text_processing import simplify_output, extract_full_text, stitch_text_smart, stitch_text_sequential
|
|
5
|
+
|
|
6
|
+
class LensAPI:
|
|
7
|
+
def __init__(self, config=None, sleep_time=1000):
|
|
8
|
+
self.lens = Lens(config=config, sleep_time=sleep_time)
|
|
9
|
+
|
|
10
|
+
def get_all_data(self, file_path):
|
|
11
|
+
"""Возвращает все данные для изображения"""
|
|
12
|
+
result = self.lens.scan_by_file(file_path)
|
|
13
|
+
return simplify_output(result)
|
|
14
|
+
|
|
15
|
+
def get_full_text(self, file_path):
|
|
16
|
+
"""Возвращает полный текст"""
|
|
17
|
+
result = self.lens.scan_by_file(file_path)
|
|
18
|
+
return extract_full_text(result['data'])
|
|
19
|
+
|
|
20
|
+
def get_text_with_coordinates(self, file_path):
|
|
21
|
+
"""Возвращает текст с координатами в формате JSON"""
|
|
22
|
+
result = self.lens.scan_by_file(file_path)
|
|
23
|
+
simplified_result = simplify_output(result)
|
|
24
|
+
return simplified_result['text_with_coordinates']
|
|
25
|
+
|
|
26
|
+
def get_stitched_text_smart(self, file_path):
|
|
27
|
+
"""Возвращает сшитый текст (умный метод)"""
|
|
28
|
+
result = self.lens.scan_by_file(file_path)
|
|
29
|
+
simplified_result = simplify_output(result)
|
|
30
|
+
return simplified_result['stitched_text_smart']
|
|
31
|
+
|
|
32
|
+
def get_stitched_text_sequential(self, file_path):
|
|
33
|
+
"""Возвращает сшитый текст (последовательный метод)"""
|
|
34
|
+
result = self.lens.scan_by_file(file_path)
|
|
35
|
+
simplified_result = simplify_output(result)
|
|
36
|
+
return simplified_result['stitched_text_sequential']
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import json
|
|
3
|
+
import argparse
|
|
4
|
+
from .lens_api import LensAPI
|
|
5
|
+
from rich.console import Console
|
|
6
|
+
from rich.table import Table
|
|
7
|
+
|
|
8
|
+
console = Console()
|
|
9
|
+
|
|
10
|
+
def print_help():
|
|
11
|
+
console.print("Usage: [b]lens_scan [options] <image_file> <data_type>[/b]")
|
|
12
|
+
console.print("\nOptions:")
|
|
13
|
+
console.print("[b]-h, --help[/b] Show this help message and exit")
|
|
14
|
+
console.print("[b]<data_type>[/b] options:")
|
|
15
|
+
console.print("[b]all[/b] Get all data (full text, coordinates, and stitched text)")
|
|
16
|
+
console.print("[b]full_text_default[/b] Get only the default full text")
|
|
17
|
+
console.print("[b]full_text_old_method[/b] Get stitched text using the old method")
|
|
18
|
+
console.print("[b]full_text_new_method[/b] Get stitched text using the new method")
|
|
19
|
+
console.print("[b]coordinates[/b] Get text with coordinates")
|
|
20
|
+
|
|
21
|
+
def main():
|
|
22
|
+
parser = argparse.ArgumentParser(description="Process images with Google Lens API and extract text data.", add_help=False)
|
|
23
|
+
parser.add_argument('image_file', nargs='?', help="Path to the image file")
|
|
24
|
+
parser.add_argument('data_type', nargs='?', choices=['all', 'full_text_default', 'full_text_old_method', 'full_text_new_method', 'coordinates'], help="Type of data to extract")
|
|
25
|
+
parser.add_argument('-h', '--help', action='store_true', help="Show this help message and exit")
|
|
26
|
+
|
|
27
|
+
args = parser.parse_args()
|
|
28
|
+
|
|
29
|
+
if args.help or not args.image_file or not args.data_type:
|
|
30
|
+
print_help()
|
|
31
|
+
sys.exit(1)
|
|
32
|
+
|
|
33
|
+
image_file = args.image_file
|
|
34
|
+
data_type = args.data_type
|
|
35
|
+
|
|
36
|
+
try:
|
|
37
|
+
api = LensAPI()
|
|
38
|
+
|
|
39
|
+
if data_type == "all":
|
|
40
|
+
result = api.get_all_data(image_file)
|
|
41
|
+
elif data_type == "full_text_default":
|
|
42
|
+
result = api.get_full_text(image_file)
|
|
43
|
+
elif data_type == "full_text_old_method":
|
|
44
|
+
result = api.get_stitched_text_sequential(image_file)
|
|
45
|
+
elif data_type == "full_text_new_method":
|
|
46
|
+
result = api.get_stitched_text_smart(image_file)
|
|
47
|
+
elif data_type == "coordinates":
|
|
48
|
+
result = api.get_text_with_coordinates(image_file)
|
|
49
|
+
else:
|
|
50
|
+
console.print("Invalid data_type option", style="bold red")
|
|
51
|
+
sys.exit(1)
|
|
52
|
+
|
|
53
|
+
console.print(json.dumps(result, indent=2), style="bold white")
|
|
54
|
+
|
|
55
|
+
except Exception as e:
|
|
56
|
+
console.print(f"Error: {e}", style="bold red")
|
|
57
|
+
|
|
58
|
+
if __name__ == '__main__':
|
|
59
|
+
main()
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# request_handler.py
|
|
2
|
+
|
|
3
|
+
import requests
|
|
4
|
+
import io
|
|
5
|
+
import os
|
|
6
|
+
import time
|
|
7
|
+
import http.cookiejar as cookielib
|
|
8
|
+
import lxml.html
|
|
9
|
+
import json5
|
|
10
|
+
import filetype
|
|
11
|
+
from PIL import Image
|
|
12
|
+
from .constants import LENS_ENDPOINT, HEADERS, MIME_TO_EXT, SUPPORTED_MIMES
|
|
13
|
+
from .utils import sleep, is_supported_mime
|
|
14
|
+
from .image_processing import resize_image
|
|
15
|
+
|
|
16
|
+
class LensError(Exception):
|
|
17
|
+
"""Класс для обработки ошибок."""
|
|
18
|
+
def __init__(self, message, code=None, headers=None, body=None):
|
|
19
|
+
super().__init__(message)
|
|
20
|
+
self.code = code
|
|
21
|
+
self.headers = headers
|
|
22
|
+
self.body = body
|
|
23
|
+
|
|
24
|
+
class LensCore:
|
|
25
|
+
"""Базовый класс для работы с Google Lens API."""
|
|
26
|
+
def __init__(self, config=None, sleep_time=1000):
|
|
27
|
+
self.config = config if config else {}
|
|
28
|
+
self.cookies = {}
|
|
29
|
+
self.sleep_time = sleep_time
|
|
30
|
+
self.parse_cookies()
|
|
31
|
+
|
|
32
|
+
def parse_cookies(self):
|
|
33
|
+
"""Инициализирует куки."""
|
|
34
|
+
self.cookies = {
|
|
35
|
+
'NID': {
|
|
36
|
+
'name': 'NID',
|
|
37
|
+
'value': '511=b-iPvznEQOKO1rDvyj7vkLrfe9i-PQiN0z_nhNv7lg-3_0YpQf2ZSKikTrlpu4W3mko4n2RAfYMho9NJqDEsmO-4BZG_iOqmufFZIzW4jiGJMmnaE1S3crNWwUL1HNnDqVUZZjRYkK_S-wsDWCuVul3Q_sCjucSvJ-CTN63GSjY',
|
|
38
|
+
'expires': 1707050670000
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
def generate_cookie_header(self, headers):
|
|
43
|
+
"""Добавляет куки в заголовки запроса."""
|
|
44
|
+
if self.cookies:
|
|
45
|
+
self.cookies = {k: v for k, v in self.cookies.items() if v['expires'] > time.time() * 1000}
|
|
46
|
+
headers['Cookie'] = '; '.join([f"{cookie['name']}={cookie['value']}" for cookie in self.cookies.values()])
|
|
47
|
+
|
|
48
|
+
def scan_by_data(self, data, mime, dimensions):
|
|
49
|
+
"""Отправляет изображение на анализ в Google Lens API."""
|
|
50
|
+
headers = HEADERS.copy()
|
|
51
|
+
self.generate_cookie_header(headers)
|
|
52
|
+
|
|
53
|
+
session = requests.Session()
|
|
54
|
+
session.cookies = cookielib.CookieJar()
|
|
55
|
+
print(f"Sending data to {LENS_ENDPOINT}")
|
|
56
|
+
|
|
57
|
+
file_name = f"image.{MIME_TO_EXT[mime]}"
|
|
58
|
+
files = {
|
|
59
|
+
'encoded_image': (file_name, data, mime),
|
|
60
|
+
'original_width': (None, str(dimensions[0])),
|
|
61
|
+
'original_height': (None, str(dimensions[1])),
|
|
62
|
+
'processed_image_dimensions': (None, f"{dimensions[0]},{dimensions[1]}")
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
# Используем кастомное время задержки
|
|
66
|
+
sleep(self.sleep_time)
|
|
67
|
+
|
|
68
|
+
response = session.post(LENS_ENDPOINT, headers=headers, files=files)
|
|
69
|
+
print(f"Response status code: {response.status_code}")
|
|
70
|
+
|
|
71
|
+
if response.status_code != 200:
|
|
72
|
+
print(f"Response headers: {response.headers}")
|
|
73
|
+
print(f"Response body: {response.text}")
|
|
74
|
+
raise LensError("Failed to upload image", response.status_code, response.headers, response.text)
|
|
75
|
+
|
|
76
|
+
buffer_text = io.StringIO(response.text)
|
|
77
|
+
tree = lxml.html.parse(buffer_text)
|
|
78
|
+
|
|
79
|
+
r = tree.xpath("//script[@class='ds:1']")
|
|
80
|
+
return json5.loads(r[0].text[len("AF_initDataCallback("):-2])
|
|
81
|
+
|
|
82
|
+
class Lens(LensCore):
|
|
83
|
+
"""Класс для работы с Google Lens API, предоставляющий удобные методы."""
|
|
84
|
+
def __init__(self, config=None, sleep_time=1000):
|
|
85
|
+
super().__init__(config, sleep_time)
|
|
86
|
+
|
|
87
|
+
def scan_by_file(self, file_path):
|
|
88
|
+
"""Сканирует изображение по пути к файлу и возвращает результаты."""
|
|
89
|
+
if not os.path.isfile(file_path):
|
|
90
|
+
raise FileNotFoundError(f"File not found: {file_path}")
|
|
91
|
+
if not is_supported_mime(file_path):
|
|
92
|
+
raise ValueError("Unsupported file type")
|
|
93
|
+
img_data, dimensions = resize_image(file_path)
|
|
94
|
+
return self.scan_by_data(img_data, 'image/jpeg', dimensions)
|
|
95
|
+
|
|
96
|
+
def scan_by_buffer(self, buffer):
|
|
97
|
+
"""Сканирует изображение из буфера и возвращает результаты."""
|
|
98
|
+
kind = filetype.guess(buffer)
|
|
99
|
+
if not kind or kind.mime not in SUPPORTED_MIMES:
|
|
100
|
+
raise ValueError("Unsupported file type")
|
|
101
|
+
img = Image.open(io.BytesIO(buffer))
|
|
102
|
+
img.thumbnail((1000, 1000))
|
|
103
|
+
if img.mode == 'RGBA':
|
|
104
|
+
img = img.convert('RGB')
|
|
105
|
+
img_buffer = io.BytesIO()
|
|
106
|
+
img.save(img_buffer, format="JPEG")
|
|
107
|
+
img_data = img_buffer.getvalue()
|
|
108
|
+
return self.scan_by_data(img_data, 'image/jpeg', img.size)
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# text_processing.py
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
|
|
5
|
+
def stitch_text_from_coordinates(text_with_coords):
|
|
6
|
+
"""Сшивает текст из координат по строкам и позициям."""
|
|
7
|
+
sorted_elements = sorted(text_with_coords, key=lambda x: (round(x['coordinates'][1], 2), x['coordinates'][0]))
|
|
8
|
+
|
|
9
|
+
stitched_text = ""
|
|
10
|
+
current_y = None
|
|
11
|
+
current_line = []
|
|
12
|
+
|
|
13
|
+
for element in sorted_elements:
|
|
14
|
+
if current_y is None or abs(element['coordinates'][1] - current_y) > 0.05:
|
|
15
|
+
if current_line:
|
|
16
|
+
stitched_text += " ".join(current_line) + "\n"
|
|
17
|
+
current_line = []
|
|
18
|
+
current_y = element['coordinates'][1]
|
|
19
|
+
current_line.append(element['text'])
|
|
20
|
+
|
|
21
|
+
if current_line:
|
|
22
|
+
stitched_text += " ".join(current_line)
|
|
23
|
+
|
|
24
|
+
stitched_text = re.sub(r'\s+([,?.!])', r'\1', stitched_text)
|
|
25
|
+
|
|
26
|
+
return stitched_text.strip()
|
|
27
|
+
|
|
28
|
+
def stitch_text_smart(text_with_coords):
|
|
29
|
+
"""Сшивает текст из координат умным методом."""
|
|
30
|
+
transformed_coords = [{'text': item['text'], 'coordinates': [item['coordinates'][1], item['coordinates'][0]]} for item in text_with_coords]
|
|
31
|
+
sorted_elements = sorted(transformed_coords, key=lambda x: (round(x['coordinates'][1], 2), x['coordinates'][0]))
|
|
32
|
+
|
|
33
|
+
stitched_text = []
|
|
34
|
+
current_y = None
|
|
35
|
+
current_line = []
|
|
36
|
+
word_threshold = 0.02
|
|
37
|
+
|
|
38
|
+
for element in sorted_elements:
|
|
39
|
+
if current_y is None or abs(element['coordinates'][1] - current_y) > 0.05:
|
|
40
|
+
if current_line:
|
|
41
|
+
stitched_text.append(" ".join(current_line))
|
|
42
|
+
current_line = []
|
|
43
|
+
current_y = element['coordinates'][1]
|
|
44
|
+
|
|
45
|
+
if element['text'] in [',', '.', '!', '?', ';', ':'] and current_line:
|
|
46
|
+
current_line[-1] += element['text']
|
|
47
|
+
else:
|
|
48
|
+
current_line.append(element['text'])
|
|
49
|
+
|
|
50
|
+
if current_line:
|
|
51
|
+
stitched_text.append(" ".join(current_line))
|
|
52
|
+
|
|
53
|
+
return "\n".join(stitched_text).strip()
|
|
54
|
+
|
|
55
|
+
def stitch_text_sequential(text_with_coords):
|
|
56
|
+
"""Сшивает текст в последовательности, как он был распознан."""
|
|
57
|
+
stitched_text = " ".join([element['text'] for element in text_with_coords])
|
|
58
|
+
stitched_text = re.sub(r'\s+([,?.!])', r'\1', stitched_text)
|
|
59
|
+
|
|
60
|
+
return stitched_text.strip()
|
|
61
|
+
|
|
62
|
+
def extract_text_and_coordinates(data):
|
|
63
|
+
"""Извлекает текст и координаты из структуры данных."""
|
|
64
|
+
text_with_coords = []
|
|
65
|
+
if isinstance(data, list):
|
|
66
|
+
for item in data:
|
|
67
|
+
if isinstance(item, list):
|
|
68
|
+
for sub_item in item:
|
|
69
|
+
if isinstance(sub_item, list) and len(sub_item) > 1 and isinstance(sub_item[0], str):
|
|
70
|
+
word = sub_item[0]
|
|
71
|
+
coords = sub_item[1]
|
|
72
|
+
if isinstance(coords, list) and all(isinstance(coord, (int, float)) for coord in coords):
|
|
73
|
+
text_with_coords.append({"text": word, "coordinates": coords})
|
|
74
|
+
else:
|
|
75
|
+
text_with_coords.extend(extract_text_and_coordinates(sub_item))
|
|
76
|
+
else:
|
|
77
|
+
text_with_coords.extend(extract_text_and_coordinates(item))
|
|
78
|
+
elif isinstance(data, dict):
|
|
79
|
+
for value in data.values():
|
|
80
|
+
text_with_coords.extend(extract_text_and_coordinates(value))
|
|
81
|
+
return text_with_coords
|
|
82
|
+
|
|
83
|
+
def extract_full_text(data):
|
|
84
|
+
"""Извлекает полный текст из структуры данных."""
|
|
85
|
+
try:
|
|
86
|
+
text_data = data[3][4][0][0]
|
|
87
|
+
if isinstance(text_data, list):
|
|
88
|
+
return "\n".join(text_data)
|
|
89
|
+
return text_data
|
|
90
|
+
except (IndexError, TypeError):
|
|
91
|
+
return "Full text not found in expected structure"
|
|
92
|
+
|
|
93
|
+
def simplify_output(result):
|
|
94
|
+
"""Упрощает структуру данных, извлекая ключевые элементы."""
|
|
95
|
+
simplified = {}
|
|
96
|
+
|
|
97
|
+
try:
|
|
98
|
+
if 'data' in result and isinstance(result['data'], list) and len(result['data']) > 3:
|
|
99
|
+
if isinstance(result['data'][3], list) and len(result['data'][3]) > 3:
|
|
100
|
+
simplified['language'] = result['data'][3][3]
|
|
101
|
+
else:
|
|
102
|
+
simplified['language'] = "Language not found in expected structure"
|
|
103
|
+
|
|
104
|
+
simplified['full_text'] = extract_full_text(result['data'])
|
|
105
|
+
|
|
106
|
+
if 'data' in result and isinstance(result['data'], list):
|
|
107
|
+
text_with_coords = extract_text_and_coordinates(result['data'])
|
|
108
|
+
simplified['text_with_coordinates'] = text_with_coords
|
|
109
|
+
|
|
110
|
+
simplified['stitched_text_smart'] = stitch_text_smart(text_with_coords)
|
|
111
|
+
simplified['stitched_text_sequential'] = stitch_text_sequential(text_with_coords)
|
|
112
|
+
except Exception as e:
|
|
113
|
+
print(f"Error in simplify_output: {e}")
|
|
114
|
+
simplified['error'] = str(e)
|
|
115
|
+
|
|
116
|
+
return simplified
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# utils.py
|
|
2
|
+
|
|
3
|
+
import filetype
|
|
4
|
+
import time
|
|
5
|
+
|
|
6
|
+
from .constants import SUPPORTED_MIMES
|
|
7
|
+
|
|
8
|
+
def is_supported_mime(file_path):
|
|
9
|
+
"""Проверяет, поддерживается ли MIME-тип файла."""
|
|
10
|
+
kind = filetype.guess(file_path)
|
|
11
|
+
return kind and kind.mime in SUPPORTED_MIMES
|
|
12
|
+
|
|
13
|
+
def sleep(ms):
|
|
14
|
+
"""Функция ожидания."""
|
|
15
|
+
time.sleep(ms / 1000)
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: chrome_lens_py
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Library to use Google Lens OCR via API used in Chromium.
|
|
5
|
+
Home-page: https://github.com/bropines/chrome-lens-py
|
|
6
|
+
Author: Bropines
|
|
7
|
+
Author-email: bropines@gmail.com
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Requires-Dist: requests
|
|
14
|
+
Requires-Dist: Pillow
|
|
15
|
+
Requires-Dist: filetype
|
|
16
|
+
Requires-Dist: lxml
|
|
17
|
+
Requires-Dist: json5
|
|
18
|
+
Requires-Dist: rich
|
|
19
|
+
|
|
20
|
+
# Chrome Lens API for Python
|
|
21
|
+
|
|
22
|
+
[English](/README.md) | [Русский](/README_RU.md)
|
|
23
|
+
|
|
24
|
+
This project provides a Python library and CLI tool for interacting with Google Lens's OCR functionality via the API used in Chromium. This allows you to process images and extract text data, including full text, coordinates, and stitched text using various methods.
|
|
25
|
+
|
|
26
|
+
## Features
|
|
27
|
+
|
|
28
|
+
- **Full Text Extraction**: Extract the complete text from an image.
|
|
29
|
+
- **Coordinates Extraction**: Extract text along with its coordinates.
|
|
30
|
+
- **Stitched Text**: Reconstruct text from blocks using various methods:
|
|
31
|
+
- **Default Full Text**: Basic method for stitching text blocks.
|
|
32
|
+
- **Old Method**: Sequential text stitching.
|
|
33
|
+
- **New Method**: Enhanced text stitching.
|
|
34
|
+
|
|
35
|
+
PS. Lens has a problem with the way it displays full text, which is why methods have been added that stitch text from coordinates.
|
|
36
|
+
|
|
37
|
+
## Installation
|
|
38
|
+
|
|
39
|
+
You can install the package using `pip`:
|
|
40
|
+
|
|
41
|
+
### From PyPI (SOON)
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pip install chrome-lens-py
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### From GIT
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pip install git+https://github.com/bropines/chrome-lens-py.git
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### From source
|
|
54
|
+
|
|
55
|
+
Clone the repository and install the package:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
git clone https://github.com/bropines/chrome-lens-api-py.git
|
|
59
|
+
cd chrome-lens-api-py
|
|
60
|
+
pip install -r requirements.txt
|
|
61
|
+
pip install .
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Usage
|
|
65
|
+
|
|
66
|
+
You can use the `lens_scan` command from the CLI to process images and extract text data, or you can use the Python API to integrate this functionality into your own projects.
|
|
67
|
+
|
|
68
|
+
### CLI Usage
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
lens_scan <image_file> <data_type>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
#### Data Types
|
|
75
|
+
|
|
76
|
+
- **all**: Get all data (full text, coordinates, and stitched text using both methods).
|
|
77
|
+
- **full_text_default**: Get only the default full text.
|
|
78
|
+
- **full_text_old_method**: Get stitched text using the old sequential method.
|
|
79
|
+
- **full_text_new_method**: Get stitched text using the new enhanced method.
|
|
80
|
+
- **coordinates**: Get text along with coordinates.
|
|
81
|
+
|
|
82
|
+
#### Example
|
|
83
|
+
|
|
84
|
+
To extract text using the new method for stitching:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
lens_scan path/to/image.jpg full_text_new_method
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
To get all available data:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
lens_scan path/to/image.jpg all
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
#### CLI Help
|
|
97
|
+
|
|
98
|
+
You can use the `-h` or `--help` option to display usage information:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
lens_scan -h
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Programmatic API Usage
|
|
105
|
+
|
|
106
|
+
In addition to the CLI tool, this project provides a Python API that can be used in your scripts.
|
|
107
|
+
|
|
108
|
+
#### Basic Programmatic Usage
|
|
109
|
+
|
|
110
|
+
First, import the `LensAPI` class:
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
from chrome_lens_py import LensAPI
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
#### Example Programmatic Usage
|
|
117
|
+
|
|
118
|
+
1. **Instantiate the API**:
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
api = LensAPI()
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
2. **Process an image**:
|
|
125
|
+
|
|
126
|
+
- **Get all data**:
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
result = api.get_all_data('path/to/image.jpg')
|
|
130
|
+
print(result)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
- **Get the default full text**:
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
result = api.get_full_text('path/to/image.jpg')
|
|
137
|
+
print(result)
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
- **Get stitched text using the old method**:
|
|
141
|
+
|
|
142
|
+
```python
|
|
143
|
+
result = api.get_stitched_text_sequential('path/to/image.jpg')
|
|
144
|
+
print(result)
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
- **Get stitched text using the new method**:
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
result = api.get_stitched_text_smart('path/to/image.jpg')
|
|
151
|
+
print(result)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
- **Get text with coordinates**:
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
result = api.get_text_with_coordinates('path/to/image.jpg')
|
|
158
|
+
print(result)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
#### Programmatic API Methods
|
|
162
|
+
|
|
163
|
+
- **`get_all_data(image_path)`**: Returns all available data for the given image.
|
|
164
|
+
- **`get_full_text(image_path)`**: Returns only the full text from the image.
|
|
165
|
+
- **`get_text_with_coordinates(image_path)`**: Returns text along with its coordinates in JSON format.
|
|
166
|
+
- **`get_stitched_text_smart(image_path)`**: Returns stitched text using the enhanced method.
|
|
167
|
+
- **`get_stitched_text_sequential(image_path)`**: Returns stitched text using the basic sequential method.
|
|
168
|
+
|
|
169
|
+
## Project Structure
|
|
170
|
+
|
|
171
|
+
```
|
|
172
|
+
/chrome-lens-api-py
|
|
173
|
+
│
|
|
174
|
+
├── /src
|
|
175
|
+
│ ├── /chrome_lens_py
|
|
176
|
+
│ │ ├── __init__.py # Package initialization
|
|
177
|
+
│ │ ├── constants.py # Constants used in the project
|
|
178
|
+
│ │ ├── utils.py # Utility functions
|
|
179
|
+
│ │ ├── image_processing.py # Image processing module
|
|
180
|
+
│ │ ├── request_handler.py # API request handling module
|
|
181
|
+
│ │ ├── text_processing.py # Text processing module
|
|
182
|
+
│ │ ├── lens_api.py # API interface for use in other scripts
|
|
183
|
+
│ │ └── main.py # CLI tool entry point
|
|
184
|
+
│
|
|
185
|
+
├── setup.py # Installation setup
|
|
186
|
+
├── README.md # Project description and usage guide
|
|
187
|
+
└── requirements.txt # Project dependencies
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Acknowledgments
|
|
191
|
+
|
|
192
|
+
Special thanks to [dimdenGD](https://github.com/dimdenGD) for the method of text extraction used in this project. You can check out their work on the [chrome-lens-ocr](https://github.com/dimdenGD/chrome-lens-ocr) repository. This project is inspired by their approach to leveraging Google Lens OCR functionality.
|
|
193
|
+
|
|
194
|
+
## License
|
|
195
|
+
|
|
196
|
+
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for more details.
|
|
197
|
+
|
|
198
|
+
## Disclaimer
|
|
199
|
+
|
|
200
|
+
This project is intended for educational purposes only. The use of Google Lens OCR functionality must comply with Google's Terms of Service. The author of this project is not responsible for any misuse of this software or for any consequences arising from its use. Users are solely responsible for ensuring that their use of this software complies with all applicable laws and regulations.
|
|
201
|
+
|
|
202
|
+
## Author
|
|
203
|
+
|
|
204
|
+
### Bropines - [Mail](mailto:bropines@gmail.com) / [Telegram](https://t.me/bropines)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
setup.py
|
|
4
|
+
src/chrome_lens_py/__init__.py
|
|
5
|
+
src/chrome_lens_py/constants.py
|
|
6
|
+
src/chrome_lens_py/image_processing.py
|
|
7
|
+
src/chrome_lens_py/lens_api.py
|
|
8
|
+
src/chrome_lens_py/main.py
|
|
9
|
+
src/chrome_lens_py/request_handler.py
|
|
10
|
+
src/chrome_lens_py/text_processing.py
|
|
11
|
+
src/chrome_lens_py/utils.py
|
|
12
|
+
src/chrome_lens_py.egg-info/PKG-INFO
|
|
13
|
+
src/chrome_lens_py.egg-info/SOURCES.txt
|
|
14
|
+
src/chrome_lens_py.egg-info/dependency_links.txt
|
|
15
|
+
src/chrome_lens_py.egg-info/entry_points.txt
|
|
16
|
+
src/chrome_lens_py.egg-info/requires.txt
|
|
17
|
+
src/chrome_lens_py.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
chrome_lens_py
|