├── .gitignore ├── Readme.md ├── db.sqlite3 ├── manage.py ├── ocr ├── __init__.py ├── admin.py ├── apps.py ├── migrations │ └── __init__.py ├── models.py ├── tests.py ├── urls.py └── views.py ├── requirements.txt ├── sample image ├── 2022-02-16_16-25.png ├── 2022-02-16_16-26.png ├── 2022-02-16_16-30.png └── 2022-02-16_16-31.png ├── static ├── assets │ ├── 1.svg │ ├── 2.svg │ ├── 3.svg │ ├── 4.svg │ └── icons │ │ ├── TEXT.svg │ │ ├── sachit.jpg │ │ └── text-check.svg ├── build.css ├── copy.js ├── error.js └── style.css ├── templates └── home.html └── website ├── __init__.py ├── asgi.py ├── settings.py ├── urls.py └── wsgi.py /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | env 3 | __pycache__ 4 | 5 | # tailwind css 6 | templates/package.json 7 | templates/tailwind.config.js 8 | templates/package-lock.json 9 | templates/node_modules 10 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | 2 | # Text Extractor/ OCR in Django 3 | 4 | 5 | A django webapp for scanning texts from images, simply you have to upload image and it will provide you with texts found 6 | 7 | 8 | 9 | ## Home page 10 | 11 | ![App Screenshot](https://cdn.discordapp.com/attachments/884460118715019274/945247468747124736/unknown.png) 12 | 13 | ## Result page 14 | 15 | ![App Screenshot](https://cdn.discordapp.com/attachments/884460118715019274/945247765259247616/unknown.png) 16 | 17 | ## Nepali Language 18 | ![App Screenshot](https://media.discordapp.net/attachments/884460118715019274/945248254428323850/unknown.png) 19 | 20 | ## Hindi Language 21 | ![App Screenshot](https://media.discordapp.net/attachments/884460118715019274/945248807912882206/unknown.png) 22 | 23 | Currently i have included commonly used language list only, feature request for another langauges are welcomed ;) 24 | - English 25 | - Nepali 26 | - Hindi 27 | 28 | ## Installation 29 | 30 | ```bash 31 | git clone https://github.com/ASACHIT/OCR-django-app.git 32 | cd OCR-django-app 33 | pip install -r requirements 34 | python manage.py runserver 35 | # open localhost:8000 url in browser 36 | ``` 37 | Note: You have to install [tesseract module](https://github.com/UB-Mannheim/tesseract/wiki) too 38 | ## Frameworks/lib used 39 | - Tailwindcss 40 | - django 41 | - pytesseract 42 | 43 | ## Things i learnt after creating this project 44 | 45 | - Taking image input from user 46 | - Processing input image without saving it anywhere and uploading it directly to user 47 | - scanning text from image (backend) 48 | - and other many more 49 | 50 | 51 | ## Features 52 | - Quickly Upload image and get scanned text 53 | - Image is Not saved, it is directly processed in memory and directly sent to you 54 | - Friendly and Clean UI 55 | 56 | ## Contributing 57 | 58 | Contributions are always welcome! 59 | 60 | 61 | -------------------------------------------------------------------------------- /db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ASACHIT/OCR-django-app/867a588ecd2c3b3bb5e55bf878779a86a6e9b16b/db.sqlite3 -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "website.settings") 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == "__main__": 22 | main() 23 | -------------------------------------------------------------------------------- /ocr/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ASACHIT/OCR-django-app/867a588ecd2c3b3bb5e55bf878779a86a6e9b16b/ocr/__init__.py -------------------------------------------------------------------------------- /ocr/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /ocr/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class OcrConfig(AppConfig): 5 | default_auto_field = "django.db.models.BigAutoField" 6 | name = "ocr" 7 | -------------------------------------------------------------------------------- /ocr/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ASACHIT/OCR-django-app/867a588ecd2c3b3bb5e55bf878779a86a6e9b16b/ocr/migrations/__init__.py -------------------------------------------------------------------------------- /ocr/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /ocr/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /ocr/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import include, path 3 | from .views import homepage 4 | 5 | urlpatterns = [ 6 | path("", homepage, name="homepage"), 7 | ] 8 | -------------------------------------------------------------------------------- /ocr/views.py: -------------------------------------------------------------------------------- 1 | import base64 2 | 3 | import numpy as np 4 | import pytesseract 5 | from django.contrib import messages 6 | from django.shortcuts import render 7 | from PIL import Image 8 | 9 | # you have to install tesseract module too from here - https://github.com/UB-Mannheim/tesseract/wiki 10 | pytesseract.pytesseract.tesseract_cmd = ( 11 | r"C:\Program Files\Tesseract-OCR\tesseract.exe" # Path to tesseract.exe 12 | ) 13 | 14 | 15 | def homepage(request): 16 | if request.method == "POST": 17 | try: 18 | image = request.FILES["imagefile"] 19 | # encode image to base64 string 20 | image_base64 = base64.b64encode(image.read()).decode("utf-8") 21 | except: 22 | messages.add_message( 23 | request, messages.ERROR, "No image selected or uploaded" 24 | ) 25 | return render(request, "home.html") 26 | lang = request.POST["language"] 27 | img = np.array(Image.open(image)) 28 | text = pytesseract.image_to_string(img, lang=lang) 29 | # return text to html 30 | return render(request, "home.html", {"ocr": text, "image": image_base64}) 31 | 32 | return render(request, "home.html") 33 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | asgiref==3.5.0 2 | Django==4.0.2 3 | numpy==1.22.2 4 | Pillow==9.0.1 5 | pytesseract==0.3.8 6 | sqlparse==0.4.2 7 | tzdata==2021.5 8 | -------------------------------------------------------------------------------- /sample image/2022-02-16_16-25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ASACHIT/OCR-django-app/867a588ecd2c3b3bb5e55bf878779a86a6e9b16b/sample image/2022-02-16_16-25.png -------------------------------------------------------------------------------- /sample image/2022-02-16_16-26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ASACHIT/OCR-django-app/867a588ecd2c3b3bb5e55bf878779a86a6e9b16b/sample image/2022-02-16_16-26.png -------------------------------------------------------------------------------- /sample image/2022-02-16_16-30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ASACHIT/OCR-django-app/867a588ecd2c3b3bb5e55bf878779a86a6e9b16b/sample image/2022-02-16_16-30.png -------------------------------------------------------------------------------- /sample image/2022-02-16_16-31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ASACHIT/OCR-django-app/867a588ecd2c3b3bb5e55bf878779a86a6e9b16b/sample image/2022-02-16_16-31.png -------------------------------------------------------------------------------- /static/assets/1.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/assets/2.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/assets/3.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/assets/4.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/assets/icons/TEXT.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/assets/icons/sachit.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ASACHIT/OCR-django-app/867a588ecd2c3b3bb5e55bf878779a86a6e9b16b/static/assets/icons/sachit.jpg -------------------------------------------------------------------------------- /static/assets/icons/text-check.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/build.css: -------------------------------------------------------------------------------- 1 | /*! tailwindcss v3.0.22 | MIT License | https://tailwindcss.com*/ 2 | *, 3 | :after, 4 | :before { 5 | box-sizing: border-box; 6 | border: 0 solid #e5e7eb 7 | } 8 | 9 | :after, 10 | :before { 11 | --tw-content: "" 12 | } 13 | 14 | html { 15 | line-height: 1.5; 16 | -webkit-text-size-adjust: 100%; 17 | -moz-tab-size: 4; 18 | -o-tab-size: 4; 19 | tab-size: 4; 20 | font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, Noto Sans, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji 21 | } 22 | 23 | body { 24 | margin: 0; 25 | line-height: inherit 26 | } 27 | 28 | hr { 29 | height: 0; 30 | color: inherit; 31 | border-top-width: 1px 32 | } 33 | 34 | abbr:where([title]) { 35 | -webkit-text-decoration: underline dotted; 36 | text-decoration: underline dotted 37 | } 38 | 39 | h1, 40 | h2, 41 | h3, 42 | h4, 43 | h5, 44 | h6 { 45 | font-size: inherit; 46 | font-weight: inherit 47 | } 48 | 49 | a { 50 | color: inherit; 51 | text-decoration: inherit 52 | } 53 | 54 | b, 55 | strong { 56 | font-weight: bolder 57 | } 58 | 59 | code, 60 | kbd, 61 | pre, 62 | samp { 63 | font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace; 64 | font-size: 1em 65 | } 66 | 67 | small { 68 | font-size: 80% 69 | } 70 | 71 | sub, 72 | sup { 73 | font-size: 75%; 74 | line-height: 0; 75 | position: relative; 76 | vertical-align: initial 77 | } 78 | 79 | sub { 80 | bottom: -.25em 81 | } 82 | 83 | sup { 84 | top: -.5em 85 | } 86 | 87 | table { 88 | text-indent: 0; 89 | border-color: inherit; 90 | border-collapse: collapse 91 | } 92 | 93 | button, 94 | input, 95 | optgroup, 96 | select, 97 | textarea { 98 | font-family: inherit; 99 | font-size: 100%; 100 | line-height: inherit; 101 | color: inherit; 102 | margin: 0; 103 | padding: 0 104 | } 105 | 106 | button, 107 | select { 108 | text-transform: none 109 | } 110 | 111 | [type=button], 112 | [type=reset], 113 | [type=submit], 114 | button { 115 | -webkit-appearance: button; 116 | background-color: initial; 117 | background-image: none 118 | } 119 | 120 | :-moz-focusring { 121 | outline: auto 122 | } 123 | 124 | :-moz-ui-invalid { 125 | box-shadow: none 126 | } 127 | 128 | progress { 129 | vertical-align: initial 130 | } 131 | 132 | ::-webkit-inner-spin-button, 133 | ::-webkit-outer-spin-button { 134 | height: auto 135 | } 136 | 137 | [type=search] { 138 | -webkit-appearance: textfield; 139 | outline-offset: -2px 140 | } 141 | 142 | ::-webkit-search-decoration { 143 | -webkit-appearance: none 144 | } 145 | 146 | ::-webkit-file-upload-button { 147 | -webkit-appearance: button; 148 | font: inherit 149 | } 150 | 151 | summary { 152 | display: list-item 153 | } 154 | 155 | blockquote, 156 | dd, 157 | dl, 158 | figure, 159 | h1, 160 | h2, 161 | h3, 162 | h4, 163 | h5, 164 | h6, 165 | hr, 166 | p, 167 | pre { 168 | margin: 0 169 | } 170 | 171 | fieldset { 172 | margin: 0 173 | } 174 | 175 | fieldset, 176 | legend { 177 | padding: 0 178 | } 179 | 180 | menu, 181 | ol, 182 | ul { 183 | list-style: none; 184 | margin: 0; 185 | padding: 0 186 | } 187 | 188 | textarea { 189 | resize: vertical 190 | } 191 | 192 | input::-moz-placeholder, 193 | textarea::-moz-placeholder { 194 | opacity: 1; 195 | color: #9ca3af 196 | } 197 | 198 | input:-ms-input-placeholder, 199 | textarea:-ms-input-placeholder { 200 | opacity: 1; 201 | color: #9ca3af 202 | } 203 | 204 | input::placeholder, 205 | textarea::placeholder { 206 | opacity: 1; 207 | color: #9ca3af 208 | } 209 | 210 | [role=button], 211 | button { 212 | cursor: pointer 213 | } 214 | 215 | :disabled { 216 | cursor: default 217 | } 218 | 219 | audio, 220 | canvas, 221 | embed, 222 | iframe, 223 | img, 224 | object, 225 | svg, 226 | video { 227 | display: block; 228 | vertical-align: middle 229 | } 230 | 231 | img, 232 | video { 233 | max-width: 100%; 234 | height: auto 235 | } 236 | 237 | [hidden] { 238 | display: none 239 | } 240 | 241 | *, 242 | :after, 243 | :before { 244 | --tw-translate-x: 0; 245 | --tw-translate-y: 0; 246 | --tw-rotate: 0; 247 | --tw-skew-x: 0; 248 | --tw-skew-y: 0; 249 | --tw-scale-x: 1; 250 | --tw-scale-y: 1; 251 | --tw-pan-x: ; 252 | --tw-pan-y: ; 253 | --tw-pinch-zoom: ; 254 | --tw-scroll-snap-strictness: proximity; 255 | --tw-ordinal: ; 256 | --tw-slashed-zero: ; 257 | --tw-numeric-figure: ; 258 | --tw-numeric-spacing: ; 259 | --tw-numeric-fraction: ; 260 | --tw-ring-inset: ; 261 | --tw-ring-offset-width: 0px; 262 | --tw-ring-offset-color: #fff; 263 | --tw-ring-color: #3b82f680; 264 | --tw-ring-offset-shadow: 0 0 #0000; 265 | --tw-ring-shadow: 0 0 #0000; 266 | --tw-shadow: 0 0 #0000; 267 | --tw-shadow-colored: 0 0 #0000; 268 | --tw-blur: ; 269 | --tw-brightness: ; 270 | --tw-contrast: ; 271 | --tw-grayscale: ; 272 | --tw-hue-rotate: ; 273 | --tw-invert: ; 274 | --tw-saturate: ; 275 | --tw-sepia: ; 276 | --tw-drop-shadow: ; 277 | --tw-backdrop-blur: ; 278 | --tw-backdrop-brightness: ; 279 | --tw-backdrop-contrast: ; 280 | --tw-backdrop-grayscale: ; 281 | --tw-backdrop-hue-rotate: ; 282 | --tw-backdrop-invert: ; 283 | --tw-backdrop-opacity: ; 284 | --tw-backdrop-saturate: ; 285 | --tw-backdrop-sepia: 286 | } 287 | 288 | .container { 289 | width: 100% 290 | } 291 | 292 | @media (min-width:640px) { 293 | .container { 294 | max-width: 640px 295 | } 296 | } 297 | 298 | @media (min-width:768px) { 299 | .container { 300 | max-width: 768px 301 | } 302 | } 303 | 304 | @media (min-width:1024px) { 305 | .container { 306 | max-width: 1024px 307 | } 308 | } 309 | 310 | @media (min-width:1280px) { 311 | .container { 312 | max-width: 1280px 313 | } 314 | } 315 | 316 | @media (min-width:1536px) { 317 | .container { 318 | max-width: 1536px 319 | } 320 | } 321 | 322 | .fixed { 323 | position: fixed 324 | } 325 | 326 | .relative { 327 | position: relative 328 | } 329 | 330 | .mx-auto { 331 | margin-left: auto; 332 | margin-right: auto 333 | } 334 | 335 | .mb-4 { 336 | margin-bottom: 1rem 337 | } 338 | 339 | .ml-3 { 340 | margin-left: .75rem 341 | } 342 | 343 | .mr-5 { 344 | margin-right: 1.25rem 345 | } 346 | 347 | .mt-4 { 348 | margin-top: 1rem 349 | } 350 | 351 | .ml-1 { 352 | margin-left: .25rem 353 | } 354 | 355 | .mb-12 { 356 | margin-bottom: 3rem 357 | } 358 | 359 | .mt-3 { 360 | margin-top: .75rem 361 | } 362 | 363 | .mt-2 { 364 | margin-top: .5rem 365 | } 366 | 367 | .mb-8 { 368 | margin-bottom: 2rem 369 | } 370 | 371 | .mb-10 { 372 | margin-bottom: 2.5rem 373 | } 374 | 375 | .-mb-10 { 376 | margin-bottom: -2.5rem 377 | } 378 | 379 | .mb-5 { 380 | margin-bottom: 1.25rem 381 | } 382 | 383 | .mb-3 { 384 | margin-bottom: .75rem 385 | } 386 | 387 | .ml-2 { 388 | margin-left: .5rem 389 | } 390 | 391 | .flex { 392 | display: flex 393 | } 394 | 395 | .inline-flex { 396 | display: inline-flex 397 | } 398 | 399 | .h-4 { 400 | height: 1rem 401 | } 402 | 403 | .h-3\/4 { 404 | height: 75% 405 | } 406 | 407 | .h-12 { 408 | height: 3rem 409 | } 410 | 411 | .h-6 { 412 | height: 1.5rem 413 | } 414 | 415 | .w-4 { 416 | width: 1rem 417 | } 418 | 419 | .w-full { 420 | width: 100% 421 | } 422 | 423 | .w-auto { 424 | width: auto 425 | } 426 | 427 | .w-3\/4 { 428 | width: 75% 429 | } 430 | 431 | .w-12 { 432 | width: 3rem 433 | } 434 | 435 | .w-6 { 436 | width: 1.5rem 437 | } 438 | 439 | .flex-grow { 440 | flex-grow: 1 441 | } 442 | 443 | .cursor-pointer { 444 | cursor: pointer 445 | } 446 | 447 | .flex-col { 448 | flex-direction: column 449 | } 450 | 451 | .flex-wrap { 452 | flex-wrap: wrap 453 | } 454 | 455 | .items-end { 456 | align-items: flex-end 457 | } 458 | 459 | .items-center { 460 | align-items: center 461 | } 462 | 463 | .justify-center { 464 | justify-content: center 465 | } 466 | 467 | .space-y-4>:not([hidden])~:not([hidden]) { 468 | --tw-space-y-reverse: 0; 469 | margin-top: calc(1rem*(1 - var(--tw-space-y-reverse))); 470 | margin-bottom: calc(1rem*var(--tw-space-y-reverse)) 471 | } 472 | 473 | .overflow-hidden { 474 | overflow: hidden 475 | } 476 | 477 | .rounded { 478 | border-radius: .25rem 479 | } 480 | 481 | .rounded-2xl { 482 | border-radius: 1rem 483 | } 484 | 485 | .rounded-lg { 486 | border-radius: .5rem 487 | } 488 | 489 | .rounded-full { 490 | border-radius: 9999px 491 | } 492 | 493 | .bg-slate-50 { 494 | --tw-bg-opacity: 1; 495 | background-color: rgb(248 250 252/var(--tw-bg-opacity)) 496 | } 497 | 498 | .bg-gray-100 { 499 | --tw-bg-opacity: 1; 500 | background-color: rgb(243 244 246/var(--tw-bg-opacity)) 501 | } 502 | 503 | .bg-white { 504 | --tw-bg-opacity: 1; 505 | background-color: rgb(255 255 255/var(--tw-bg-opacity)) 506 | } 507 | 508 | .bg-slate-300 { 509 | --tw-bg-opacity: 1; 510 | background-color: rgb(203 213 225/var(--tw-bg-opacity)) 511 | } 512 | 513 | .object-center { 514 | -o-object-position: center; 515 | object-position: center 516 | } 517 | 518 | .p-5 { 519 | padding: 1.25rem 520 | } 521 | 522 | .p-6 { 523 | padding: 1.5rem 524 | } 525 | 526 | .py-1 { 527 | padding-top: .25rem; 528 | padding-bottom: .25rem 529 | } 530 | 531 | .px-3 { 532 | padding-left: .75rem; 533 | padding-right: .75rem 534 | } 535 | 536 | .px-5 { 537 | padding-left: 1.25rem; 538 | padding-right: 1.25rem 539 | } 540 | 541 | .py-24 { 542 | padding-top: 6rem; 543 | padding-bottom: 6rem 544 | } 545 | 546 | .px-8 { 547 | padding-left: 2rem; 548 | padding-right: 2rem 549 | } 550 | 551 | .text-center { 552 | text-align: center 553 | } 554 | 555 | .text-xl { 556 | font-size: 1.25rem; 557 | line-height: 1.75rem 558 | } 559 | 560 | .text-base { 561 | font-size: 1rem; 562 | line-height: 1.5rem 563 | } 564 | 565 | .text-2xl { 566 | font-size: 1.5rem; 567 | line-height: 2rem 568 | } 569 | 570 | .text-sm { 571 | font-size: .875rem; 572 | line-height: 1.25rem 573 | } 574 | 575 | .text-lg { 576 | font-size: 1.125rem; 577 | line-height: 1.75rem 578 | } 579 | 580 | .font-medium { 581 | font-weight: 500 582 | } 583 | 584 | .leading-relaxed { 585 | line-height: 1.625 586 | } 587 | 588 | .leading-7 { 589 | line-height: 1.75rem 590 | } 591 | 592 | .text-gray-600 { 593 | --tw-text-opacity: 1; 594 | color: rgb(75 85 99/var(--tw-text-opacity)) 595 | } 596 | 597 | .text-gray-900 { 598 | --tw-text-opacity: 1; 599 | color: rgb(17 24 39/var(--tw-text-opacity)) 600 | } 601 | 602 | .text-slate-800 { 603 | --tw-text-opacity: 1; 604 | color: rgb(30 41 59/var(--tw-text-opacity)) 605 | } 606 | 607 | .shadow-md { 608 | --tw-shadow: 0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a; 609 | --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color); 610 | box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow) 611 | } 612 | 613 | .duration-300 { 614 | transition-duration: .3s 615 | } 616 | 617 | .ease-in-out { 618 | transition-timing-function: cubic-bezier(.4, 0, .2, 1) 619 | } 620 | 621 | .ease-out { 622 | transition-timing-function: cubic-bezier(0, 0, .2, 1) 623 | } 624 | 625 | .hover\:text-gray-900:hover { 626 | --tw-text-opacity: 1; 627 | color: rgb(17 24 39/var(--tw-text-opacity)) 628 | } 629 | 630 | .hover\:shadow-lg:hover { 631 | --tw-shadow: 0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a; 632 | --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color) 633 | } 634 | 635 | .hover\:shadow-lg:hover, 636 | .hover\:shadow-xl:hover { 637 | box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow) 638 | } 639 | 640 | .hover\:shadow-xl:hover { 641 | --tw-shadow: 0 20px 25px -5px #0000001a, 0 8px 10px -6px #0000001a; 642 | --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color) 643 | } 644 | 645 | @media (min-width:640px) { 646 | .sm\:flex-row { 647 | flex-direction: row 648 | } 649 | 650 | .sm\:space-x-4>:not([hidden])~:not([hidden]) { 651 | --tw-space-x-reverse: 0; 652 | margin-right: calc(1rem*var(--tw-space-x-reverse)); 653 | margin-left: calc(1rem*(1 - var(--tw-space-x-reverse))) 654 | } 655 | 656 | .sm\:space-y-0>:not([hidden])~:not([hidden]) { 657 | --tw-space-y-reverse: 0; 658 | margin-top: calc(0px*(1 - var(--tw-space-y-reverse))); 659 | margin-bottom: calc(0px*var(--tw-space-y-reverse)) 660 | } 661 | 662 | .sm\:px-0 { 663 | padding-left: 0; 664 | padding-right: 0 665 | } 666 | 667 | .sm\:text-7xl { 668 | font-size: 4.5rem; 669 | line-height: 1 670 | } 671 | } 672 | 673 | @media (min-width:768px) { 674 | .md\:mb-0 { 675 | margin-bottom: 0 676 | } 677 | 678 | .md\:ml-auto { 679 | margin-left: auto 680 | } 681 | 682 | .md\:mr-auto { 683 | margin-right: auto 684 | } 685 | 686 | .md\:mt-0 { 687 | margin-top: 0 688 | } 689 | 690 | .md\:flex-row { 691 | flex-direction: row 692 | } 693 | } 694 | 695 | @media (min-width:1024px) { 696 | .lg\:mb-0 { 697 | margin-bottom: 0 698 | } 699 | 700 | .lg\:w-2\/3 { 701 | width: 66.666667% 702 | } 703 | 704 | .lg\:w-1\/2 { 705 | width: 50% 706 | } 707 | 708 | .lg\:items-start { 709 | align-items: flex-start 710 | } 711 | 712 | .lg\:py-6 { 713 | padding-top: 1.5rem; 714 | padding-bottom: 1.5rem 715 | } 716 | 717 | .lg\:pl-12 { 718 | padding-left: 3rem 719 | } 720 | 721 | .lg\:text-left { 722 | text-align: left 723 | } 724 | } 725 | 726 | .button { 727 | display: inline-flex; 728 | padding: 1.3em 3em; 729 | font-size: 12px; 730 | text-transform: uppercase; 731 | letter-spacing: 2.5px; 732 | font-weight: 500; 733 | color: #000; 734 | background-color: #fff; 735 | border: none; 736 | border-radius: 45px; 737 | box-shadow: 0px 8px 15px rgba(0, 0, 0, 0.1); 738 | transition: all 0.3s ease 0s; 739 | cursor: pointer; 740 | outline: none; 741 | } 742 | 743 | .button:hover { 744 | background-color: #2EE59D; 745 | box-shadow: 0px 15px 20px rgba(46, 229, 157, 0.4); 746 | color: #fff; 747 | transform: translateY(-7px); 748 | } 749 | 750 | .button:active { 751 | transform: translateY(-1px); 752 | } 753 | 754 | 755 | .container .buttons { 756 | display: -webkit-box; 757 | display: -ms-flexbox; 758 | display: flex; 759 | -webkit-box-pack: center; 760 | -ms-flex-pack: center; 761 | justify-content: center; 762 | -webkit-box-align: center; 763 | -ms-flex-align: center; 764 | align-items: center; 765 | -ms-flex-wrap: wrap; 766 | flex-wrap: wrap; 767 | } 768 | 769 | .container .buttons button { 770 | margin: 10px; 771 | } 772 | 773 | button.upload .circle .icon { 774 | transition: all 0.45s cubic-bezier(0.65, 0, 0.076, 1); 775 | position: absolute; 776 | top: 0; 777 | bottom: 0; 778 | margin: auto; 779 | background: #fff; 780 | } 781 | 782 | .custom-btn { 783 | padding: 10px 25px; 784 | width: 10em; 785 | border: unset; 786 | border-radius: 50px; 787 | color: #212121; 788 | z-index: 1; 789 | background: white; 790 | position: relative; 791 | font-size: 17px; 792 | transition: all 250ms; 793 | overflow: hidden; 794 | } 795 | 796 | .custom-btn::before { 797 | content: ""; 798 | position: absolute; 799 | top: 0; 800 | left: 0; 801 | height: 100%; 802 | width: 0; 803 | border-radius: 15px; 804 | background-color: #212121; 805 | z-index: -1; 806 | transition: all 250ms 807 | } 808 | 809 | .custom-btn:hover { 810 | color: #e8e8e8; 811 | } 812 | 813 | .custom-btn:hover::before { 814 | width: 100%; 815 | } 816 | 817 | .icons { 818 | font-size: larger; 819 | } -------------------------------------------------------------------------------- /static/copy.js: -------------------------------------------------------------------------------- 1 | console.log('copy.js'); 2 | 3 | // copy to clipboard on copy btn click 4 | function copy() { 5 | /* Get the text field */ 6 | var copyText = document.getElementById("ocrtext"); 7 | // get text inside of copytext element 8 | var text = copyText.innerText; 9 | /* Copy the text inside the text field */ 10 | navigator.clipboard.writeText(text); 11 | // set the text to be copied 12 | document.querySelector('#copybtn').innerText = "Copied!"; 13 | } 14 | 15 | // on upload button click , change text to clicked 16 | function uploaded() { 17 | console.log('uploaded'); 18 | document.querySelector('#upload-btn').innerText = "Uploaded!"; 19 | } -------------------------------------------------------------------------------- /static/error.js: -------------------------------------------------------------------------------- 1 | setTimeout(function () { 2 | const modal = document.getElementById("error-modal"); 3 | // hide modal after 3 seconds 4 | modal.style.display = "none"; 5 | }, 2800); -------------------------------------------------------------------------------- /static/style.css: -------------------------------------------------------------------------------- 1 | /*! tailwindcss v3.0.22 | MIT License | https://tailwindcss.com*/ 2 | *, 3 | :after, 4 | :before { 5 | box-sizing: border-box; 6 | border: 0 solid #e5e7eb 7 | } 8 | 9 | :after, 10 | :before { 11 | --tw-content: "" 12 | } 13 | 14 | html { 15 | line-height: 1.5; 16 | -webkit-text-size-adjust: 100%; 17 | -moz-tab-size: 4; 18 | -o-tab-size: 4; 19 | tab-size: 4; 20 | font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, Noto Sans, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji 21 | } 22 | 23 | body { 24 | margin: 0; 25 | line-height: inherit 26 | } 27 | 28 | hr { 29 | height: 0; 30 | color: inherit; 31 | border-top-width: 1px 32 | } 33 | 34 | abbr:where([title]) { 35 | -webkit-text-decoration: underline dotted; 36 | text-decoration: underline dotted 37 | } 38 | 39 | h1, 40 | h2, 41 | h3, 42 | h4, 43 | h5, 44 | h6 { 45 | font-size: inherit; 46 | font-weight: inherit 47 | } 48 | 49 | a { 50 | color: inherit; 51 | text-decoration: inherit 52 | } 53 | 54 | b, 55 | strong { 56 | font-weight: bolder 57 | } 58 | 59 | code, 60 | kbd, 61 | pre, 62 | samp { 63 | font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace; 64 | font-size: 1em 65 | } 66 | 67 | small { 68 | font-size: 80% 69 | } 70 | 71 | sub, 72 | sup { 73 | font-size: 75%; 74 | line-height: 0; 75 | position: relative; 76 | vertical-align: initial 77 | } 78 | 79 | sub { 80 | bottom: -.25em 81 | } 82 | 83 | sup { 84 | top: -.5em 85 | } 86 | 87 | table { 88 | text-indent: 0; 89 | border-color: inherit; 90 | border-collapse: collapse 91 | } 92 | 93 | button, 94 | input, 95 | optgroup, 96 | select, 97 | textarea { 98 | font-family: inherit; 99 | font-size: 100%; 100 | line-height: inherit; 101 | color: inherit; 102 | margin: 0; 103 | padding: 0 104 | } 105 | 106 | button, 107 | select { 108 | text-transform: none 109 | } 110 | 111 | [type=button], 112 | [type=reset], 113 | [type=submit], 114 | button { 115 | -webkit-appearance: button; 116 | background-color: initial; 117 | background-image: none 118 | } 119 | 120 | :-moz-focusring { 121 | outline: auto 122 | } 123 | 124 | :-moz-ui-invalid { 125 | box-shadow: none 126 | } 127 | 128 | progress { 129 | vertical-align: initial 130 | } 131 | 132 | ::-webkit-inner-spin-button, 133 | ::-webkit-outer-spin-button { 134 | height: auto 135 | } 136 | 137 | [type=search] { 138 | -webkit-appearance: textfield; 139 | outline-offset: -2px 140 | } 141 | 142 | ::-webkit-search-decoration { 143 | -webkit-appearance: none 144 | } 145 | 146 | ::-webkit-file-upload-button { 147 | -webkit-appearance: button; 148 | font: inherit 149 | } 150 | 151 | summary { 152 | display: list-item 153 | } 154 | 155 | blockquote, 156 | dd, 157 | dl, 158 | figure, 159 | h1, 160 | h2, 161 | h3, 162 | h4, 163 | h5, 164 | h6, 165 | hr, 166 | p, 167 | pre { 168 | margin: 0 169 | } 170 | 171 | fieldset { 172 | margin: 0 173 | } 174 | 175 | fieldset, 176 | legend { 177 | padding: 0 178 | } 179 | 180 | menu, 181 | ol, 182 | ul { 183 | list-style: none; 184 | margin: 0; 185 | padding: 0 186 | } 187 | 188 | textarea { 189 | resize: vertical 190 | } 191 | 192 | input::-moz-placeholder, 193 | textarea::-moz-placeholder { 194 | opacity: 1; 195 | color: #9ca3af 196 | } 197 | 198 | input:-ms-input-placeholder, 199 | textarea:-ms-input-placeholder { 200 | opacity: 1; 201 | color: #9ca3af 202 | } 203 | 204 | input::placeholder, 205 | textarea::placeholder { 206 | opacity: 1; 207 | color: #9ca3af 208 | } 209 | 210 | [role=button], 211 | button { 212 | cursor: pointer 213 | } 214 | 215 | :disabled { 216 | cursor: default 217 | } 218 | 219 | audio, 220 | canvas, 221 | embed, 222 | iframe, 223 | img, 224 | object, 225 | svg, 226 | video { 227 | display: block; 228 | vertical-align: middle 229 | } 230 | 231 | img, 232 | video { 233 | max-width: 100%; 234 | height: auto 235 | } 236 | 237 | [hidden] { 238 | display: none 239 | } 240 | 241 | *, 242 | :after, 243 | :before { 244 | --tw-translate-x: 0; 245 | --tw-translate-y: 0; 246 | --tw-rotate: 0; 247 | --tw-skew-x: 0; 248 | --tw-skew-y: 0; 249 | --tw-scale-x: 1; 250 | --tw-scale-y: 1; 251 | --tw-pan-x: ; 252 | --tw-pan-y: ; 253 | --tw-pinch-zoom: ; 254 | --tw-scroll-snap-strictness: proximity; 255 | --tw-ordinal: ; 256 | --tw-slashed-zero: ; 257 | --tw-numeric-figure: ; 258 | --tw-numeric-spacing: ; 259 | --tw-numeric-fraction: ; 260 | --tw-ring-inset: ; 261 | --tw-ring-offset-width: 0px; 262 | --tw-ring-offset-color: #fff; 263 | --tw-ring-color: #3b82f680; 264 | --tw-ring-offset-shadow: 0 0 #0000; 265 | --tw-ring-shadow: 0 0 #0000; 266 | --tw-shadow: 0 0 #0000; 267 | --tw-shadow-colored: 0 0 #0000; 268 | --tw-blur: ; 269 | --tw-brightness: ; 270 | --tw-contrast: ; 271 | --tw-grayscale: ; 272 | --tw-hue-rotate: ; 273 | --tw-invert: ; 274 | --tw-saturate: ; 275 | --tw-sepia: ; 276 | --tw-drop-shadow: ; 277 | --tw-backdrop-blur: ; 278 | --tw-backdrop-brightness: ; 279 | --tw-backdrop-contrast: ; 280 | --tw-backdrop-grayscale: ; 281 | --tw-backdrop-hue-rotate: ; 282 | --tw-backdrop-invert: ; 283 | --tw-backdrop-opacity: ; 284 | --tw-backdrop-saturate: ; 285 | --tw-backdrop-sepia: 286 | } 287 | 288 | .container { 289 | width: 100% 290 | } 291 | 292 | @media (min-width:640px) { 293 | .container { 294 | max-width: 640px 295 | } 296 | } 297 | 298 | @media (min-width:768px) { 299 | .container { 300 | max-width: 768px 301 | } 302 | } 303 | 304 | @media (min-width:1024px) { 305 | .container { 306 | max-width: 1024px 307 | } 308 | } 309 | 310 | @media (min-width:1280px) { 311 | .container { 312 | max-width: 1280px 313 | } 314 | } 315 | 316 | @media (min-width:1536px) { 317 | .container { 318 | max-width: 1536px 319 | } 320 | } 321 | 322 | .fixed { 323 | position: fixed 324 | } 325 | 326 | .left-8 { 327 | left: 2rem 328 | } 329 | 330 | .top-8 { 331 | top: 2rem 332 | } 333 | 334 | .m-5 { 335 | margin: 1.25rem 336 | } 337 | 338 | .mx-auto { 339 | margin-left: auto; 340 | margin-right: auto 341 | } 342 | 343 | .-mx-3 { 344 | margin-left: -.75rem; 345 | margin-right: -.75rem 346 | } 347 | 348 | .mx-3 { 349 | margin-left: .75rem; 350 | margin-right: .75rem 351 | } 352 | 353 | .mb-4 { 354 | margin-bottom: 1rem 355 | } 356 | 357 | .ml-3 { 358 | margin-left: .75rem 359 | } 360 | 361 | .mr-5 { 362 | margin-right: 1.25rem 363 | } 364 | 365 | .mt-4 { 366 | margin-top: 1rem 367 | } 368 | 369 | .ml-1 { 370 | margin-left: .25rem 371 | } 372 | 373 | .mb-12 { 374 | margin-bottom: 3rem 375 | } 376 | 377 | .mb-2 { 378 | margin-bottom: .5rem 379 | } 380 | 381 | .mt-3 { 382 | margin-top: .75rem 383 | } 384 | 385 | .mt-2 { 386 | margin-top: .5rem 387 | } 388 | 389 | .mb-8 { 390 | margin-bottom: 2rem 391 | } 392 | 393 | .mb-10 { 394 | margin-bottom: 2.5rem 395 | } 396 | 397 | .-mb-10 { 398 | margin-bottom: -2.5rem 399 | } 400 | 401 | .mb-5 { 402 | margin-bottom: 1.25rem 403 | } 404 | 405 | .mb-3 { 406 | margin-bottom: .75rem 407 | } 408 | 409 | .ml-2 { 410 | margin-left: .5rem 411 | } 412 | 413 | .flex { 414 | display: flex 415 | } 416 | 417 | .inline-flex { 418 | display: inline-flex 419 | } 420 | 421 | .h-4 { 422 | height: 1rem 423 | } 424 | 425 | .h-6 { 426 | height: 1.5rem 427 | } 428 | 429 | .h-96 { 430 | height: 24rem 431 | } 432 | 433 | .h-3\/4 { 434 | height: 75% 435 | } 436 | 437 | .h-12 { 438 | height: 3rem 439 | } 440 | 441 | .h-20 { 442 | height: 5rem 443 | } 444 | 445 | .h-5 { 446 | height: 1.25rem 447 | } 448 | 449 | .w-4 { 450 | width: 1rem 451 | } 452 | 453 | .w-full { 454 | width: 100% 455 | } 456 | 457 | .w-12 { 458 | width: 3rem 459 | } 460 | 461 | .w-6 { 462 | width: 1.5rem 463 | } 464 | 465 | .w-auto { 466 | width: auto 467 | } 468 | 469 | .w-3\/4 { 470 | width: 75% 471 | } 472 | 473 | .w-5 { 474 | width: 1.25rem 475 | } 476 | 477 | .max-w-sm { 478 | max-width: 24rem 479 | } 480 | 481 | .flex-grow { 482 | flex-grow: 1 483 | } 484 | 485 | @-webkit-keyframes pulse { 486 | 50% { 487 | opacity: .5 488 | } 489 | } 490 | 491 | @keyframes pulse { 492 | 50% { 493 | opacity: .5 494 | } 495 | } 496 | 497 | .animate-pulse { 498 | -webkit-animation: pulse 2s cubic-bezier(.4, 0, .6, 1) infinite; 499 | animation: pulse 2s cubic-bezier(.4, 0, .6, 1) infinite 500 | } 501 | 502 | .cursor-pointer { 503 | cursor: pointer 504 | } 505 | 506 | .flex-col { 507 | flex-direction: column 508 | } 509 | 510 | .flex-wrap { 511 | flex-wrap: wrap 512 | } 513 | 514 | .items-center { 515 | align-items: center 516 | } 517 | 518 | .justify-center { 519 | justify-content: center 520 | } 521 | 522 | .overflow-hidden { 523 | overflow: hidden 524 | } 525 | 526 | .rounded { 527 | border-radius: .25rem 528 | } 529 | 530 | .rounded-lg { 531 | border-radius: .5rem 532 | } 533 | 534 | .rounded-2xl { 535 | border-radius: 1rem 536 | } 537 | 538 | .rounded-full { 539 | border-radius: 9999px 540 | } 541 | 542 | .bg-slate-50 { 543 | --tw-bg-opacity: 1; 544 | background-color: rgb(248 250 252/var(--tw-bg-opacity)) 545 | } 546 | 547 | .bg-gray-100 { 548 | --tw-bg-opacity: 1; 549 | background-color: rgb(243 244 246/var(--tw-bg-opacity)) 550 | } 551 | 552 | .bg-white { 553 | --tw-bg-opacity: 1; 554 | background-color: rgb(255 255 255/var(--tw-bg-opacity)) 555 | } 556 | 557 | .bg-transparent { 558 | background-color: initial 559 | } 560 | 561 | .bg-slate-300 { 562 | --tw-bg-opacity: 1; 563 | background-color: rgb(203 213 225/var(--tw-bg-opacity)) 564 | } 565 | 566 | .fill-current { 567 | fill: currentColor 568 | } 569 | 570 | .stroke-slate-900 { 571 | stroke: #0f172a 572 | } 573 | 574 | .stroke-white { 575 | stroke: #fff 576 | } 577 | 578 | .stroke-slate-400 { 579 | stroke: #94a3b8 580 | } 581 | 582 | .stroke-2 { 583 | stroke-width: 2 584 | } 585 | 586 | .object-center { 587 | -o-object-position: center; 588 | object-position: center 589 | } 590 | 591 | .p-5 { 592 | padding: 1.25rem 593 | } 594 | 595 | .p-6 { 596 | padding: 1.5rem 597 | } 598 | 599 | .p-2 { 600 | padding: .5rem 601 | } 602 | 603 | .py-1 { 604 | padding-top: .25rem; 605 | padding-bottom: .25rem 606 | } 607 | 608 | .px-3 { 609 | padding-left: .75rem; 610 | padding-right: .75rem 611 | } 612 | 613 | .px-4 { 614 | padding-left: 1rem; 615 | padding-right: 1rem 616 | } 617 | 618 | .py-2 { 619 | padding-top: .5rem; 620 | padding-bottom: .5rem 621 | } 622 | 623 | .px-5 { 624 | padding-left: 1.25rem; 625 | padding-right: 1.25rem 626 | } 627 | 628 | .py-24 { 629 | padding-top: 6rem; 630 | padding-bottom: 6rem 631 | } 632 | 633 | .py-8 { 634 | padding-top: 2rem; 635 | padding-bottom: 2rem 636 | } 637 | 638 | .text-center { 639 | text-align: center 640 | } 641 | 642 | .text-xl { 643 | font-size: 1.25rem; 644 | line-height: 1.75rem 645 | } 646 | 647 | .text-base { 648 | font-size: 1rem; 649 | line-height: 1.5rem 650 | } 651 | 652 | .text-sm { 653 | font-size: .875rem; 654 | line-height: 1.25rem 655 | } 656 | 657 | .text-2xl { 658 | font-size: 1.5rem; 659 | line-height: 2rem 660 | } 661 | 662 | .text-lg { 663 | font-size: 1.125rem; 664 | line-height: 1.75rem 665 | } 666 | 667 | .font-medium { 668 | font-weight: 500 669 | } 670 | 671 | .font-semibold { 672 | font-weight: 600 673 | } 674 | 675 | .leading-relaxed { 676 | line-height: 1.625 677 | } 678 | 679 | .text-gray-600 { 680 | --tw-text-opacity: 1; 681 | color: rgb(75 85 99/var(--tw-text-opacity)) 682 | } 683 | 684 | .text-gray-900 { 685 | --tw-text-opacity: 1; 686 | color: rgb(17 24 39/var(--tw-text-opacity)) 687 | } 688 | 689 | .text-slate-800 { 690 | --tw-text-opacity: 1; 691 | color: rgb(30 41 59/var(--tw-text-opacity)) 692 | } 693 | 694 | .text-white { 695 | --tw-text-opacity: 1; 696 | color: rgb(255 255 255/var(--tw-text-opacity)) 697 | } 698 | 699 | .text-gray-500 { 700 | --tw-text-opacity: 1; 701 | color: rgb(107 114 128/var(--tw-text-opacity)) 702 | } 703 | 704 | .shadow-lg { 705 | --tw-shadow: 0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a; 706 | --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color) 707 | } 708 | 709 | .shadow-lg, 710 | .shadow-md { 711 | box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow) 712 | } 713 | 714 | .shadow-md { 715 | --tw-shadow: 0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a; 716 | --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color) 717 | } 718 | 719 | .duration-300 { 720 | transition-duration: .3s 721 | } 722 | 723 | .duration-500 { 724 | transition-duration: .5s 725 | } 726 | 727 | .ease-out { 728 | transition-timing-function: cubic-bezier(0, 0, .2, 1) 729 | } 730 | 731 | .hover\:scale-105:hover { 732 | --tw-scale-x: 1.05; 733 | --tw-scale-y: 1.05; 734 | transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)) 735 | } 736 | 737 | .hover\:text-gray-900:hover { 738 | --tw-text-opacity: 1; 739 | color: rgb(17 24 39/var(--tw-text-opacity)) 740 | } 741 | 742 | .hover\:shadow-lg:hover { 743 | --tw-shadow: 0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a; 744 | --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color); 745 | box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow) 746 | } 747 | 748 | @media (min-width:640px) { 749 | .sm\:ml-4 { 750 | margin-left: 1rem 751 | } 752 | 753 | .sm\:mt-0 { 754 | margin-top: 0 755 | } 756 | 757 | .sm\:ml-auto { 758 | margin-left: auto 759 | } 760 | 761 | .sm\:flex-row { 762 | flex-direction: row 763 | } 764 | 765 | .sm\:justify-start { 766 | justify-content: flex-start 767 | } 768 | 769 | .sm\:border-l-2 { 770 | border-left-width: 2px 771 | } 772 | 773 | .sm\:border-gray-200 { 774 | --tw-border-opacity: 1; 775 | border-color: rgb(229 231 235/var(--tw-border-opacity)) 776 | } 777 | 778 | .sm\:py-2 { 779 | padding-top: .5rem; 780 | padding-bottom: .5rem 781 | } 782 | 783 | .sm\:pl-4 { 784 | padding-left: 1rem 785 | } 786 | 787 | .sm\:text-7xl { 788 | font-size: 4.5rem; 789 | line-height: 1 790 | } 791 | } 792 | 793 | @media (min-width:768px) { 794 | .md\:mb-0 { 795 | margin-bottom: 0 796 | } 797 | 798 | .md\:ml-auto { 799 | margin-left: auto 800 | } 801 | 802 | .md\:mr-auto { 803 | margin-right: auto 804 | } 805 | 806 | .md\:mt-0 { 807 | margin-top: 0 808 | } 809 | 810 | .md\:flex-row { 811 | flex-direction: row 812 | } 813 | 814 | .md\:justify-start { 815 | justify-content: flex-start 816 | } 817 | } 818 | 819 | @media (min-width:1024px) { 820 | .lg\:mb-0 { 821 | margin-bottom: 0 822 | } 823 | 824 | .lg\:w-2\/3 { 825 | width: 66.666667% 826 | } 827 | 828 | .lg\:w-1\/2 { 829 | width: 50% 830 | } 831 | 832 | .lg\:items-start { 833 | align-items: flex-start 834 | } 835 | 836 | .lg\:py-6 { 837 | padding-top: 1.5rem; 838 | padding-bottom: 1.5rem 839 | } 840 | 841 | .lg\:pl-12 { 842 | padding-left: 3rem 843 | } 844 | 845 | .lg\:text-left { 846 | text-align: left 847 | } 848 | } 849 | 850 | .button { 851 | display: inline-flex; 852 | padding: 1.3em 3em; 853 | font-size: 12px; 854 | text-transform: uppercase; 855 | letter-spacing: 2.5px; 856 | font-weight: 500; 857 | color: #000; 858 | background-color: #fff; 859 | border: none; 860 | border-radius: 45px; 861 | box-shadow: 0px 8px 15px rgba(0, 0, 0, 0.1); 862 | transition: all 0.3s ease 0s; 863 | cursor: pointer; 864 | outline: none; 865 | } 866 | 867 | .button:hover { 868 | background-color: #2EE59D; 869 | box-shadow: 0px 15px 20px rgba(46, 229, 157, 0.4); 870 | color: #fff; 871 | transform: translateY(-7px); 872 | } 873 | 874 | .button:active { 875 | transform: translateY(-1px); 876 | } 877 | 878 | 879 | .container .buttons { 880 | display: -webkit-box; 881 | display: -ms-flexbox; 882 | display: flex; 883 | -webkit-box-pack: center; 884 | -ms-flex-pack: center; 885 | justify-content: center; 886 | -webkit-box-align: center; 887 | -ms-flex-align: center; 888 | align-items: center; 889 | -ms-flex-wrap: wrap; 890 | flex-wrap: wrap; 891 | } 892 | 893 | .container .buttons button { 894 | margin: 10px; 895 | } 896 | 897 | button.upload .circle .icon { 898 | transition: all 0.45s cubic-bezier(0.65, 0, 0.076, 1); 899 | position: absolute; 900 | top: 0; 901 | bottom: 0; 902 | margin: auto; 903 | background: #fff; 904 | } 905 | 906 | .custom-btn { 907 | padding: 10px 25px; 908 | width: 10em; 909 | border: unset; 910 | border-radius: 50px; 911 | color: #212121; 912 | z-index: 1; 913 | background: white; 914 | position: relative; 915 | font-size: 17px; 916 | transition: all 250ms; 917 | overflow: hidden; 918 | } 919 | 920 | .custom-btn::before { 921 | content: ""; 922 | position: absolute; 923 | top: 0; 924 | left: 0; 925 | height: 100%; 926 | width: 0; 927 | border-radius: 15px; 928 | background-color: #212121; 929 | z-index: -1; 930 | transition: all 250ms 931 | } 932 | 933 | .custom-btn:hover { 934 | color: #e8e8e8; 935 | } 936 | 937 | .custom-btn:hover::before { 938 | width: 100%; 939 | } 940 | 941 | .icons { 942 | font-size: larger; 943 | } -------------------------------------------------------------------------------- /templates/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | Text Extractor Scan text from Image| OCR 10 | 11 | 13 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 |
23 | 24 | OCR 25 | 26 | 31 | 32 | 39 | 40 |
41 | 42 | 43 |
44 | 45 | {% if messages %} 46 | {% for msg in messages %} 47 |
49 |
50 | 51 | 53 | 54 |
55 | 56 |
57 |
58 | Error 59 |

{{msg}}

60 |
61 |
62 |
63 | {% endfor %} 64 | {% endif %} 65 | 66 | 67 |
68 |
69 |
70 |

Text Extractor

71 |

Extract or Scan text from images

72 |
73 | 74 | 75 |
76 |
77 | 81 |
82 | {% csrf_token %} 83 | 85 | 92 | 94 |
95 |
96 |
97 | 98 | 99 | 100 | {% if image %} 101 |
102 | 104 |
105 | {% endif %} 106 | 107 | 108 | 109 | {% if ocr %} 110 |
111 |

{{ ocr }}

112 | 115 |
116 | {% endif %} 117 | 118 |
119 | 120 | 121 |
122 |
123 |
124 |
125 | feature 127 |
128 | 129 | 145 | 146 |
147 |
148 |
150 | 151 |
152 |
153 |

Fast and Easy

154 |

Tesseract tests the text lines to determine whether 155 | they are fixed pitch. Where it finds fixed pitch text, Tesseract chops the words into 156 | characters using the pitch, and disables the chopper and associator on these words for 157 | the word recognition step.

158 | Learn More 159 | 161 | 162 | 163 | 164 |
165 |
166 |
167 |
169 | 171 | 172 | 173 | 174 | 175 |
176 |
177 |

Accuracy

178 |

Easily crop the text from images and copy it to 179 | clipboard, And its Results are Highly Accurate

180 | Learn More 181 | 183 | 184 | 185 | 186 |
187 |
188 | 189 |
190 |
191 |
192 | 193 | 194 | 231 | 232 | 233 | 234 | -------------------------------------------------------------------------------- /website/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ASACHIT/OCR-django-app/867a588ecd2c3b3bb5e55bf878779a86a6e9b16b/website/__init__.py -------------------------------------------------------------------------------- /website/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for website project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "website.settings") 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /website/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for website project. 3 | 4 | Generated by 'django-admin startproject' using Django 4.0.2. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/4.0/ref/settings/ 11 | """ 12 | 13 | from pathlib import Path 14 | 15 | # Build paths inside the project like this: BASE_DIR / 'subdir'. 16 | BASE_DIR = Path(__file__).resolve().parent.parent 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = "django-insecure-rvg_d+jt2!lv0ow6vmzocscl+010w2vdz^@rjgorz^=930o13b" 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = True 27 | 28 | ALLOWED_HOSTS = [] 29 | 30 | 31 | # Application definition 32 | 33 | INSTALLED_APPS = [ 34 | "django.contrib.admin", 35 | "django.contrib.auth", 36 | "django.contrib.contenttypes", 37 | "django.contrib.sessions", 38 | "django.contrib.messages", 39 | "django.contrib.staticfiles", 40 | ] 41 | 42 | MIDDLEWARE = [ 43 | "django.middleware.security.SecurityMiddleware", 44 | "django.contrib.sessions.middleware.SessionMiddleware", 45 | "django.middleware.common.CommonMiddleware", 46 | "django.middleware.csrf.CsrfViewMiddleware", 47 | "django.contrib.auth.middleware.AuthenticationMiddleware", 48 | "django.contrib.messages.middleware.MessageMiddleware", 49 | "django.middleware.clickjacking.XFrameOptionsMiddleware", 50 | ] 51 | 52 | ROOT_URLCONF = "website.urls" 53 | 54 | TEMPLATES = [ 55 | { 56 | "BACKEND": "django.template.backends.django.DjangoTemplates", 57 | "DIRS": [BASE_DIR / "templates"], 58 | "APP_DIRS": True, 59 | "OPTIONS": { 60 | "context_processors": [ 61 | "django.template.context_processors.debug", 62 | "django.template.context_processors.request", 63 | "django.contrib.auth.context_processors.auth", 64 | "django.contrib.messages.context_processors.messages", 65 | ], 66 | }, 67 | }, 68 | ] 69 | 70 | WSGI_APPLICATION = "website.wsgi.application" 71 | 72 | 73 | # Database 74 | # https://docs.djangoproject.com/en/4.0/ref/settings/#databases 75 | 76 | DATABASES = { 77 | "default": { 78 | "ENGINE": "django.db.backends.sqlite3", 79 | "NAME": BASE_DIR / "db.sqlite3", 80 | } 81 | } 82 | 83 | 84 | # Password validation 85 | # https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators 86 | 87 | AUTH_PASSWORD_VALIDATORS = [ 88 | { 89 | "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", 90 | }, 91 | { 92 | "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", 93 | }, 94 | { 95 | "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", 96 | }, 97 | { 98 | "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", 99 | }, 100 | ] 101 | 102 | 103 | # Internationalization 104 | # https://docs.djangoproject.com/en/4.0/topics/i18n/ 105 | 106 | LANGUAGE_CODE = "en-us" 107 | 108 | TIME_ZONE = "UTC" 109 | 110 | USE_I18N = True 111 | 112 | USE_TZ = True 113 | 114 | 115 | # Static files (CSS, JavaScript, Images) 116 | # https://docs.djangoproject.com/en/4.0/howto/static-files/ 117 | 118 | STATIC_URL = "static/" 119 | STATICFILES_DIRS = [BASE_DIR / "static"] 120 | 121 | # Default primary key field type 122 | # https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field 123 | 124 | DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" 125 | -------------------------------------------------------------------------------- /website/urls.py: -------------------------------------------------------------------------------- 1 | """website URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/4.0/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.contrib import admin 17 | from django.urls import include, path 18 | 19 | urlpatterns = [path("admin/", admin.site.urls), path("", include("ocr.urls"))] 20 | -------------------------------------------------------------------------------- /website/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for website project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "website.settings") 15 | 16 | application = get_wsgi_application() 17 | --------------------------------------------------------------------------------