Handling images in mobile applications has become the norm. Almost 99% of the applications we interact with daily have images in one way or another. However, dealing with the back-end images has proven to be a very complex task. For this reason, developers have come up with alternatives to handling images.
This tutorial goes through how images can be uploaded from an REST api by mobile application as base64 and uploaded to the server as an image.
Table of contents
- Setting up server for image upload
- Testing From PostMan
- Conclusion
Prerequisites
To follow this tutorial along, you need to have:
- PHP 8+ locally installed.
- Laravel Latest installed.
- Basic knowledge of SQL and MySQL locally installed.
Setting up the server for image upload
Install laravel and let's start
First, set up the database configurations by editing the .env file as shown below:
...DB_CONNECTION=mysqlDB_HOST=127.0.0.1DB_PORT=3306DB_DATABASE=imageDB_USERNAME=yourDBusernameDB_PASSWORD=yourDBpassword
Next, create the Uploads model by running the following commands:
php artisan make:model Uploads --m
The above command generates a model in the App/Models folder and a migration file.
Now, edit both the model and the migration file as shown below:
<?php//edit model as shown belownamespace App\Models;class Uploads extends Model{
....
protected $fillable=[
'image_path',
];
...}
The above script creates a model with image_path, which we’ll later use to store our uploaded file’s path.
<?php...class CreateUploadsTable extends Migration{
public function up()
{
Schema::create('uploads', function (Blueprint $table) {
$table->id();
$table->string('image_path')->nullable();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('uploads');
}}
The above script creates our database table to store our uploaded files details.
Next, execute the following commands to migrate our database:
php artisan migrate
With the database and model setup complete, let’s create a controller to handle the image from the api & application.
To handle this, first create an image repository in the App/Repos namespace and update it as follows:
<?phpnamespace App\Repos;...use Intervention\Image\Facades\Image;...class ImageRepository{
// define a method to upload our image
public function upload_image($base64_image,$image_path){
//The base64 encoded image data
$image_64 = $base64_image;
// exploed the image to get the extension
$extension = explode(';base64',$image_64);
//from the first element
$extension = explode('/',$extension[0]);
// from the 2nd element
$extension = $extension[1];
$replace = substr($image_64, 0, strpos($image_64, ',')+1);
// finding the substring from
// replace here for example in our case: data:image/png;base64,
$image = str_replace($replace, '', $image_64);
// replace
$image = str_replace(' ', '+', $image);
// set the image name using the time and a random string plus
// an extension
$imageName = time().'_'.Str::random(20).'.'.$extension;
// save the image in the image path we passed from the
// function parameter.
Storage::disk('public')->put($image_path.'/' .$imageName, base64_decode($image));
// return the image path and feed to the function that requests it
return $image_path.'/'.$imageName;
}}
In the above script, we’ve defined the ImageRepository class. The class has the upload_image() method that takes two parameters, i.e, the base64 image submitted from the frontend and the image_path.
The image path passed in the above method would be where we store the image.
The function also has a couple of variables:
$image_64 holds the image in base64 format.
$extension refers to the extension of the image i.e png.
$imageName. We use the PHP inbuilt method time() and a random string concatenated together to come up with image name. This ensures uniqueness in image names.
The return statement returns the image path.
Next, let’s create our controller. Run the following commands to create a controller in the App/Http/Controllers directory:
php artisan make:controller Api/UploaderController
Open this new file App/Http/Controllers/Api/UploaderController.php and update it as follows:
<?php
/**
* @group Image
* Create new images uploaded
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function createUploadedImages(Request $request) {
// validate the incoming API requests to ensure
// that they contain the images to upload
$validator=Validator::make($request->all(),[
'image' =>'required',
]);
// if the request does not contain the image
// handle the error message as shown below
if($validator->fails()){
return response()->json([
'success'=>false,
'message'=>$validator->errors()->first(),
],400);
}
// otherwise the image has been received and it's time handle them
$attachment_url= (new ImageRepository)
->upload_image($request->input('banner_image'),'test-images');
//use Image model to create image
$image=Upload::create([
'image' =>$attachment_url
]);
// return the success response
return response()->json([
'success'=>true,
'message'=>"You have successfully created a test image",
],201);
}
In the above controller, we define the createUploadedImages method to handle the requests. Then, we proceed to validate this request and handle the image.
We have called the image repository class to handle our image. We then create an image in the database table using the image class instance. and you can use "use" keyword and import instance.
Testing
To test our application, we need to define our routes and ensure that all the images submitted to the server are base64.
Therefore, edit the routes/api.php file as shown below:
...
Route::post('image-uploader',[UploaderController::class,'createUploadedImages']);...
Next, serve the application by running the following commands:
php artisan serve
Conclusion
In this article, we have discussed image upload in depth. We have also seen how we can convert images to base64 using events.
We have also seen how we can handle this base64 image using an image repository and save the image path to the database on the server.