Deploy your apps to a supercloud in a few clicks

This Engineering Education program is supported by Section. Instantly deploy your GitHub apps, Docker containers or K8s namespaces to a supercloud.

Try It For Free

Handling Angular Base64 images in a RESTFul API with Laravel

December 30, 2021

Handling images in web 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 Angular application as base64 and uploaded to the server as an image.

Table of contents


To follow this tutorial along, you need to have:

  • PHP 7.3+ locally installed.
  • Laravel 8 installed.
  • Angular 12 installed.
  • Basic knowledge of SQL and MySQL locally installed.
  • An IDE of your interest. We’ll use both the PhpStorm for PHP and Webstorm for Angular in this article.

By the end of this tutorial, the reader should know how to handle base64 images in both Angular and Laravel.

Setting up Angular application

There are different ways of setting up Angular applications. However, this article installs our application using the Angular CLI.

Type in the following to check your currently installed version:

# command to check the current ng version
ng --version
# My installed version CLI (this may differ from your version)
Angular CLI: 12.2.3
# My current Node version 
Node: 16.5.0 
# My current npm version
Package Manager: npm 7.19.1
# On ubuntu 20.04
OS: linux x64

Note that the above output may vary and not necessarily match your versions

Next, proceed and install the Angular application by running the following commands:

ng new base64 # this installs a new angular application

Depending on your internet connection, the above command may take some time to execute.

Upon installation, navigate into the project root and create an image component as follows:

cd base64
ng g c image

The above command generates four files, including the template and TypeScript files.

Now that we have the image component, edit the app.component.html file as shown below:


The above tags ensure that the image component gets displayed when the AppComponent is executed.

Let’s change our ImageComponent template as shown below:

<div class="content mat-elevation-z8">
  <h2 class="text-center text-dark">Upload Image</h2>
  <form [formGroup]="uploadForm" (ngSubmit)="onSubmit()">
      <div class="form-row m-3">
        <div class="col-md-6">
          <label for="news_banner">Image</label>
          <input type="file" id="file" (change)="handleImageUpload($event)" class="form-control-file"required="">

You notice we’ve added an onchange event handler in the above template. This ensures that an image will only be uploaded every time a new image is added.

Next, edit the ImageComponent script file as shown below:

import {ApiService} from "../../../core/services/api.service";
import {ToastrService} from "ngx-toastr";
import * as _ from 'lodash';
export class ImageComponent implements OnInit {

  uploadImageBase64: string;
   * on image submit
    let upload:uploads={
      banner_image: this.uploadImageBase64,
          // if response is successful
          // if the response fails, show error alert
      },error => {
        //if an error occurs during the api request

   * handle image upload
   * @param fileToUpload
  // @ts-ignore
  handleImageUpload(fileToUpload) {
    // check for image to upload
    // this checks if the user has uploaded any file
    if ( &&[0]) {
      // calculate your image sizes allowed for upload
      const max_size = 20971510;
      // the only MIME types allowed
      const allowed_types = ['image/png', 'image/jpeg','image/jpg'];
      // max image height allowed
      const max_height = 14200;
      //max image width allowed
      const max_width = 15600;

      // check the file uploaded by the user
      if ([0].size > max_size) {
        //show error
        this.error = 'max image size allowed is ' + max_size / 1000 + 'Mb';
        //show an error alert using the Toastr service.
        return false;
      // check for allowable types
      if (!_.includes(allowed_types,[0].type)) {
        // define the error message due to wrong MIME type
        let error = 'The allowed images are: ( JPEG | JPG | PNG )';
        // show an error alert for MIME
        //return false since the MIME type is wrong
        return false;
      // define a file reader constant
      const reader = new FileReader();
      // read the file on load
      reader.onload = (e: any) => {
        // create an instance of the Image()
        const image = new Image();
        // get the image source
        image.src =;
        // @ts-ignore
        image.onload = rs => {
          // get the image height read
          const img_height = rs.currentTarget['height'];
          // get the image width read
          const img_width = rs.currentTarget['width'];
          // check if the dimensions meet the required height and width
          if (img_height > max_height && img_width > max_width) {
            // throw error due to unmatched dimensions
            error =
              'Maximum dimensions allowed: ' +
              max_height +
              '*' +
              max_width +
            return false;
          } else {
            // otherise get the base64 image
            this.uploadedImageBase64 =;
      // reader as data url

We have the onSubmit() method in the above script. This method is used to submit the uploaded base64 image.

The handleImageUpload() method is our image handler. It first checks the image size being uploaded. If the image size meets our predefined size, we upload it.

Next, we check if the image only contains the required MIME, i.e., JPG, PNG, and JPEG. When our checks are complete, we process our images using the FileReader method.

Setting up the server for image upload

Now that we have the Angular application up and running let’s set up our Laravel 8 server to handle the image.

First, set up the database configurations by editing the .env file as shown below:


Next, create the Image model by running the following commands:

php artisan make:model Image --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:

//edit model as shown below
namespace App\Models;
class Image extends Model
    protected $fillable=[

The above script creates a model with image_path, which we’ll later use to store our uploaded file’s path.


class CreateImageTable extends Migration
    public function up()
        Schema::create('images', function (Blueprint $table) {
    public function down()

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 Angular application.

To handle this, first create an image repository in the App/Repos namespace and update it as follows:

namespace 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 ImageUploaderController

Open this new file App/Http/Controllers/ImageUploaderController.php and update it as follows:

     * @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
            'image'       =>'required',

      // if the request does not contain the image
      // handle the error message as shown below
            return response()->json([
        // otherwise the image has been received and it's time handle them
       $attachment_url= (new ImageRepository)
       //use Image model to create image
            'image' =>$attachment_url
        // return the success response
        return response()->json([
            'message'=>"You have successfully created a test image",

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.

Finally, the return statement sends a success message to the uploading application, in this case, the Angular frontend.


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:


Next, serve the application by running the following commands:

php artisan serve

Now that you have the API server running in your Angular application, edit the api service you had initially created as follows:

   * Upload new images

The above api service ensures that we only submit the image to the route we have defined in the API server route.

And with that, you can now handle images easily using Angular and Laravel.


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.

Happy coding!

Peer Review Contributions by: Miller Juma