How to generate QR code with logo easily in PHP automatically

How to generate QR code with logo easily in PHP automatically

QR codes are a popular type of two-dimensional barcode. They are also known as hardlinks or physical world hyperlinks. QR Codes store up to 4,296 alphanumeric characters of arbitrary text. This text can be anything, for example URL, contact information, a telephone number, even a poem! QR codes can be read by an optical device with the appropriate software. Such devices range from dedicated QR code readers to mobile phones.

Whatever, everybody knows what a QR code is, but what could be more cool than a custom QR code with your own logo on it ?. With PHP , this task isn't so easy to achieve, however not impossible.

There are 2 ways to achieve your goal, either you use a library that generates QR Codes and allow you to customize it (logo customization possible) or you can implement it by yourself with php, you can render an image on another image, that means that we are going to render the logo over an already generated QR code image.

1. Use a library

Libraries make your life easier, in this case to implement a custom logo within a QR Code, you can use the Endroid QRCode package. This library is based on QRcode Perl CGI & PHP scripts by Y. Swetake and it helps you generate images containing a QR code.

The preferred way to install this library is via composer, to install execute the following composer command:

composer require endroid/qrcode

Or edit your composer.json manually and execute composer install:


{
    "require": {
        "endroid/qrcode": "^1.7",
    }
}

Now, after the installation include the class with an use statement in your class:

use Endroid\QrCode\QrCode;

And create your first QR Code with logo using the following code:

Return QR Code with logo as response

// Include the QRCode generator library
use Endroid\QrCode\QrCode;

$qrCode = new QrCode();
$qrCode->setText('http://ourcodeworld.com')
    ->setSize(300)
    ->setPadding(10)
    ->setErrorCorrection('high')
    ->setForegroundColor(array('r' => 0, 'g' => 0, 'b' => 0, 'a' => 0))
    ->setBackgroundColor(array('r' => 255, 'g' => 255, 'b' => 255, 'a' => 0))
    // Path to your logo with transparency
    ->setLogo("logo.png")
    // Set the size of your logo, default is 48
    ->setLogoSize(98)
    ->setImageType(QrCode::IMAGE_TYPE_PNG)
;

// Send output of the QRCode directly
header('Content-Type: '.$qrCode->getContentType());
$qrCode->render();

Save QR Code with logo in server

// Include the QRCode generator library
use Endroid\QrCode\QrCode;

$qrCode = new QrCode();
$qrCode->setText('http://ourcodeworld.com')
    ->setSize(300)
    ->setPadding(10)
    ->setErrorCorrection('high')
    ->setForegroundColor(array('r' => 0, 'g' => 0, 'b' => 0, 'a' => 0))
    ->setBackgroundColor(array('r' => 255, 'g' => 255, 'b' => 255, 'a' => 0))
    // Path to your logo with transparency
    ->setLogo("logo.png")
    // Set the size of your logo, default is 48
    ->setLogoSize(98)
    ->setImageType(QrCode::IMAGE_TYPE_PNG)
;

$qrCode->save('qrcode.png');

The execution of any of the previous methods, should generate the following QRCode:

Our Code World QR Code example

Don't forget to set a valid path for the logo with transparency, as you can see, Endroid QRCode offers a lot of useful methods as custom labels that could be useful for you, please visit the repository for more information.

2. Manual implementation

This feature is reliable as the QR code will be still readable even if it has a little image in the middle.

Quick example

In this case, we are going to use a simple snippet that will retrieve a QR code from the Chart API from google, which return a generated QR code.

Due to its simplicity, is (in my case) the easiest solution.

<?php
// Text content of the QRCode
$data = 'http://ourcodeworld.com';
// QRCode size
$size = '500x500';
// Path to image (web or local)
$logo = 'http://ourcodeworld.com/resources/img/ocw-empty.png';

// Get QR Code image from Google Chart API
// http://code.google.com/apis/chart/infographics/docs/qr_codes.html
$QR = imagecreatefrompng('https://chart.googleapis.com/chart?cht=qr&chld=H|1&chs='.$size.'&chl='.urlencode($data));

// START TO DRAW THE IMAGE ON THE QR CODE
$logo = imagecreatefromstring(file_get_contents($logo));
$QR_width = imagesx($QR);
$QR_height = imagesy($QR);

$logo_width = imagesx($logo);
$logo_height = imagesy($logo);

// Scale logo to fit in the QR Code
$logo_qr_width = $QR_width/3;
$scale = $logo_width/$logo_qr_width;
$logo_qr_height = $logo_height/$scale;

imagecopyresampled($QR, $logo, $QR_width/3, $QR_height/3, 0, 0, $logo_qr_width, $logo_qr_height, $logo_width, $logo_height);

// END OF DRAW

/**
 * As this example is a plain PHP example, return
 * an image response.
 *
 * Note: you can save the image if you want.
 */
header('Content-type: image/png');
imagepng($QR);
imagedestroy($QR);

// If you decide to save the image somewhere remove the header and use instead :
// $savePath = "/path/to-my-server-images/myqrcodewithlogo.png";
// imagepng($QR, $savePath);
?>

Note: the previous snippet will generate the same QR code as the image of this article, you can test it in PHPFiddle or test it locally in your environment. If you want, you can refine the method to use more sophisticated method to create the request to the google website instead of file_get_contents.

Basic troubleshooting

The logo is completely transparent and covers the QR code

This problem happens sometimes when the transparency exists but it deletes the area where is the QR code, like :

To solve it, we need to use the following lines 

// START TO DRAW THE IMAGE ON THE QR CODE
$logo = imagecreatefromstring(file_get_contents($logopath));

/**
 *  Fix for the transparent background
 */
imagecolortransparent($logo , imagecolorallocatealpha($logo , 0, 0, 0, 127));
imagealphablending($logo , false);
imagesavealpha($logo , true);

Those lines will prevent that the transparency covers the QR code, however it will still with transparency as we need it.

Finally our fixed snippet will look like :

<?php

require_once("phpqrcode/qrlib.php");

// Path where the images will be saved
$filepath = 'myimage.png';
// Image (logo) to be drawn
$logopath = 'http://ourcodeworld.com/resources/img/ocw-empty.png';
// qr code content
$codeContents = 'http://ourcodeworld.com';
// Create the file in the providen path
// Customize how you want
QRcode::png($codeContents,$filepath , QR_ECLEVEL_H, 20);

// Start DRAWING LOGO IN QRCODE

$QR = imagecreatefrompng($filepath);

// START TO DRAW THE IMAGE ON THE QR CODE
$logo = imagecreatefromstring(file_get_contents($logopath));

/**
 *  Fix for the transparent background
 */
imagecolortransparent($logo , imagecolorallocatealpha($logo , 0, 0, 0, 127));
imagealphablending($logo , false);
imagesavealpha($logo , true);

$QR_width = imagesx($QR);
$QR_height = imagesy($QR);

$logo_width = imagesx($logo);
$logo_height = imagesy($logo);

// Scale logo to fit in the QR Code
$logo_qr_width = $QR_width/3;
$scale = $logo_width/$logo_qr_width;
$logo_qr_height = $logo_height/$scale;

imagecopyresampled($QR, $logo, $QR_width/3, $QR_height/3, 0, 0, $logo_qr_width, $logo_qr_height, $logo_width, $logo_height);

// Save QR code again, but with logo on it
imagepng($QR,$filepath);

// End DRAWING LOGO IN QR CODE

// Ouput image in the browser
echo '<img src="'.$filepath.'" />';

Although there is an open source librarie that do the trick for you, you can still achieve it with some plain PHP code.

Recommendations

As you can see in the second method, we are not using any library. We just download a QR image response from the google Charts API and we draw our logo on it. However, you may not want to depend on the server google as this API is deprecated according to the homepage here and they recommend you to use the actively maintained Google Charts API instead (which doesn't support QR codes).

We recommend you to use an open source QR code generator library as TCPDF (which generates PDF also) or the most common and famous PHP QR Code.

PHP QR Code is open source (LGPL) library for generating QR Code, 2-dimensional barcode. Based on libqrencode C library, provides API for creating QR Code barcode images (PNG, JPEG thanks to GD2). Implemented purely in PHP, with no external dependencies (except GD2 if needed).

Some of library features includes:

  • Supports QR Code versions (size) 1-40.
  • Numeric, Alphanumeric, 8-bit and Kanji encoding.
  • Implemented purely in PHP, no external dependencies except GD2.
  • Exports to PNG, JPEG images, also exports as bit-table.
  • TCPDF 2-D barcode API integration.
  • Easy to configure.
  • Data cache for calculation speed-up.
  • Provided merge tool helps deploy library as a one big dependency-less file, simple to "include and do not wory".
  • Debug data dump, error logging, time benchmarking.
  • API documentation.
  • Detailed examples.
  • 100% Open Source, LGPL Licensed.

The following snippet shows a working solution with PHP QR Code :

<?php
require_once("phpqrcode/qrlib.php");

// Path where the images will be saved
$filepath = 'examplefolder/myimage.png';
// Image (logo) to be drawn
$logopath = 'http://ourcodeworld.com/resources/img/ocw-empty.png';
// qr code content
$codeContents = 'http://ourcodeworld.com';
// Create the file in the providen path
// Customize how you want
QRcode::png($codeContents,$filepath , QR_ECLEVEL_H, 20);

// Start DRAWING LOGO IN QRCODE

$QR = imagecreatefrompng($filepath);

// START TO DRAW THE IMAGE ON THE QR CODE
$logo = imagecreatefromstring(file_get_contents($logopath));
$QR_width = imagesx($QR);
$QR_height = imagesy($QR);

$logo_width = imagesx($logo);
$logo_height = imagesy($logo);

// Scale logo to fit in the QR Code
$logo_qr_width = $QR_width/3;
$scale = $logo_width/$logo_qr_width;
$logo_qr_height = $logo_height/$scale;

imagecopyresampled($QR, $logo, $QR_width/3, $QR_height/3, 0, 0, $logo_qr_width, $logo_qr_height, $logo_width, $logo_height);

// Save QR code again, but with logo on it
imagepng($QR,$filepath);

// End DRAWING LOGO IN QR CODE

// Ouput image in the browser
echo '<img src="'.$filepath.'" />';
?>

Note: include the qrlib.php for full version (also you have to provide all library files form package plus cache dir) or phpqrcode.php for merged version (only one file, but slower and less accurate code because disabled cache and quicker masking configured).

Have fun !

Become a more social person