diff --git a/google_vision.module b/google_vision.module index 6d26c90..51c50c5 100755 --- a/google_vision.module +++ b/google_vision.module @@ -6,7 +6,7 @@ use Drupal\Core\Form\FormStateInterface; use Drupal\field\FieldConfigInterface; -use Drupal\google_vision\Connector; +use Drupal\google_vision\GoogleVisionAPI; /** * Implements hook_entity_presave(). @@ -67,7 +67,7 @@ function google_vision_file_entity_add_labels($file, $field, $vid) { // Try to retrieve file URI. $file_uri = $file->getFileUri(); if ($filepath = \Drupal::service('file_system')->realpath($file_uri)) { - $data = Connector::makeRequestForLabels($filepath); + $data = \Drupal::service('google_vision.api')->labelDetection($filepath); // If we have retrieved labels. if (!empty($data['responses'][0]['labelAnnotations'])) { $labels = []; diff --git a/google_vision.services.yml b/google_vision.services.yml new file mode 100755 index 0000000..91ddb31 --- /dev/null +++ b/google_vision.services.yml @@ -0,0 +1,4 @@ +services: + google_vision.api: + class: Drupal\google_vision\GoogleVisionAPI + arguments: ['@config.factory', '@http_client'] diff --git a/src/Connector.php b/src/Connector.php deleted file mode 100755 index 1d03323..0000000 --- a/src/Connector.php +++ /dev/null @@ -1,61 +0,0 @@ -get('config.factory')->getEditable('google_vision.settings'); - $api_key = $config->get('api_key'); - if (!$api_key) { - return FALSE; - } - - // It looks pretty dirty. I hope that in future it will be implemented in Google SDK - // and we will be able to avoid this approach. - $encoded_image = base64_encode(file_get_contents($filepath)); - - // Prepare JSON. - $data = '{ - "requests":[ - { - "image":{ - "content":"' . $encoded_image . '" - }, - "features":[ - { - "type":"LABEL_DETECTION", - "maxResults":5 - } - ] - } - ] - }'; - - $ch = curl_init('https://vision.googleapis.com/v1/images:annotate?key=' . $api_key); - curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); - curl_setopt($ch, CURLOPT_POSTFIELDS, $data); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_HTTPHEADER, array( - 'Content-Type: application/json', - 'Content-Length: ' . strlen($data), - ) - ); - - $result = Json::decode(curl_exec($ch)); - if (empty($result['error'])) { - return $result; - } - return FALSE; - } -} diff --git a/src/GoogleVisionAPI.php b/src/GoogleVisionAPI.php new file mode 100755 index 0000000..814a1d7 --- /dev/null +++ b/src/GoogleVisionAPI.php @@ -0,0 +1,360 @@ +configFactory = $config_factory; + $this->httpClient = $http_client; + $this->apiKey = $this->configFactory->get('google_vision.settings')->get('api_key'); + } + + /** + * Function to make request through httpClient service. + * + * @param $data. + * The object to be passed during the API call. + * + * @return An array obtained in response from the API call. + */ + protected function postRequest($data) { + $url = static::APIEndpoint . $this->apiKey; + $response = $this->httpClient->post($url, [ + RequestOptions::JSON => $data, + RequestOptions::HEADERS => ['Content-Type' => 'application/json'], + ]); + + return Json::decode($response->getBody()); + } + + /** + * Function to retrieve labels for given image. + * + * @param string $filepath. + * + * @return Array|bool. + */ + public function labelDetection($filepath) { + if (!$this->apiKey) { + return FALSE; + } + + // It looks pretty dirty. I hope that in future it will be implemented in Google SDK + // and we will be able to avoid this approach. + $encoded_image = base64_encode(file_get_contents($filepath)); + + // Prepare JSON. + $data = [ + 'requests' => [ + [ + 'image' => [ + 'content' => $encoded_image + ], + 'features' => [ + [ + 'type' => 'LABEL_DETECTION', + 'maxResults' => 5 + ], + ], + ], + ], + ]; + + $result = $this->postRequest($data); + if (empty($result['error'])) { + return $result; + } + return FALSE; + + } + + /** + * Function to detect landmarks within a given image. + * + * @param string $filepath. + * + * @return Array|bool. + */ + public function landmarkDetection($filepath) { + if (!$this->apiKey) { + return FALSE; + } + + // It looks pretty dirty. I hope that in future it will be implemented in Google SDK + // and we will be able to avoid this approach. + $encoded_image = base64_encode(file_get_contents($filepath)); + + // Prepare JSON. + $data = [ + 'requests' => [ + [ + 'image' => [ + 'content' => $encoded_image + ], + 'features' => [ + [ + 'type' => 'LANDMARK_DETECTION', + 'maxResults' => 2 + ], + ], + ], + ], + ]; + + $result = $this->postRequest($data); + if (empty($result['error'])) { + return $result; + } + return FALSE; + + } + + /** + * Function to detect logos of famous brands within a given image. + * + * @param string $filepath. + * + * @return Array|bool. + */ + public function logoDetection($filepath) { + if (!$this->apiKey) { + return FALSE; + } + + // It looks pretty dirty. I hope that in future it will be implemented in Google SDK + // and we will be able to avoid this approach. + $encoded_image = base64_encode(file_get_contents($filepath)); + + // Prepare JSON. + $data = [ + 'requests' => [ + [ + 'image' => [ + 'content' => $encoded_image + ], + 'features' => [ + [ + 'type' => 'LOGO_DETECTION', + 'maxResults' => 2 + ], + ], + ], + ], + ]; + + $result = $this->postRequest($data); + if (empty($result['error'])) { + return $result; + } + return FALSE; + + } + + /** + * Function to detect explicit content within a given image. + * + * @param string $filepath. + * + * @return Array|bool. + */ + public function safeSearchDetection($filepath) { + if (!$this->apiKey) { + return FALSE; + } + + // It looks pretty dirty. I hope that in future it will be implemented in Google SDK + // and we will be able to avoid this approach. + $encoded_image = base64_encode(file_get_contents($filepath)); + + // Prepare JSON. + $data = [ + 'requests' => [ + [ + 'image' => [ + 'content' => $encoded_image + ], + 'features' => [ + [ + 'type' => 'SAFE_SEARCH_DETECTION', + 'maxResults' => 1 + ], + ], + ], + ], + ]; + + $result = $this->postRequest($data); + if (empty($result['error'])) { + return $result; + } + return FALSE; + + } + + /** + * Function to retrieve texts for given image. + * + * @param string $filepath. + * + * @return Array|bool. + */ + public function opticalCharacterRecognition($filepath) { + if (!$this->apiKey) { + return FALSE; + } + + // It looks pretty dirty. I hope that in future it will be implemented in Google SDK + // and we will be able to avoid this approach. + $encoded_image = base64_encode(file_get_contents($filepath)); + + // Prepare JSON. + $data = [ + 'requests' => [ + [ + 'image' => [ + 'content' => $encoded_image + ], + 'features' => [ + [ + 'type' => 'TEXT_DETECTION', + 'maxResults' => 10 + ], + ], + ], + ], + ]; + + $result = $this->postRequest($data); + if (empty($result['error'])) { + return $result; + } + return FALSE; + + } + + /** + * Function to fetch faces from a given image. + * + * @param string $filepath. + * + * @return Array|bool. + */ + public function faceDetection($filepath) { + if (!$this->apiKey) { + return FALSE; + } + + // It looks pretty dirty. I hope that in future it will be implemented in Google SDK + // and we will be able to avoid this approach. + $encoded_image = base64_encode(file_get_contents($filepath)); + + // Prepare JSON. + $data = [ + 'requests' => [ + [ + 'image' => [ + 'content' => $encoded_image + ], + 'features' => [ + [ + 'type' => 'FACE_DETECTION', + 'maxResults' => 25 + ], + ], + ], + ], + ]; + + $result = $this->postRequest($data); + if (empty($result['error'])) { + return $result; + } + return FALSE; + + } + + /** + * Function to retrieve image attributes for given image. + * + * @param string $filepath. + * + * @return Array|bool. + */ + public function imageAttributesDetection($filepath) { + if (!$this->apiKey) { + return FALSE; + } + + // It looks pretty dirty. I hope that in future it will be implemented in Google SDK + // and we will be able to avoid this approach. + $encoded_image = base64_encode(file_get_contents($filepath)); + + // Prepare JSON. + $data = [ + 'requests' => [ + [ + 'image' => [ + 'content' => $encoded_image + ], + 'features' => [ + [ + 'type' => 'IMAGE_PROPERTIES', + 'maxResults' => 5 + ], + ], + ], + ], + ]; + + $result = $this->postRequest($data); + if (empty($result['error'])) { + return $result; + } + return FALSE; + + } +}