diff --git a/config/schema/google_vision.schema.yml b/config/schema/google_vision.schema.yml
index bcb997e..884df2a 100644
--- a/config/schema/google_vision.schema.yml
+++ b/config/schema/google_vision.schema.yml
@@ -13,3 +13,11 @@ google_vision.settings:
     api_key:
       type: string
       label: 'Google Vision Api Key'
+
+field.field.*.*.*.third_party.google_vision:
+  type: mapping
+  label: 'Per-image field safe search settings'
+  mapping:
+    safe_search:
+      type: boolean
+      label: 'Safe Search'
diff --git a/google_vision.module b/google_vision.module
index a4c567c..4855e94 100644
--- a/google_vision.module
+++ b/google_vision.module
@@ -7,6 +7,11 @@
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\field\FieldConfigInterface;
 use Drupal\google_vision\GoogleVisionAPI;
+use Drupal\field\FieldStorageConfigInterface;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\Core\Field\FieldItemListInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
 
 /**
  * Implements hook_entity_presave().
@@ -49,18 +54,50 @@ function google_vision_form_field_config_edit_form_alter(&$form, \Drupal\Core\Fo
       '#default_value' => !empty($settings['google_vision']) ? $settings['google_vision'] : FALSE,
     ];
 
-    $form['#entity_builders'][] = 'google_vision_form_field_config_form_builder';
+    $form['#entity_builders'][] = 'google_vision_form_field_config_form_taxonomy_builder';
+  }
+
+  if($field_entity->getType() == 'image') {
+    $settings = $form_state->getFormObject()->getEntity()->getThirdPartySettings('google_vision');
+    $form['safe_search'] = [
+      '#type' => 'checkbox',
+      '#title' => t('Enable Safe Search'),
+      '#description' => t('Detects and avoids explicit contents.'),
+      '#default_value' => !empty($settings['safe_search']) ? $settings['safe_search'] : FALSE,
+    ];
+
+    $form['#entity_builders'][] = 'google_vision_form_field_config_form_image_builder';
   }
 }
 
 /**
- * Form builder to save the settings.
+ * Form builder to save the settings for entity reference.
  */
-function google_vision_form_field_config_form_builder($entity_type, FieldConfigInterface $type, &$form, FormStateInterface $form_state) {
+function google_vision_form_field_config_form_taxonomy_builder($entity_type, FieldConfigInterface $type, &$form, FormStateInterface $form_state) {
   $type->setThirdPartySetting('google_vision', 'google_vision', $form_state->getValue('google_vision'));
 }
 
 /**
+ * Implements hook_entity_bundle_field_info_alter().
+ */
+function google_vision_entity_bundle_field_info_alter(&$fields, EntityTypeInterface $entity_type, $bundle) {
+  if ($entity_type->id() == 'node') {
+    foreach ($fields as $field) {
+      if ($field->getType() == 'image') {
+        $fields[$field->getName()]->addConstraint('SafeSearch');
+      }
+    }
+  }
+}
+
+/**
+ * Form builder to save the settings for images.
+ */
+function google_vision_form_field_config_form_image_builder($entity_type, FieldConfigInterface $type, &$form, FormStateInterface $form_state) {
+  $type->setThirdPartySetting('google_vision', 'safe_search', $form_state->getValue('safe_search'));
+}
+
+/**
  * Try to get and add labels for the file entity.
  */
 function google_vision_file_entity_add_labels($file, $field, $vid) {
diff --git a/src/Plugin/Validation/Constraint/SafeSearchConstraint.php b/src/Plugin/Validation/Constraint/SafeSearchConstraint.php
new file mode 100755
index 0000000..9bf064d
--- /dev/null
+++ b/src/Plugin/Validation/Constraint/SafeSearchConstraint.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace Drupal\google_vision\Plugin\Validation\Constraint;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * Checks that the node is assigned only a "leaf" term in the forum taxonomy.
+ *
+ * @Constraint(
+ *   id = "SafeSearch",
+ *   label = @Translation("Safe Search", context = "Validation"),
+ * )
+ */
+class SafeSearchConstraint extends Constraint {
+
+  public $message = 'This image contains explicit content and will not be saved.';
+}
diff --git a/src/Plugin/Validation/Constraint/SafeSearchConstraintValidator.php b/src/Plugin/Validation/Constraint/SafeSearchConstraintValidator.php
new file mode 100755
index 0000000..c49d7de
--- /dev/null
+++ b/src/Plugin/Validation/Constraint/SafeSearchConstraintValidator.php
@@ -0,0 +1,85 @@
+<?php
+
+namespace Drupal\google_vision\Plugin\Validation\Constraint;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Drupal\Core\Field\FieldItemListInterface;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\file\FileInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
+use Drupal\google_vision\GoogleVisionAPI;
+use Drupal\Core\File\FileSystemInterface;
+
+/**
+ * Validates the SafeSearch constraint.
+ */
+class SafeSearchConstraintValidator extends ConstraintValidator implements ContainerInjectionInterface {
+
+  /**
+   * The Google Vision API.
+   *
+   * @var \Drupal\google_vision\GoogleVisionAPI.
+   */
+  protected $googleVisionAPI;
+
+  /**
+   * The file system.
+   *
+   * @var \Drupal\Core\File\FileSystemInterface.
+   */
+  protected $fileSystem;
+
+  /**
+   * Constructs a SafeSearchConstraintValidator object.
+   *
+   * @param \Drupal\google_vision\GoogleVisionAPI $googleVisionAPI
+   *  The Google Vision API object.
+   *
+   * @param \Drupal\Core\File\FileSystemInterface $fileSystem
+   *  The File System object.
+   */
+  public function __construct(GoogleVisionAPI $google_vision, FileSystemInterface $file_system) {
+    $this->googleVisionAPI = $google_vision;
+    $this->fileSystem = $file_system;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validate($data, Constraint $constraint) {
+    $field_def = $data->getFieldDefinition();
+    $settings = $field_def->getThirdPartySettings('google_vision');
+    // if the Safe Search detection is on.
+    if (!empty($settings['safe_search'])) {
+      // if the image is uploaded.
+      if (!empty($data->getValue('target_id'))) {
+        // Retrieve the file uri.
+        $file_uri = $data->entity->getFileUri();
+        if ($filepath = $this->fileSystem->realpath($file_uri)) {
+          $result = $this->googleVisionAPI->safeSearchDetection($filepath);
+          if (!empty($result['responses'][0]['safeSearchAnnotation'])) {
+            $adult = $result['responses'][0]['safeSearchAnnotation']['adult'];
+            $likelihood = array('POSSIBLE', 'LIKELY', 'VERY_LIKELY');
+            // if the image has explicit content.
+            if (in_array($adult, $likelihood)) {
+              $this->context->addViolation($constraint->message);
+            }
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static (
+      $container->get('google_vision.api'),
+      $container->get('file_system')
+    );
+  }
+}
diff --git a/src/Tests/SafeSearchConstraintValidationTest.php b/src/Tests/SafeSearchConstraintValidationTest.php
new file mode 100644
index 0000000..764ec71
--- /dev/null
+++ b/src/Tests/SafeSearchConstraintValidationTest.php
@@ -0,0 +1,214 @@
+<?php
+
+namespace Drupal\google_vision\Tests;
+
+use Drupal\Core\Url;
+use Drupal\node\Entity\Node;
+use Drupal\field\Entity\FieldConfig;
+use Drupal\Core\Field\FieldConfigBase;
+use Drupal\simpletest\WebTestBase;
+use Drupal\field\Entity\FieldStorageConfig;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\Core\Field\FieldItemListInterface;
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Drupal\google_vision\GoogleVisionAPI;
+
+/**
+ * Tests to verify whether the Safe Search Constraint Validation works
+ * correctly.
+ *
+ * @group google_vision
+ */
+class SafeSearchConstraintValidationTest extends WebTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['google_vision', 'node', 'image', 'field_ui', 'field', 'google_vision_test'];
+
+  /**
+   * A user with permission to create content and upload images.
+   *
+   * @var object
+   */
+  protected $adminUser;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    //Create custom content type.
+    $contentType = $this->drupalCreateContentType(array('type' => 'test_images', 'name' => 'Test Images'));
+    // Creates administrative user.
+    $this->adminUser = $this->drupalCreateUser(array('administer google vision','create test_images content', 'access content',  'access administration pages', 'administer node fields', 'administer nodes', 'administer node display')
+    );
+    $this->drupalLogin($this->adminUser);
+
+    //Set the API Key.
+    /*\Drupal::configFactory()->getEditable('google_vision.settings')->set('api_key', 'AIzaSyAtuc_LOB70imSYsT0TXFUNnNlMqiDoyP8')->save();
+    $this->drupalGet(Url::fromRoute('google_vision.settings'));
+    $this->assertResponse(200);
+    $this->assertFieldByName('api_key', 'AIzaSyAtuc_LOB70imSYsT0TXFUNnNlMqiDoyP8', 'The key has been saved');
+    */
+  }
+
+  /**
+   * Create a new image field.
+   *
+   * @param string $name
+   *   The name of the new field (all lowercase), exclude the "field_" prefix.
+   * @param string $type_name
+   *   The node type that this field will be added to.
+   * @param array $storage_settings
+   *   A list of field storage settings that will be added to the defaults.
+   * @param array $field_settings
+   *   A list of instance settings that will be added to the instance defaults.
+   * @param array $widget_settings
+   *   Widget settings to be added to the widget defaults.
+   * @param array $formatter_settings
+   *   Formatter settings to be added to the formatter defaults.
+   * @param string $description
+   *   A description for the field.
+   */
+  public function createImageField($name, $type_name, $storage_settings = array(), $field_settings = array(), $widget_settings = array(), $formatter_settings = array(), $description = '') {
+    FieldStorageConfig::create(array(
+      'field_name' => $name,
+      'entity_type' => 'node',
+      'type' => 'image',
+      'settings' => $storage_settings,
+      'cardinality' => 1,
+    ))->save();
+
+    $field_config = FieldConfig::create([
+      'field_name' => $name,
+      'label' => $name,
+      'entity_type' => 'node',
+      'bundle' => $type_name,
+      'settings' => $field_settings,
+      'description' => $description,
+    ])->addConstraint('SafeSearch');
+    $field_config->save();
+
+    entity_get_form_display('node', $type_name, 'default')
+      ->setComponent($name, array(
+        'type' => 'image_image',
+        'settings' => $widget_settings,
+      ))
+      ->save();
+
+    entity_get_display('node', $type_name, 'default')
+      ->setComponent($name, array(
+        'type' => 'image',
+        'settings' => $formatter_settings,
+      ))
+      ->save();
+
+    return $field_config;
+  }
+
+  /**
+   * Get the field id of the image field formed.
+   */
+  public function getImageFieldId() {
+    // Create an image field and add an field to the custom content type.
+    $storage_settings['default_image'] = array(
+      'uuid' => 1,
+      'alt' => '',
+      'title' => '',
+      'width' => 0,
+      'height' => 0,
+    );
+    $field_settings['default_image'] = array(
+      'uuid' => 1,
+      'alt' => '',
+      'title' => '',
+      'width' => 0,
+      'height' => 0,
+    );
+    $widget_settings = array(
+      'preview_image_style' => 'medium',
+    );
+    $field = $this->createImageField('images', 'test_images', $storage_settings, $field_settings, $widget_settings);
+
+    $field_id = $field->id();
+    return $field_id;
+  }
+
+  /**
+   * Upload an image to the node of type test_images and create the node.
+   *
+   * @param The image file $image
+   *   A file object representing the image to upload.
+   */
+  function uploadImageFile($image) {
+    $edit = array(
+      'title[0][value]' => $this->randomMachineName(),
+      'files[images_0]' => drupal_realpath($image->getFileUri()),
+    );
+
+    $this->drupalPostForm('node/add/test_images' , $edit, t('Save and publish'));
+
+    // Add alt text.
+    $this->drupalPostForm(NULL, ['images[0][alt]' => $this->randomMachineName()], t('Save and publish'));
+
+    // Retrieve ID of the newly created node from the current URL.
+    $matches = array();
+    preg_match('/node\/([0-9]+)/', $this->getUrl(), $matches);
+    return isset($matches[1]) ? $matches[1] : FALSE;
+  }
+
+  /**
+   * Test to ensure explicit content is detected when Safe Search is enabled.
+   */
+  public function testSafeSearchConstraint() {
+    //Get the image field id.
+    $field_id = $this->getImageFieldId();
+
+    //Enable the Safe Search.
+    $edit = array(
+      'safe_search' => 1,
+    );
+    $this->drupalPostForm("admin/structure/types/manage/test_images/fields/$field_id", $edit, t('Save settings'));
+
+    //Ensure that the safe search is enabled.
+    $this->drupalGet("admin/structure/types/manage/test_images/fields/$field_id");
+
+    // Get an image with explicit content from web.
+    $image = file_get_contents('http://www.menshealth.com/sites/menshealth.com/files/articles/2015/12/man-snoring.jpg'); // string
+    $file = file_save_data($image, 'public://explicit.jpg', FILE_EXISTS_REPLACE);
+
+    // Save the node.
+    $node_id = $this->uploadImageFile($file);
+    //Assert the constraint message.
+    $this->assertText('This image contains explicit content and will not be saved.', 'Constraint message found');
+    //Assert that the node is not saved.
+    $this->assertFalse($node_id, 'The node has not been saved');
+  }
+
+  /**
+   * Test to ensure no explicit content is detected when Safe Search is disabled.
+   */
+  public function testNoSafeSearchConstraint() {
+    // Get the image field id.
+    $field_id = $this->getImageFieldId();
+
+    //Ensure that the safe search is disabled.
+    $this->drupalGet("admin/structure/types/manage/test_images/fields/$field_id");
+
+    // Get an image with explicit content from web.
+
+    $image = file_get_contents('http://www.menshealth.com/sites/menshealth.com/files/articles/2015/12/man-snoring.jpg'); // string
+    $file = file_save_data($image, 'public://explicit.jpg', FILE_EXISTS_REPLACE);
+
+    // Save the node.
+    $node_id = $this->uploadImageFile($file);
+    //Assert the constraint message.
+    $this->assertNoText('This image contains explicit content and will not be saved.', 'No Constraint message found');
+    //Display the node.
+    $this->drupalGet('node/' . $node_id);
+  }
+}
diff --git a/tests/modules/google_vision_test/google_vision_test.info.yml b/tests/modules/google_vision_test/google_vision_test.info.yml
new file mode 100644
index 0000000..fcaa773
--- /dev/null
+++ b/tests/modules/google_vision_test/google_vision_test.info.yml
@@ -0,0 +1,8 @@
+name: 'Google Vision Test Helper'
+type: module
+description: 'Mocks the Google Vision Service'
+package: Testing
+# version: VERSION
+# core: 8.x
+dependencies:
+  - google_vision
diff --git a/tests/modules/google_vision_test/src/GoogleVisionAPIFake.php b/tests/modules/google_vision_test/src/GoogleVisionAPIFake.php
new file mode 100644
index 0000000..e660ffe
--- /dev/null
+++ b/tests/modules/google_vision_test/src/GoogleVisionAPIFake.php
@@ -0,0 +1,68 @@
+<?php
+
+namespace Drupal\google_vision_test;
+
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\google_vision\GoogleVisionAPI;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use GuzzleHttp\ClientInterface;
+use GuzzleHttp\RequestOptions;
+
+class GoogleVisionAPIFake extends GoogleVisionAPI {
+
+  /**
+   * The config factory.
+   *
+   * @var \Drupal\Core\Config\ConfigFactoryInterface
+   */
+  protected $configFactory;
+
+  /**
+   * The HTTP client to fetch the feed data with.
+   *
+   * @var \GuzzleHttp\ClientInterface
+   */
+  protected $httpClient;
+
+  /**
+   * Stores the API key.
+   *
+   * @var int
+   */
+  protected $apiKey;
+
+
+  /**
+   * Construct a GoogleVisionAPI object.
+   *
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   The config factory.
+   *
+   * @param \GuzzleHttp\ClientInterface $http_client
+   *   A Guzzle client object.
+   *
+   * @todo Throw the exception when the api key is not set on status page.
+   */
+  public function __construct(ConfigFactoryInterface $config_factory, ClientInterface $http_client) {
+    $this->configFactory = $config_factory;
+    $this->httpClient = $http_client;
+    /*$this->apiKey = $this->configFactory->get('google_vision.settings')
+      ->get('api_key');*/
+  }
+
+  public function safeSearchDetection($filepath) {
+    /*if(!$this->apiKey) {
+      return FALSE;
+    }*/
+    $response = array(
+      'responses' => array(
+        '0' => array(
+          'safeSearchAnnotation' => array(
+            'adult' => 'LIKELY'
+          ),
+        ),
+      ),
+    );
+    return $response;
+  }
+}
diff --git a/tests/modules/google_vision_test/src/GoogleVisionTestServiceProvider.php b/tests/modules/google_vision_test/src/GoogleVisionTestServiceProvider.php
new file mode 100644
index 0000000..0c9f54d
--- /dev/null
+++ b/tests/modules/google_vision_test/src/GoogleVisionTestServiceProvider.php
@@ -0,0 +1,17 @@
+<?php
+
+namespace Drupal\google_vision_test;
+
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\Core\DependencyInjection\ServiceProviderBase;
+
+class GoogleVisionTestServiceProvider extends ServiceProviderBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function alter(ContainerBuilder $container) {
+    // Overrides lingotek class to mock communication with the server.
+    $definition = $container->getDefinition('google_vision.api');
+    $definition->setClass('Drupal\google_vision_test\GoogleVisionAPIFake');
+}
