-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit c620890
Showing
12 changed files
with
635 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
.idea | ||
.DS_Store | ||
vendor | ||
composer.lock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) Jonas Van Assche | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
# Analyze images with Google Cloud Vision | ||
|
||
Easy way to analyze images with Laravel and Google Cloud Vision. Check their [demo](https://cloud.google.com/vision/docs/drag-and-drop) to see what it can do. | ||
|
||
## Features | ||
|
||
### Optical Character Recognition | ||
|
||
Convert an image or PDF document to text | ||
|
||
```php | ||
$path = $request->file('file')->getRealPath(); | ||
|
||
$text = Vision::getFullText($path); | ||
``` | ||
|
||
### Annotate image | ||
|
||
Get annotations of your image for one or more Vision [features](https://cloud.google.com/vision/docs/features). | ||
|
||
Make sure you extract the same type of annotations from the response as the feature you requested. (eg: `Type::FACE_DETECTION` -> `$response->getFaceAnnotations()`) | ||
|
||
```php | ||
use Google\Cloud\Vision\V1\Feature\Type; | ||
|
||
$path = $request->file('file')->getRealPath(); | ||
|
||
$features = [Type::FACE_DETECTION]; | ||
|
||
$response = Vision::annotateImage($path, $features); | ||
|
||
$faces = $response->getFaceAnnotations(); | ||
``` | ||
|
||
## Installation | ||
|
||
### Laravel | ||
|
||
This package can be installed through Composer. | ||
|
||
```bash | ||
composer require jonasva/laravel-vision | ||
``` | ||
|
||
Publish config | ||
```bash | ||
php artisan vendor:publish --provider="Jonasva\Vision\VisionServiceProvider" | ||
``` | ||
|
||
### Google Cloud Console | ||
|
||
In order to use the Google Cloud Vision API, you'll need to setup a couple of things in Google Cloud Console. | ||
|
||
1. Go to [Cloud Console](https://console.cloud.google.com) and select a project (or create a new one). | ||
|
||
2. Add your project ID to your env file under `GOOGLE_CLOUD_PROJECT` | ||
|
||
3. Go to the API library and find "Cloud Vision API". Click "Enable" | ||
|
||
4. Create a service account + credentials file for Cloud Vision API. Place the credentials file in your project, and add the path (relative to your project root) to it in your env file under `GOOGLE_APPLICATION_CREDENTIALS`. (see `config/vision.php` file for more details.) | ||
|
||
5. Setup a Google Cloud Storage bucket and make sure your newly created Cloud Vision service account user has read/write permissions to it. This bucket will be used to process PDF and TIFF type files. | ||
|
||
6. Add the bucket name in your env under `GOOGLE_CLOUD_BUCKET` | ||
|
||
7. I suggest setting up a lifecycle rule for your bucket to automatically remove files older than 1 day. | ||
|
||
## Pricing | ||
|
||
Make sure you take a look at Cloud Vision API's [pricing](https://cloud.google.com/vision/pricing), as it's not an entirely free service. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
{ | ||
"name": "jonasva/laravel-vision", | ||
"description": "A Laravel 5 package to interact with Google Cloud Vision.", | ||
"keywords": [ | ||
"laravel", | ||
"ocr", | ||
"vision", | ||
"google", | ||
"gcloud" | ||
], | ||
"homepage": "https://github.com/jonasva/laravel-vision", | ||
"license": "MIT", | ||
"authors": [ | ||
{ | ||
"name": "Jonas Van Assche", | ||
"email": "[email protected]" | ||
} | ||
], | ||
"require": { | ||
"php" : "^7.2", | ||
"illuminate/support": "^5.4", | ||
"google/cloud-storage": "^1.3", | ||
"google/cloud-vision": "^0.22.0" | ||
}, | ||
"autoload": { | ||
"psr-4": { | ||
"Jonasva\\Vision\\": "src" | ||
} | ||
}, | ||
"extra": { | ||
"laravel": { | ||
"providers": [ | ||
"Jonasva\\Vision\\VisionServiceProvider" | ||
], | ||
"aliases": { | ||
"Vision": "Jonasva\\Vision\\VisionFacade" | ||
} | ||
} | ||
}, | ||
"config": { | ||
"sort-packages": true | ||
}, | ||
"minimum-stability": "stable", | ||
"prefer-stable": true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
<?php | ||
|
||
return [ | ||
|
||
/* | ||
|-------------------------------------------------------------------------- | ||
| Google Cloud project ID | ||
|-------------------------------------------------------------------------- | ||
| | ||
| Your API project's ID from Google Cloud Console | ||
| https://console.cloud.google.com | ||
| | ||
*/ | ||
|
||
'google_cloud_project_id' => env('GOOGLE_CLOUD_PROJECT'), | ||
|
||
/* | ||
|-------------------------------------------------------------------------- | ||
| Google application credentials path | ||
|-------------------------------------------------------------------------- | ||
| | ||
| Path of your the credentials file used to access the API | ||
| (path is relative to your project root eg: credentials/vision/demo.json) | ||
| | ||
*/ | ||
|
||
'google_app_credentials_path' => env('GOOGLE_APPLICATION_CREDENTIALS'), | ||
|
||
/* | ||
|-------------------------------------------------------------------------- | ||
| Google Cloud Storage bucket | ||
|-------------------------------------------------------------------------- | ||
| | ||
| Storage bucket used to upload and batch process document type files. | ||
| Make sure your API user has read and write access to this bucket | ||
| | ||
| Tip: setup a lifecycle rule for this bucket to automatically delete files older | ||
| than one day. That way you'll save on storage costs of useless files. | ||
| | ||
*/ | ||
|
||
'google_cloud_storage' => [ | ||
'bucket' => env('GOOGLE_CLOUD_BUCKET'), | ||
'raw_prefix' => 'raw/', | ||
'processed_prefix' => 'processed/', | ||
], | ||
|
||
/* | ||
|-------------------------------------------------------------------------- | ||
| Document batch size | ||
|-------------------------------------------------------------------------- | ||
| | ||
| Amount of pages per batch for text detection on documents | ||
| | ||
*/ | ||
'document_batch_size' => 3, | ||
|
||
/* | ||
|-------------------------------------------------------------------------- | ||
| Maximum file size | ||
|-------------------------------------------------------------------------- | ||
| | ||
| Maximum file size in Bytes of a single image or document | ||
| | ||
*/ | ||
'max_file_size' => 10 * 1000 * 1000, // 10 MB | ||
|
||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<?php | ||
|
||
namespace Jonasva\Vision\Exceptions; | ||
|
||
use Exception; | ||
|
||
class NotSupportedException extends Exception | ||
{ | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
<?php | ||
|
||
namespace Jonasva\Vision; | ||
|
||
use Google\Cloud\Vision\V1\AnnotateImageResponse; | ||
use Illuminate\Support\Facades\File; | ||
use Jonasva\Vision\Exceptions\NotSupportedException; | ||
|
||
class Vision | ||
{ | ||
protected $config; | ||
|
||
protected $visionImageClient; | ||
|
||
protected $visionDocumentClient; | ||
|
||
/** | ||
* Vision constructor. | ||
* @param array $config | ||
*/ | ||
public function __construct(array $config) | ||
{ | ||
$this->config = $config; | ||
} | ||
|
||
/** | ||
* @param string $filePath | ||
* @param array $languageHints | ||
* @return string | ||
* @throws NotSupportedException | ||
*/ | ||
public function getFullText(string $filePath, array $languageHints = []): string | ||
{ | ||
$this->checkFileSize($filePath); | ||
|
||
$mimeType = File::mimeType($filePath); | ||
$fileType = $this->detectFileType($mimeType); | ||
|
||
if ($fileType == 'image') { | ||
return $this->getVisionImageClient()->getFullText($filePath, $languageHints); | ||
} | ||
elseif ($fileType == 'document') { | ||
return $this->getVisionDocumentClient()->getFullText($filePath, $mimeType, $languageHints); | ||
} | ||
} | ||
|
||
/** | ||
* @param string $filePath | ||
* @param array $features | ||
* @param array $options | ||
* @return AnnotateImageResponse | ||
* @throws NotSupportedException | ||
*/ | ||
public function annotateImage(string $filePath, array $features, array $options = []): AnnotateImageResponse | ||
{ | ||
$this->checkFileSize($filePath); | ||
$this->checkIsImage($filePath); | ||
|
||
return $this->getVisionImageClient()->annotateImage($filePath, $features, $options); | ||
} | ||
|
||
/** | ||
* @param string $filePath | ||
* @throws NotSupportedException | ||
*/ | ||
protected function checkIsImage(string $filePath): void | ||
{ | ||
$mimeType = File::mimeType($filePath); | ||
$fileType = $this->detectFileType($mimeType); | ||
|
||
if ($fileType !== 'image') { | ||
throw new NotSupportedException($mimeType . ' file type not supported.'); | ||
} | ||
} | ||
|
||
/** | ||
* @param string $filePath | ||
* @throws NotSupportedException | ||
*/ | ||
protected function checkFileSize(string $filePath): void | ||
{ | ||
$size = File::size($filePath); | ||
|
||
if ($size > $this->config['max_file_size']) { | ||
throw new NotSupportedException('Maximum file size of ' . $this->config['max_file_size'] . ' Bytes exceeded'); | ||
} | ||
} | ||
|
||
/** | ||
* @param string $mimeType | ||
* @return string | ||
* @throws NotSupportedException | ||
*/ | ||
protected function detectFileType(string $mimeType): string | ||
{ | ||
if (in_array($mimeType, ['image/jpeg', 'image/png', 'image/gif', 'image/bmp', 'image/webp', 'image/vnd.microsoft.icon'])) { | ||
return 'image'; | ||
} | ||
elseif (in_array($mimeType, ['application/pdf', 'image/tiff'])) { | ||
return 'document'; | ||
} | ||
else { | ||
throw new NotSupportedException($mimeType . ' file type not supported.'); | ||
} | ||
} | ||
|
||
/** | ||
* @return VisionImageClient | ||
*/ | ||
protected function getVisionImageClient(): VisionImageClient | ||
{ | ||
if (!$this->visionImageClient) { | ||
$this->visionImageClient = new VisionImageClient($this->config); | ||
} | ||
|
||
return $this->visionImageClient; | ||
} | ||
|
||
/** | ||
* @return VisionDocumentClient | ||
*/ | ||
protected function getVisionDocumentClient(): VisionDocumentClient | ||
{ | ||
if (!$this->visionDocumentClient) { | ||
$this->visionDocumentClient = new VisionDocumentClient($this->config); | ||
} | ||
|
||
return $this->visionDocumentClient; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
<?php | ||
|
||
namespace Jonasva\Vision; | ||
|
||
use Google\Cloud\Vision\V1\ImageAnnotatorClient; | ||
use Illuminate\Support\Facades\File; | ||
|
||
class VisionClient | ||
{ | ||
protected $imageAnnotatorClient; | ||
|
||
protected $config; | ||
|
||
/** | ||
* VisionClient constructor. | ||
* @param array $config | ||
* @throws \Google\ApiCore\ValidationException | ||
*/ | ||
public function __construct(array $config) | ||
{ | ||
$this->config = $config; | ||
|
||
$this->imageAnnotatorClient = new ImageAnnotatorClient([ | ||
'credentials' => base_path($this->config['google_app_credentials_path']), | ||
]); | ||
} | ||
|
||
/** | ||
* @param string $filePath | ||
* @return string | ||
*/ | ||
protected function getFile(string $filePath): string | ||
{ | ||
return File::get($filePath); | ||
} | ||
} |
Oops, something went wrong.