{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE StrictData #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# OPTIONS_GHC -fno-warn-unused-binds #-}
{-# OPTIONS_GHC -fno-warn-unused-imports #-}
{-# OPTIONS_GHC -fno-warn-unused-matches #-}

-- Derived from AWS service descriptions, licensed under Apache 2.0.

-- |
-- Module      : Amazonka.Rekognition.DetectText
-- Copyright   : (c) 2013-2021 Brendan Hay
-- License     : Mozilla Public License, v. 2.0.
-- Maintainer  : Brendan Hay <brendan.g.hay+amazonka@gmail.com>
-- Stability   : auto-generated
-- Portability : non-portable (GHC extensions)
--
-- Detects text in the input image and converts it into machine-readable
-- text.
--
-- Pass the input image as base64-encoded image bytes or as a reference to
-- an image in an Amazon S3 bucket. If you use the AWS CLI to call Amazon
-- Rekognition operations, you must pass it as a reference to an image in
-- an Amazon S3 bucket. For the AWS CLI, passing image bytes is not
-- supported. The image must be either a .png or .jpeg formatted file.
--
-- The @DetectText@ operation returns text in an array of TextDetection
-- elements, @TextDetections@. Each @TextDetection@ element provides
-- information about a single word or line of text that was detected in the
-- image.
--
-- A word is one or more ISO basic latin script characters that are not
-- separated by spaces. @DetectText@ can detect up to 100 words in an
-- image.
--
-- A line is a string of equally spaced words. A line isn\'t necessarily a
-- complete sentence. For example, a driver\'s license number is detected
-- as a line. A line ends when there is no aligned text after it. Also, a
-- line ends when there is a large gap between words, relative to the
-- length of the words. This means, depending on the gap between words,
-- Amazon Rekognition may detect multiple lines in text aligned in the same
-- direction. Periods don\'t represent the end of a line. If a sentence
-- spans multiple lines, the @DetectText@ operation returns multiple lines.
--
-- To determine whether a @TextDetection@ element is a line of text or a
-- word, use the @TextDetection@ object @Type@ field.
--
-- To be detected, text must be within +\/- 90 degrees orientation of the
-- horizontal axis.
--
-- For more information, see DetectText in the Amazon Rekognition Developer
-- Guide.
module Amazonka.Rekognition.DetectText
  ( -- * Creating a Request
    DetectText (..),
    newDetectText,

    -- * Request Lenses
    detectText_filters,
    detectText_image,

    -- * Destructuring the Response
    DetectTextResponse (..),
    newDetectTextResponse,

    -- * Response Lenses
    detectTextResponse_textDetections,
    detectTextResponse_textModelVersion,
    detectTextResponse_httpStatus,
  )
where

import qualified Amazonka.Core as Core
import qualified Amazonka.Lens as Lens
import qualified Amazonka.Prelude as Prelude
import Amazonka.Rekognition.Types
import qualified Amazonka.Request as Request
import qualified Amazonka.Response as Response

-- | /See:/ 'newDetectText' smart constructor.
data DetectText = DetectText'
  { -- | Optional parameters that let you set the criteria that the text must
    -- meet to be included in your response.
    DetectText -> Maybe DetectTextFilters
filters :: Prelude.Maybe DetectTextFilters,
    -- | The input image as base64-encoded bytes or an Amazon S3 object. If you
    -- use the AWS CLI to call Amazon Rekognition operations, you can\'t pass
    -- image bytes.
    --
    -- If you are using an AWS SDK to call Amazon Rekognition, you might not
    -- need to base64-encode image bytes passed using the @Bytes@ field. For
    -- more information, see Images in the Amazon Rekognition developer guide.
    DetectText -> Image
image :: Image
  }
  deriving (DetectText -> DetectText -> Bool
(DetectText -> DetectText -> Bool)
-> (DetectText -> DetectText -> Bool) -> Eq DetectText
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DetectText -> DetectText -> Bool
$c/= :: DetectText -> DetectText -> Bool
== :: DetectText -> DetectText -> Bool
$c== :: DetectText -> DetectText -> Bool
Prelude.Eq, ReadPrec [DetectText]
ReadPrec DetectText
Int -> ReadS DetectText
ReadS [DetectText]
(Int -> ReadS DetectText)
-> ReadS [DetectText]
-> ReadPrec DetectText
-> ReadPrec [DetectText]
-> Read DetectText
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [DetectText]
$creadListPrec :: ReadPrec [DetectText]
readPrec :: ReadPrec DetectText
$creadPrec :: ReadPrec DetectText
readList :: ReadS [DetectText]
$creadList :: ReadS [DetectText]
readsPrec :: Int -> ReadS DetectText
$creadsPrec :: Int -> ReadS DetectText
Prelude.Read, Int -> DetectText -> ShowS
[DetectText] -> ShowS
DetectText -> String
(Int -> DetectText -> ShowS)
-> (DetectText -> String)
-> ([DetectText] -> ShowS)
-> Show DetectText
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DetectText] -> ShowS
$cshowList :: [DetectText] -> ShowS
show :: DetectText -> String
$cshow :: DetectText -> String
showsPrec :: Int -> DetectText -> ShowS
$cshowsPrec :: Int -> DetectText -> ShowS
Prelude.Show, (forall x. DetectText -> Rep DetectText x)
-> (forall x. Rep DetectText x -> DetectText) -> Generic DetectText
forall x. Rep DetectText x -> DetectText
forall x. DetectText -> Rep DetectText x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep DetectText x -> DetectText
$cfrom :: forall x. DetectText -> Rep DetectText x
Prelude.Generic)

-- |
-- Create a value of 'DetectText' with all optional fields omitted.
--
-- Use <https://hackage.haskell.org/package/generic-lens generic-lens> or <https://hackage.haskell.org/package/optics optics> to modify other optional fields.
--
-- The following record fields are available, with the corresponding lenses provided
-- for backwards compatibility:
--
-- 'filters', 'detectText_filters' - Optional parameters that let you set the criteria that the text must
-- meet to be included in your response.
--
-- 'image', 'detectText_image' - The input image as base64-encoded bytes or an Amazon S3 object. If you
-- use the AWS CLI to call Amazon Rekognition operations, you can\'t pass
-- image bytes.
--
-- If you are using an AWS SDK to call Amazon Rekognition, you might not
-- need to base64-encode image bytes passed using the @Bytes@ field. For
-- more information, see Images in the Amazon Rekognition developer guide.
newDetectText ::
  -- | 'image'
  Image ->
  DetectText
newDetectText :: Image -> DetectText
newDetectText Image
pImage_ =
  DetectText' :: Maybe DetectTextFilters -> Image -> DetectText
DetectText'
    { $sel:filters:DetectText' :: Maybe DetectTextFilters
filters = Maybe DetectTextFilters
forall a. Maybe a
Prelude.Nothing,
      $sel:image:DetectText' :: Image
image = Image
pImage_
    }

-- | Optional parameters that let you set the criteria that the text must
-- meet to be included in your response.
detectText_filters :: Lens.Lens' DetectText (Prelude.Maybe DetectTextFilters)
detectText_filters :: (Maybe DetectTextFilters -> f (Maybe DetectTextFilters))
-> DetectText -> f DetectText
detectText_filters = (DetectText -> Maybe DetectTextFilters)
-> (DetectText -> Maybe DetectTextFilters -> DetectText)
-> Lens
     DetectText
     DetectText
     (Maybe DetectTextFilters)
     (Maybe DetectTextFilters)
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
Lens.lens (\DetectText' {Maybe DetectTextFilters
filters :: Maybe DetectTextFilters
$sel:filters:DetectText' :: DetectText -> Maybe DetectTextFilters
filters} -> Maybe DetectTextFilters
filters) (\s :: DetectText
s@DetectText' {} Maybe DetectTextFilters
a -> DetectText
s {$sel:filters:DetectText' :: Maybe DetectTextFilters
filters = Maybe DetectTextFilters
a} :: DetectText)

-- | The input image as base64-encoded bytes or an Amazon S3 object. If you
-- use the AWS CLI to call Amazon Rekognition operations, you can\'t pass
-- image bytes.
--
-- If you are using an AWS SDK to call Amazon Rekognition, you might not
-- need to base64-encode image bytes passed using the @Bytes@ field. For
-- more information, see Images in the Amazon Rekognition developer guide.
detectText_image :: Lens.Lens' DetectText Image
detectText_image :: (Image -> f Image) -> DetectText -> f DetectText
detectText_image = (DetectText -> Image)
-> (DetectText -> Image -> DetectText)
-> Lens DetectText DetectText Image Image
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
Lens.lens (\DetectText' {Image
image :: Image
$sel:image:DetectText' :: DetectText -> Image
image} -> Image
image) (\s :: DetectText
s@DetectText' {} Image
a -> DetectText
s {$sel:image:DetectText' :: Image
image = Image
a} :: DetectText)

instance Core.AWSRequest DetectText where
  type AWSResponse DetectText = DetectTextResponse
  request :: DetectText -> Request DetectText
request = Service -> DetectText -> Request DetectText
forall a. (ToRequest a, ToJSON a) => Service -> a -> Request a
Request.postJSON Service
defaultService
  response :: Logger
-> Service
-> Proxy DetectText
-> ClientResponse ClientBody
-> m (Either Error (ClientResponse (AWSResponse DetectText)))
response =
    (Int
 -> ResponseHeaders
 -> Object
 -> Either String (AWSResponse DetectText))
-> Logger
-> Service
-> Proxy DetectText
-> ClientResponse ClientBody
-> m (Either Error (ClientResponse (AWSResponse DetectText)))
forall (m :: * -> *) a.
MonadResource m =>
(Int -> ResponseHeaders -> Object -> Either String (AWSResponse a))
-> Logger
-> Service
-> Proxy a
-> ClientResponse ClientBody
-> m (Either Error (ClientResponse (AWSResponse a)))
Response.receiveJSON
      ( \Int
s ResponseHeaders
h Object
x ->
          Maybe [TextDetection] -> Maybe Text -> Int -> DetectTextResponse
DetectTextResponse'
            (Maybe [TextDetection] -> Maybe Text -> Int -> DetectTextResponse)
-> Either String (Maybe [TextDetection])
-> Either String (Maybe Text -> Int -> DetectTextResponse)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
Prelude.<$> (Object
x Object -> Text -> Either String (Maybe (Maybe [TextDetection]))
forall a. FromJSON a => Object -> Text -> Either String (Maybe a)
Core..?> Text
"TextDetections" Either String (Maybe (Maybe [TextDetection]))
-> Maybe [TextDetection] -> Either String (Maybe [TextDetection])
forall (f :: * -> *) a. Functor f => f (Maybe a) -> a -> f a
Core..!@ Maybe [TextDetection]
forall a. Monoid a => a
Prelude.mempty)
            Either String (Maybe Text -> Int -> DetectTextResponse)
-> Either String (Maybe Text)
-> Either String (Int -> DetectTextResponse)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
Prelude.<*> (Object
x Object -> Text -> Either String (Maybe Text)
forall a. FromJSON a => Object -> Text -> Either String (Maybe a)
Core..?> Text
"TextModelVersion")
            Either String (Int -> DetectTextResponse)
-> Either String Int -> Either String DetectTextResponse
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
Prelude.<*> (Int -> Either String Int
forall (f :: * -> *) a. Applicative f => a -> f a
Prelude.pure (Int -> Int
forall a. Enum a => a -> Int
Prelude.fromEnum Int
s))
      )

instance Prelude.Hashable DetectText

instance Prelude.NFData DetectText

instance Core.ToHeaders DetectText where
  toHeaders :: DetectText -> ResponseHeaders
toHeaders =
    ResponseHeaders -> DetectText -> ResponseHeaders
forall a b. a -> b -> a
Prelude.const
      ( [ResponseHeaders] -> ResponseHeaders
forall a. Monoid a => [a] -> a
Prelude.mconcat
          [ HeaderName
"X-Amz-Target"
              HeaderName -> ByteString -> ResponseHeaders
forall a. ToHeader a => HeaderName -> a -> ResponseHeaders
Core.=# ( ByteString
"RekognitionService.DetectText" ::
                          Prelude.ByteString
                      ),
            HeaderName
"Content-Type"
              HeaderName -> ByteString -> ResponseHeaders
forall a. ToHeader a => HeaderName -> a -> ResponseHeaders
Core.=# ( ByteString
"application/x-amz-json-1.1" ::
                          Prelude.ByteString
                      )
          ]
      )

instance Core.ToJSON DetectText where
  toJSON :: DetectText -> Value
toJSON DetectText' {Maybe DetectTextFilters
Image
image :: Image
filters :: Maybe DetectTextFilters
$sel:image:DetectText' :: DetectText -> Image
$sel:filters:DetectText' :: DetectText -> Maybe DetectTextFilters
..} =
    [Pair] -> Value
Core.object
      ( [Maybe Pair] -> [Pair]
forall a. [Maybe a] -> [a]
Prelude.catMaybes
          [ (Text
"Filters" Text -> DetectTextFilters -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
Core..=) (DetectTextFilters -> Pair)
-> Maybe DetectTextFilters -> Maybe Pair
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
Prelude.<$> Maybe DetectTextFilters
filters,
            Pair -> Maybe Pair
forall a. a -> Maybe a
Prelude.Just (Text
"Image" Text -> Image -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
Core..= Image
image)
          ]
      )

instance Core.ToPath DetectText where
  toPath :: DetectText -> ByteString
toPath = ByteString -> DetectText -> ByteString
forall a b. a -> b -> a
Prelude.const ByteString
"/"

instance Core.ToQuery DetectText where
  toQuery :: DetectText -> QueryString
toQuery = QueryString -> DetectText -> QueryString
forall a b. a -> b -> a
Prelude.const QueryString
forall a. Monoid a => a
Prelude.mempty

-- | /See:/ 'newDetectTextResponse' smart constructor.
data DetectTextResponse = DetectTextResponse'
  { -- | An array of text that was detected in the input image.
    DetectTextResponse -> Maybe [TextDetection]
textDetections :: Prelude.Maybe [TextDetection],
    -- | The model version used to detect text.
    DetectTextResponse -> Maybe Text
textModelVersion :: Prelude.Maybe Prelude.Text,
    -- | The response's http status code.
    DetectTextResponse -> Int
httpStatus :: Prelude.Int
  }
  deriving (DetectTextResponse -> DetectTextResponse -> Bool
(DetectTextResponse -> DetectTextResponse -> Bool)
-> (DetectTextResponse -> DetectTextResponse -> Bool)
-> Eq DetectTextResponse
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DetectTextResponse -> DetectTextResponse -> Bool
$c/= :: DetectTextResponse -> DetectTextResponse -> Bool
== :: DetectTextResponse -> DetectTextResponse -> Bool
$c== :: DetectTextResponse -> DetectTextResponse -> Bool
Prelude.Eq, ReadPrec [DetectTextResponse]
ReadPrec DetectTextResponse
Int -> ReadS DetectTextResponse
ReadS [DetectTextResponse]
(Int -> ReadS DetectTextResponse)
-> ReadS [DetectTextResponse]
-> ReadPrec DetectTextResponse
-> ReadPrec [DetectTextResponse]
-> Read DetectTextResponse
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [DetectTextResponse]
$creadListPrec :: ReadPrec [DetectTextResponse]
readPrec :: ReadPrec DetectTextResponse
$creadPrec :: ReadPrec DetectTextResponse
readList :: ReadS [DetectTextResponse]
$creadList :: ReadS [DetectTextResponse]
readsPrec :: Int -> ReadS DetectTextResponse
$creadsPrec :: Int -> ReadS DetectTextResponse
Prelude.Read, Int -> DetectTextResponse -> ShowS
[DetectTextResponse] -> ShowS
DetectTextResponse -> String
(Int -> DetectTextResponse -> ShowS)
-> (DetectTextResponse -> String)
-> ([DetectTextResponse] -> ShowS)
-> Show DetectTextResponse
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DetectTextResponse] -> ShowS
$cshowList :: [DetectTextResponse] -> ShowS
show :: DetectTextResponse -> String
$cshow :: DetectTextResponse -> String
showsPrec :: Int -> DetectTextResponse -> ShowS
$cshowsPrec :: Int -> DetectTextResponse -> ShowS
Prelude.Show, (forall x. DetectTextResponse -> Rep DetectTextResponse x)
-> (forall x. Rep DetectTextResponse x -> DetectTextResponse)
-> Generic DetectTextResponse
forall x. Rep DetectTextResponse x -> DetectTextResponse
forall x. DetectTextResponse -> Rep DetectTextResponse x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep DetectTextResponse x -> DetectTextResponse
$cfrom :: forall x. DetectTextResponse -> Rep DetectTextResponse x
Prelude.Generic)

-- |
-- Create a value of 'DetectTextResponse' with all optional fields omitted.
--
-- Use <https://hackage.haskell.org/package/generic-lens generic-lens> or <https://hackage.haskell.org/package/optics optics> to modify other optional fields.
--
-- The following record fields are available, with the corresponding lenses provided
-- for backwards compatibility:
--
-- 'textDetections', 'detectTextResponse_textDetections' - An array of text that was detected in the input image.
--
-- 'textModelVersion', 'detectTextResponse_textModelVersion' - The model version used to detect text.
--
-- 'httpStatus', 'detectTextResponse_httpStatus' - The response's http status code.
newDetectTextResponse ::
  -- | 'httpStatus'
  Prelude.Int ->
  DetectTextResponse
newDetectTextResponse :: Int -> DetectTextResponse
newDetectTextResponse Int
pHttpStatus_ =
  DetectTextResponse' :: Maybe [TextDetection] -> Maybe Text -> Int -> DetectTextResponse
DetectTextResponse'
    { $sel:textDetections:DetectTextResponse' :: Maybe [TextDetection]
textDetections =
        Maybe [TextDetection]
forall a. Maybe a
Prelude.Nothing,
      $sel:textModelVersion:DetectTextResponse' :: Maybe Text
textModelVersion = Maybe Text
forall a. Maybe a
Prelude.Nothing,
      $sel:httpStatus:DetectTextResponse' :: Int
httpStatus = Int
pHttpStatus_
    }

-- | An array of text that was detected in the input image.
detectTextResponse_textDetections :: Lens.Lens' DetectTextResponse (Prelude.Maybe [TextDetection])
detectTextResponse_textDetections :: (Maybe [TextDetection] -> f (Maybe [TextDetection]))
-> DetectTextResponse -> f DetectTextResponse
detectTextResponse_textDetections = (DetectTextResponse -> Maybe [TextDetection])
-> (DetectTextResponse
    -> Maybe [TextDetection] -> DetectTextResponse)
-> Lens
     DetectTextResponse
     DetectTextResponse
     (Maybe [TextDetection])
     (Maybe [TextDetection])
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
Lens.lens (\DetectTextResponse' {Maybe [TextDetection]
textDetections :: Maybe [TextDetection]
$sel:textDetections:DetectTextResponse' :: DetectTextResponse -> Maybe [TextDetection]
textDetections} -> Maybe [TextDetection]
textDetections) (\s :: DetectTextResponse
s@DetectTextResponse' {} Maybe [TextDetection]
a -> DetectTextResponse
s {$sel:textDetections:DetectTextResponse' :: Maybe [TextDetection]
textDetections = Maybe [TextDetection]
a} :: DetectTextResponse) ((Maybe [TextDetection] -> f (Maybe [TextDetection]))
 -> DetectTextResponse -> f DetectTextResponse)
-> ((Maybe [TextDetection] -> f (Maybe [TextDetection]))
    -> Maybe [TextDetection] -> f (Maybe [TextDetection]))
-> (Maybe [TextDetection] -> f (Maybe [TextDetection]))
-> DetectTextResponse
-> f DetectTextResponse
forall b c a. (b -> c) -> (a -> b) -> a -> c
Prelude.. AnIso
  [TextDetection] [TextDetection] [TextDetection] [TextDetection]
-> Iso
     (Maybe [TextDetection])
     (Maybe [TextDetection])
     (Maybe [TextDetection])
     (Maybe [TextDetection])
forall (f :: * -> *) (g :: * -> *) s t a b.
(Functor f, Functor g) =>
AnIso s t a b -> Iso (f s) (g t) (f a) (g b)
Lens.mapping AnIso
  [TextDetection] [TextDetection] [TextDetection] [TextDetection]
forall s t a b. (Coercible s a, Coercible t b) => Iso s t a b
Lens.coerced

-- | The model version used to detect text.
detectTextResponse_textModelVersion :: Lens.Lens' DetectTextResponse (Prelude.Maybe Prelude.Text)
detectTextResponse_textModelVersion :: (Maybe Text -> f (Maybe Text))
-> DetectTextResponse -> f DetectTextResponse
detectTextResponse_textModelVersion = (DetectTextResponse -> Maybe Text)
-> (DetectTextResponse -> Maybe Text -> DetectTextResponse)
-> Lens
     DetectTextResponse DetectTextResponse (Maybe Text) (Maybe Text)
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
Lens.lens (\DetectTextResponse' {Maybe Text
textModelVersion :: Maybe Text
$sel:textModelVersion:DetectTextResponse' :: DetectTextResponse -> Maybe Text
textModelVersion} -> Maybe Text
textModelVersion) (\s :: DetectTextResponse
s@DetectTextResponse' {} Maybe Text
a -> DetectTextResponse
s {$sel:textModelVersion:DetectTextResponse' :: Maybe Text
textModelVersion = Maybe Text
a} :: DetectTextResponse)

-- | The response's http status code.
detectTextResponse_httpStatus :: Lens.Lens' DetectTextResponse Prelude.Int
detectTextResponse_httpStatus :: (Int -> f Int) -> DetectTextResponse -> f DetectTextResponse
detectTextResponse_httpStatus = (DetectTextResponse -> Int)
-> (DetectTextResponse -> Int -> DetectTextResponse)
-> Lens DetectTextResponse DetectTextResponse Int Int
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
Lens.lens (\DetectTextResponse' {Int
httpStatus :: Int
$sel:httpStatus:DetectTextResponse' :: DetectTextResponse -> Int
httpStatus} -> Int
httpStatus) (\s :: DetectTextResponse
s@DetectTextResponse' {} Int
a -> DetectTextResponse
s {$sel:httpStatus:DetectTextResponse' :: Int
httpStatus = Int
a} :: DetectTextResponse)

instance Prelude.NFData DetectTextResponse