This tutorial demonstrates the integration of the AWS SDK for PHP Rekognition client into a Laravel project, covering two functions of the Rekognition service: detecting text in photos, and detecting nudity.
A demo of the completed tutorial is available below.
Demo URL: http://laravel-aws-rekognition-demo.icwebapps.com/
You will need to get your AWS Secret Access Key
and Access Key ID
to use the SDK. Click here to visit the Managing Access Keys for IAM Users page and learn how to find these keys.
- https://docs.aws.amazon.com/rekognition/latest/dg/moderation.html
- https://docs.aws.amazon.com/rekognition/latest/dg/API_DetectModerationLabels.html
To begin, let's install an empty Laravel project. For this tutorial, we will use the global Laravel installer. You can click here to learn more about the global installer.
laravel new rekognition
Change into the project directory
cd rekognition
Add the AWS SDK for PHP package to your composer.json
file to require aws/aws-sdk-php
version 3.
"require": {
"aws/aws-sdk-php": "3.*"
}
Install the project dependencies, this will also install the AWS SDK for PHP
composer install
Create an application environment file
mv .env.example .env
Add two new environment variables to your .env
file and populate the values with your keys found in the prerequisites section.
AWS_SECRET_ACCESS_KEY=ENTER_YOUR_KEY
AWS_ACCESS_KEY_ID=ENTER_YOUR_KEY
Generate the application key
php artisan key:generate
Set directory permissions
sudo chmod -R 777 bootstrap
sudo chmod -R 777 storage
Create a new controller called PhotosController
by running the command below. This is where we will put all the logic.
php artisan make:controller PhotosController
Open the new controller and add two new methods, one to show the form, and one to receive the form submission.
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class PhotosController extends Controller
{
public function showForm()
{
return view('form');
}
public function submitForm(Request $request)
{
//
}
}
In the showForm
method, we will simply return a view we'll create later. In the submitForm
method, all we'll do for now is include the Request $request
parameter, and add Use Illuminate\Http\Request
at the top.
Open the web.php
file in the routes
directory and create two new routes
Route::get('/', 'PhotosController@showForm');
Route::post('/', 'PhotosController@submitForm');
Create a new blade file in the following location:
/resources/views/form.blade.php
Add the following contents to the form.blade.php
file:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Laravel + AWS Rekognition</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
</head>
<body>
<div class="container">
<div class="jumbotron">
<h3>Laravel + AWS Rekognition SDK Integration</h3>
<p>This project demonstrates the integration of the AWS Rekognition SDK into a Laravel project.</p>
</div>
@if(session('success'))
<div class="alert alert-success">
<div class="form-group">{{ session('success') }}</div>
<a href="/" class="btn btn-success">Try Again</a>
</div>
@endif
@if(isset($results))
{{ dd($results) }}
@else
<form action="{{ action('PhotosController@submitForm') }}" method="post" enctype="multipart/form-data">
@csrf
<div class="form-group">
<label for="type">Action</label>
<select name="type" id="type" class="form-control">
<option value="text">Read Text</option>
<option value="nudity">Detect Nudity</option>
</select>
</div>
<div class="form-group">
<label for="confidence">Minimum Confidence</label>
<input type="number" id="confidence" name="confidence" class="form-control" value="50">
</div>
<div class="form-group">
<label for="photo">Upload a Photo</label>
<input type="file" name="photo" id="photo" class="form-control">
</div>
<div class="form-group">
<input type="submit" value="Submit" class="btn btn-success btn-lg">
</div>
</form>
@endif
</div>
</body>
</html>
Inside the submitForm
method of the PhotosController
controller, add a line to create the Rekognition client. Be sure to add use Aws\Rekognition\RekognitionClient;
at the top of your file
use Illuminate\Http\Request;
class PhotosController extends Controller
{
public function submitForm(Request $request)
{
$client = new RekognitionClient([
'region' => 'ENTER_YOUR_REGION',
'version' => 'latest'
]);
}
}
Convert the uploaded file into base64-encoded image bytes. In the snippet below, we are looking for a FILE
field with the name photo
.
public function submitForm(Request $request)
{
$client = new RekognitionClient([
'region' => 'ENTER_YOUR_REGION',
'version' => 'latest'
]);
$image = fopen($request->file('photo')->getPathName(), 'r');
$bytes = fread($image, $request->file('photo')->getSize());
}
Open the PhotosController
file and add the following lines to the submitForm
method:
public function submitForm(Request $request)
{
$client = new RekognitionClient([
'region' => 'us-west-2',
'version' => 'latest'
]);
$image = fopen($request->file('photo')->getPathName(), 'r');
$bytes = fread($image, $request->file('photo')->getSize());
if($request->input('type') === 'nudity')
{
$results = $client->detectModerationLabels(['Image' => ['Bytes' => $bytes], 'MinConfidence' => intval($request->input('confidence'))])['ModerationLabels'];
if(array_search('Explicit Nudity', array_column($results, 'Name')))
{
$message = 'This photo may contain nudity';
}
else
{
$message = 'This photo does not contain nudity';
}
}
else
{
$results = $client->detectText(['Image' => ['Bytes' => $bytes], 'MinConfidence' => intval($request->input('confidence'))])['TextDetections'];
$string = '';
foreach($results as $item)
{
if($item['Type'] === 'WORD')
{
$string .= $item['DetectedText'] . ' ';
}
}
if(empty($string))
{
$message = 'This photo does not have any words';
}
else
{
$message = 'This photo says ' . $string;
}
}
request()->session()->flash('success', $message);
return view('form', ['results' => $results]);
}
Create a request to Rekognition. Supply the image bytes, and enter a minimum confidence level for your labels.
Detect Nudity
$results = $client->detectModerationLabels([
'Image' => ['Bytes' => $bytes],
'MinConfidence' => 50
])['ModerationLabels'];
# Check to see if nudity labels were returned
$containsNudity = array_search('Explicit Nudity', array_column($results, 'Name'));
Detect Text in Photo
$results = $client->detectText([
'Image' => ['Bytes' => $bytes],
])['TextDetections'];
# Create single string of all words detected
foreach($results as $item)
{
if($item['Type'] === 'WORD')
{
$string .= $item['DetectedText'] . ' ';
}
}
###Screenshots