QR Code Generator in Laravel 10

https://harrk.dev/content/images/2023/03/QR-Code-Generator-in-Laravel-10-Tutorial.webp

In this post, we will look at generating QR codes within your Laravel applications.

First, we will need to require the simple-qrcode package that provides first-party support for Laravel. The package itself wraps the Bacon/BaconQrCode package which itself is a port of the ZXing library but for PHP.

If you wish – you may directly interact with the BaconQrCode package without using simple-qrcode. However, simple-qrcode provides a better developer experience when used with Laravel. Additionally, with out-of-the-box support for overlaying images on QR codes.

With the context blurb out of the way. Let’s dig in!

Step 1: Setting Up

Spin up a new Laravel 10 project (or step over this if you already have a project ready).

$ laravel new qrcodegenerator

Set up your database connection as per your own preference. Then install the simple-qrcode package via Composer.

$ composer require simplesoftwareio/simple-qrcode "~4"

Optional! If you want to create QR codes in .png format. You will need to install the imagick extension. In most cases, all you need to do is install via pecl with pecl install imagick. If that does not work for you, then Google is your friend here as it goes beyond the topic of this article.

Step 2: Creating The Controller

Now we need to wire up a controller and route before we can pull back a QR code in our browser.

Create a new QrCodeController.

$ php artisan make:controller QrCodeController

And then reference the controller in our routes/web.php file.

<?php

use App\Http\Controllers\QrCodeController;
use Illuminate\Support\Facades\Route;

Route::get('/', [QrCodeController::class, 'show']);

Opening up the URL in our browser gives us a blank page at this point. Also as I’m using Valet here, I only need to enter the foldername.test to view the project in my browser. Your setup may be different so you do you, whether that’s php artisan serve or something else.

A very empty page

Step 3: Generating QR Codes

At the very bare minimum, you can call the QrCode facade alongside generate with something to render. And you’ll get a QR code back.

In my QrCodeController I am creating a QR code with all the default settings with the following content “Hello, World!”.

<?php

namespace App\Http\Controllers;

use SimpleSoftwareIO\QrCode\Facades\QrCode;

class QrCodeController extends Controller
{
    public function show()
    {
        return QrCode::generate(
            'Hello, World!',
        );
    }
}

Refresh the page in the browser and…

A rendered QR code
wollah!

Step 4: Customising the Generated QR Code

Alright so how about something a little more interesting? A splash of colour? Let’s use a couple of methods that allow us to change the background colour, foreground colour, and margin.

public function show()
{
    return QrCode::size(200)
        ->backgroundColor(255, 255, 0)
        ->color(0, 0, 255)
        ->margin(1)
        ->generate(
            'Hello, World!',
        );
}

And here’s the result:

QR Code with colour

Let’s try something that makes our QR codes stand out. And I’m not talking about colours anymore.

We can actually modify the style and eye (the three corners) of the QR code. Try this out:

return QrCode::size(200)
        ->style('dot')
        ->eye('circle')
        ->color(0, 0, 255)
        ->margin(1)
        ->generate(
            'Hello, World!',
        );

Result:

QR Code with Style

Before closing this section. One more on colours: gradients.

$from = [255, 0, 0];
$to = [0, 0, 255];

return QrCode::size(200)
    ->style('dot')
    ->eye('circle')
    ->gradient($from[0], $from[1], $from[2], $to[0], $to[1], $to[2], 'diagonal')
    ->margin(1)
    ->generate(
        'Hello, World!',
    );

By specifying a from and to colour, alongside a type of gradient (vertical, horizontal, etc). You can create something really cool!

A QR Code with a gradient

Merging Images

To overlay an image in a QR code – we’ll need to change the way we do a few things.

To prepare for this I have dropped an image (twitter.jpg) in my storage/app folder. Then by calling ->merge($filepath), simple-qrcode will load that image and overlay it onto the QR code.

If you want to pull in the image data yourself, you can replace merge with mergeString. Eg: ->mergeString(Storage::get($path)).

Merging an image is only supported with png QR codes, so we need to specify the format on this, too.

public function show()
    {
        $data = QrCode::size(512)
            ->format('png')
            ->merge('/storage/app/twitter.jpg')
            ->errorCorrection('M')
            ->generate(
                'https://twitter.com/HarryKir',
            );

        return response($data)
            ->header('Content-type', 'image/png');
    }

Then the result of all this:

QR Code with Twitter Logo in Centre

You may have noticed the line in regards to errorCorrection. When we overlay an image, part of the QR code’s data becomes obscured.

By default, the errorCorrection is set to the lowest value (‘L’). If you attempt to scan your QR code like this, it’s likely that the QR code will not scan. To remedy this we adjust the errorCorrection level up a notch until our code is scannable.

The various levels are:

  • L: Low (7% correction)
  • M: Medium (15% correction)
  • Q: Quartile (25% correction)
  • H: High (30% correction)

The higher the correction level, the more “noisy” the QR code becomes. Preferably you want the lowest correction level alongside a scannable QR code for the sake of keeping up appearances.

Downloading Generated QR Codes

To return a download response, you can either store the QR code as a file and return the path with return response()->download($path); or stream the contents of the QR code without using the filesystem.

An example of using streamDownload to do this:

public function download()
{
    return response()->streamDownload(
        function () {
            echo QrCode::size(200)
                ->format('png')
                ->generate('https://harrk.dev');
        },
        'qr-code.png',
        [
            'Content-Type' => 'image/png',
        ]
    );
}

Generating QR Codes in Blade

Since we’ve been using a Facade all along, generating a QR code in Blade is as simple as repeating the above steps. Call the facade, customise as required, and call generate.

{!! QrCode::size(256)->generate('https://google.com') !!}

Or another approach, encode the data within an image tag manually. For example, if you need to change the image type for whatever reason.

<img src="data:image/png;base64, {!! base64_encode(QrCode::format('png')->size(256)->generate('https://google.com')) !!} ">

QR Code Data Types

Alright, so we’ve been using URLs in these examples. Mobile devices are clever enough to figure out how to handle these when scanned, but we can go a step further.

If you want to read the long version of this. Check out the ZXing’s Wiki page.

To summarise: simple-qrcode has a couple of helpers to specify the data the QR code will contain. You can replace the generate method with any of these.

Here are a few examples:

Email

Open a blank email addressed to “hello@example.com”.

QrCode::size(200)->email('hello@example.com');

Open an email with a predefined subject and body.

QrCode::size(200)->email('hello@example.com', 'Hello World', 'This is a test message.');

Phone Number

QrCode::size(200)->phoneNumber('555-555-5555');

SMS Text Message

Send an SMS text message to 555-555-5555 with a prewritten message, “Hi!”.

QrCode::size(200)->SMS('555-555-5555', 'Hi!');

Wi-Fi

Share Wi-Fi credentials for your visitors.

QrCode::size(200)->wiFi([
    'encryption' => 'WPA/WEP',
    'ssid' => 'SSID of the network',
    'password' => 'Password of the network',
    'hidden' => 'Whether the network is a hidden SSID or not.'
]);

Geolocation

Share a location by providing a latitude and longitude.

QrCode::size(200)->geo(51.378638, -0.100897);

Conclusion

To see more advance options for QR code customisation, refer to the documentation for simple-qrcode.

As for some real world examples of this package in action. I use simple-qrcode for generating QR codes for my QR code tracking SaaS.

QRMetric – Your Dynamic QR Code Buddy

Create Dynamic QR Codes that can be modified without requiring you to redistribute a new QR code. Can be changed any time, any place, anywhere.

Otherwise, if generating QR codes with Javascript is your thing. Consider checking out the node-qrcode library. I use this for generating QR codes on a static site, without any server involvement altogether.

Random QR Code Generator

RandomQR is a QR Code Generator for those times when you just need a random QR image and nothing more. Simple, easy, and fast.

Laravel News Links