Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Ocr Space Laravel Package

cdsmths/laravel-ocr-space

Laravel OCR Space is a clean wrapper for the OCR.space API, letting you extract text from images and PDFs in Laravel. Configure your API key, send files or URLs, and get parsed text responses with minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package via Composer. Laravel 5.5+ auto-discovers the service provider and OcrSpace facade; on older versions, register Cdsmths\LaravelOcrSpace\OcrSpaceServiceProvider in config/app.php and alias the facade.

composer require cdsmths/laravel-ocr-space
php artisan vendor:publish --tag=ocr-space-config

Add your key to .env:

OCR_SPACE_API_KEY=your_real_key

The OCR.space API ships a public helloworld key for smoke-testing — the package's config will default to it in some versions, so always set a real key before you ship anything; the shared key is heavily rate-limited and sometimes returns E101 errors under load.

Look first at: (1) config/ocr-space.php for endpoint, default language, and engine selection; (2) the facade class under src/ for the exact method names available — the API surface is small (parse-by-file, parse-by-URL, parse-base64) and reading the class is faster than guessing.

First use case — OCR a local image in a controller or artisan command:

use Cdsmths\LaravelOcrSpace\Facades\OcrSpace;

$result = OcrSpace::parseFile(storage_path('app/receipt.png'));

$text = $result->parsedText(); // or ->ParsedResults[0]->ParsedText depending on version

Run it once inside php artisan tinker with a small JPEG before wiring it into anything else — you'll confirm the key, network reachability, and the shape of the response object in one shot.

Implementation Patterns

Wrap calls in a dedicated service. Don't call the facade from controllers. Bind a small ReceiptOcrService that depends on OcrSpace, so you can swap engines, add retries, and test with a fake.

Parse by URL for remote files. If your uploads live on S3, generate a temporary signed URL and pass it to the URL-based method instead of downloading to /tmp and uploading again. This halves the latency and skips the free-tier 1 MB upload path entirely — OCR.space fetches the URL server-side.

Store the raw response, not just the text. OCR.space returns ParsedResults[] with ParsedText, TextOverlay.Lines[] (word bounding boxes when isOverlayRequired=true), ErrorMessage, and a top-level IsErroredOnProcessing flag. Persisting the JSON lets you backfill searchable PDFs, re-run layout analysis, or debug a bad parse months later. A json column plus a TEXT column for ParsedText is usually enough.

Pick OCREngine deliberately. Engine 1 is the legacy/default and is faster; engine 2 handles handwriting and dense receipts noticeably better but is ~2–3× slower and more restrictive on free quota. Make it a config value (e.g. OCR_ENGINE=2), not a hardcoded argument.

Use queue jobs for anything user-facing. A 5-page PDF at engine 2 routinely takes 20–40 seconds. Dispatch a ProcessOcrDocument job, broadcast a DocumentParsed event on success, and let the UI poll or subscribe. Set $timeout = 120 and $tries = 3 with a backoff — transient E500 / E101 responses from OCR.space are common enough that a single attempt will bite you.

Batch with Concurrency or chunked jobs. If you're ingesting a folder of scans, wrap in Bus::batch([...])->dispatch() rather than foreach — each OCR call is I/O-bound and Laravel's concurrency helper (Illuminate\Support\Facades\Concurrency) will finish a 20-image batch in a fraction of the wall time.

Language codes are ISO-639-1 or OCR.space's extended set. eng, deu, fra, spa, chi_sim, etc. Pass as an option per call and let it default from config; users frequently need spa + eng for mixed invoices (comma-separated works).

Saving searchable PDFs. With iscreatesearchablepdf=true and isOverlayRequired=true, the API returns a base64 PDF in the response. Decode it, put it on the private disk, and serve via a signed route — don't return the base64 blob in an API response.

Testing. Use Http::fake([...]) with a canned OCR.space payload. The package's parse methods ultimately hit api.ocr.space via Http::post, so the standard fake covers them. Assert on your own DTO, not on the raw array, or you'll be re-recorded fixtures every time the package bumps.

Gotchas and Tips

  • ParsedResults can be present but empty. Don't check $result->ParsedResults[0]->ParsedText without first confirming !$result->IsErroredOnProcessing and that count($result->ParsedResults) > 0. A blank image returns a successful response with an empty string, not an error — plan for "OCR succeeded but found nothing."
  • Free-tier size limits are real. 1 MB per image and 3 pages per PDF. The package won't pre-validate this for you; you'll get a cryptic E202/E300 back after a full round-trip. Add a Validator or rules() that checks $file->getSize() and page count before dispatching.
  • filetype must match the bytes. If you're uploading a PNG but declare filetype=jpg, OCR.space may still parse it, but the error messages when it doesn't are useless. Derive filetype from $file->getMimeType() or Str::afterLast($path, '.').
  • Config caching bites on deploy. If you config:cache in a deploy script but the key is read via env() inside the package class (rather than config()), the cached config will silently use the default helloworld key. Verify by logging the key prefix on boot in staging.
  • Timeout default is short. Laravel's Http client defaults to 30s. Engine 2 on a PDF frequently exceeds this. Publish the config and bump HTTP_TIMEOUT to 90+ for queues; leave it at 30 for interactive calls.
  • scale=true improves accuracy on small text but inflates the response. Bounding boxes come back in the scaled coordinate space — divide by the scale factor before drawing overlays on your UI, or your highlights will be offset.
  • Retry only specific codes. Retry on E101 (invalid key — usually transient overload on the shared key), E500, E501, timeouts. Do not retry on E200 (invalid params) or E300 (invalid file) — you'll just burn quota.
  • Debugging blank output. When OCR returns nothing useful, first test with isOverlayRequired=true and inspect the overlay — if TextOverlay.Lines is empty too, the image is genuinely blank or upside-down; add detectOrientation=true and re-run before assuming a code bug.
  • The facade is not a repository. It's a thin HTTP client. If you need caching, retry logic, quota tracking, or per-tenant API keys, that belongs in your service layer — the package won't grow those features for you, and forking it to add them creates upgrade friction.
  • Pin the version. This is a small package (125 stars) with infrequent, sometimes surprising releases. "cdsmths/laravel-ocr-space": "^1.0" rather than "*" — and read the diff before bumping, since facade method signatures are not covered by Laravel's deprecation cycle.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib