-
Notifications
You must be signed in to change notification settings - Fork 32
Expand file tree
/
Copy pathGoogleCloudVisionEngine.php
More file actions
109 lines (94 loc) · 3.43 KB
/
GoogleCloudVisionEngine.php
File metadata and controls
109 lines (94 loc) · 3.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
<?php
declare( strict_types=1 );
namespace App\Engine;
use App\Exception\OcrException;
use Google\Cloud\Vision\V1\ImageAnnotatorClient;
use Google\Cloud\Vision\V1\ImageContext;
use Google\Cloud\Vision\V1\TextAnnotation;
use Imagine\Gd\Imagine;
use Krinkle\Intuition\Intuition;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class GoogleCloudVisionEngine extends EngineBase {
/** @var string The API key. */
protected $key;
/** @var ImageAnnotatorClient */
protected $imageAnnotator;
/**
* GoogleCloudVisionEngine constructor.
* @param string $keyFile Filesystem path to the credentials JSON file.
* @param Intuition $intuition
* @param string $projectDir
* @param HttpClientInterface $httpClient
*/
public function __construct(
string $keyFile,
Intuition $intuition,
string $projectDir,
HttpClientInterface $httpClient
) {
parent::__construct( $intuition, $projectDir, $httpClient );
if ( !empty( $keyFile ) ) {
$this->imageAnnotator = new ImageAnnotatorClient( [ 'credentials' => $keyFile ] );
}
}
/**
* @inheritDoc
*/
public static function getId(): string {
return 'google';
}
/**
* @inheritDoc
* @throws OcrException
*/
public function getResult(
string $imageUrl,
string $invalidLangsMode,
array $crop,
?array $langs = null,
int $rotate = 0
): EngineResult {
$this->checkImageUrl( $imageUrl );
[ $validLangs, $invalidLangs ] = $this->filterValidLangs( $langs, $invalidLangsMode );
$imageContext = new ImageContext();
if ( $validLangs ) {
$imageContext->setLanguageHints( $validLangs );
}
if ( !$this->imageAnnotator ) {
throw new OcrException( 'google-error', [ 'Key for Google OCR engine is missing' ] );
}
$image = $this->getImage( $imageUrl, $crop );
if ( $rotate !== 0 ) {
$imagine = new Imagine();
$loaded = $imagine->load( $image->getData() ?: file_get_contents( $image->getUrl() ) );
$loaded->rotate( $rotate );
$image->setData( $loaded->get( 'jpg' ) );
}
$imageUrlOrData = $image->hasData() ? $image->getData() : $image->getUrl();
$response = $this->imageAnnotator->textDetection( $imageUrlOrData, [ 'imageContext' => $imageContext ] );
// Re-try with direct upload if the error returned is something similar to
// "The URL does not appear to be accessible by us. Please double check or download the content and pass it in."
// There doesn't seem to be a specific error code for this (it is usually 3, but that's also used for other
// things), so it seems like we have to check the actual message string.
if ( $response->getError()
&& stripos( $response->getError()->getMessage(), 'download the content and pass it in' ) !== false
) {
$image = $this->getImage( $imageUrl, $crop, self::DO_DOWNLOAD_IMAGE );
if ( $rotate !== 0 ) {
$imagine = new Imagine();
$loaded = $imagine->load( $image->getData() );
$loaded->rotate( $rotate );
$image->setData( $loaded->get( 'jpg' ) );
}
$response = $this->imageAnnotator->textDetection( $image->getData(), [ 'imageContext' => $imageContext ] );
}
// Other errors, report to the user.
if ( $response->getError() ) {
throw new OcrException( 'google-error', [ $response->getError()->getMessage() ] );
}
$annotation = $response->getFullTextAnnotation();
$resText = $annotation instanceof TextAnnotation ? $annotation->getText() : '';
$warnings = $invalidLangs ? [ $this->getInvalidLangsWarning( $invalidLangs ) ] : [];
return new EngineResult( $resText, $warnings );
}
}