{-# 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-2023 Brendan Hay
-- License     : Mozilla Public License, v. 2.0.
-- Maintainer  : Brendan Hay
-- 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 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 Detecting text 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.Core.Lens.Internal as Lens
import qualified Amazonka.Data as Data
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
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]
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
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. 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'
    { $sel:filters:DetectText' :: Maybe DetectTextFilters
filters = 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 :: Lens' DetectText (Maybe DetectTextFilters)
detectText_filters = 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 :: Lens' DetectText Image
detectText_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 :: (Service -> Service) -> DetectText -> Request DetectText
request Service -> Service
overrides =
    forall a. (ToRequest a, ToJSON a) => Service -> a -> Request a
Request.postJSON (Service -> Service
overrides Service
defaultService)
  response :: forall (m :: * -> *).
MonadResource m =>
(ByteStringLazy -> IO ByteStringLazy)
-> Service
-> Proxy DetectText
-> ClientResponse ClientBody
-> m (Either Error (ClientResponse (AWSResponse DetectText)))
response =
    forall (m :: * -> *) a.
MonadResource m =>
(Int -> ResponseHeaders -> Object -> Either String (AWSResponse a))
-> (ByteStringLazy -> IO ByteStringLazy)
-> 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'
            forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
Prelude.<$> (Object
x forall a. FromJSON a => Object -> Key -> Either String (Maybe a)
Data..?> Key
"TextDetections" forall (f :: * -> *) a. Functor f => f (Maybe a) -> a -> f a
Core..!@ forall a. Monoid a => a
Prelude.mempty)
            forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
Prelude.<*> (Object
x forall a. FromJSON a => Object -> Key -> Either String (Maybe a)
Data..?> Key
"TextModelVersion")
            forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
Prelude.<*> (forall (f :: * -> *) a. Applicative f => a -> f a
Prelude.pure (forall a. Enum a => a -> Int
Prelude.fromEnum Int
s))
      )

instance Prelude.Hashable DetectText where
  hashWithSalt :: Int -> DetectText -> Int
hashWithSalt Int
_salt DetectText' {Maybe DetectTextFilters
Image
image :: Image
filters :: Maybe DetectTextFilters
$sel:image:DetectText' :: DetectText -> Image
$sel:filters:DetectText' :: DetectText -> Maybe DetectTextFilters
..} =
    Int
_salt
      forall a. Hashable a => Int -> a -> Int
`Prelude.hashWithSalt` Maybe DetectTextFilters
filters
      forall a. Hashable a => Int -> a -> Int
`Prelude.hashWithSalt` Image
image

instance Prelude.NFData DetectText where
  rnf :: DetectText -> ()
rnf DetectText' {Maybe DetectTextFilters
Image
image :: Image
filters :: Maybe DetectTextFilters
$sel:image:DetectText' :: DetectText -> Image
$sel:filters:DetectText' :: DetectText -> Maybe DetectTextFilters
..} =
    forall a. NFData a => a -> ()
Prelude.rnf Maybe DetectTextFilters
filters seq :: forall a b. a -> b -> b
`Prelude.seq` forall a. NFData a => a -> ()
Prelude.rnf Image
image

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

instance Data.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
Data.object
      ( forall a. [Maybe a] -> [a]
Prelude.catMaybes
          [ (Key
"Filters" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
Data..=) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
Prelude.<$> Maybe DetectTextFilters
filters,
            forall a. a -> Maybe a
Prelude.Just (Key
"Image" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
Data..= Image
image)
          ]
      )

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

instance Data.ToQuery DetectText where
  toQuery :: DetectText -> QueryString
toQuery = forall a b. a -> b -> a
Prelude.const 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
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]
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
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. 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'
    { $sel:textDetections:DetectTextResponse' :: Maybe [TextDetection]
textDetections =
        forall a. Maybe a
Prelude.Nothing,
      $sel:textModelVersion:DetectTextResponse' :: Maybe Text
textModelVersion = 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 :: Lens' DetectTextResponse (Maybe [TextDetection])
detectTextResponse_textDetections = 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) forall b c a. (b -> c) -> (a -> b) -> a -> c
Prelude.. 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 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 :: Lens' DetectTextResponse (Maybe Text)
detectTextResponse_textModelVersion = 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 :: Lens' DetectTextResponse Int
detectTextResponse_httpStatus = 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 where
  rnf :: DetectTextResponse -> ()
rnf DetectTextResponse' {Int
Maybe [TextDetection]
Maybe Text
httpStatus :: Int
textModelVersion :: Maybe Text
textDetections :: Maybe [TextDetection]
$sel:httpStatus:DetectTextResponse' :: DetectTextResponse -> Int
$sel:textModelVersion:DetectTextResponse' :: DetectTextResponse -> Maybe Text
$sel:textDetections:DetectTextResponse' :: DetectTextResponse -> Maybe [TextDetection]
..} =
    forall a. NFData a => a -> ()
Prelude.rnf Maybe [TextDetection]
textDetections
      seq :: forall a b. a -> b -> b
`Prelude.seq` forall a. NFData a => a -> ()
Prelude.rnf Maybe Text
textModelVersion
      seq :: forall a b. a -> b -> b
`Prelude.seq` forall a. NFData a => a -> ()
Prelude.rnf Int
httpStatus