Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create a QR-Code Image with the php imagick library

enter image description here

Hi,

We are using imagick for different image manipulations and have a request to add QR watermarks in the end.

Right now I could only find PHP QR Code library which uses the GD2 library:

Implemented purely in PHP, no external dependencies except GD2

Is there any php snippet or library which uses imagick to create QR codes?

like image 497
jantimon Avatar asked Jan 17 '23 22:01

jantimon


2 Answers

Looking at the PHP QR Code library, there is only one file (I think) that accesses the GD library: qrimage.php. So change that file to output via imagick and use the rest of PHP QR Code.

Below is a possible imagick output file I wrote to replace qrimage.php. However, I am unable to test this code, since I am on Windows, and cannot install imagick.

Can someone please debug it, and edit this post with any corrections?

<?php
/*
 * PHP QR Code encoder
 *
 * Image output of code using GD2
 *
 * PHP QR Code is distributed under LGPL 3
 * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

    define('QR_IMAGE', true);

    class QRimage {

        //----------------------------------------------------------------------
        public static function png($frame, $filename = false, $pixelPerPoint = 4, $outerFrame = 4,$saveandprint=FALSE) 
        {
            $image = self::image($frame, $pixelPerPoint, $outerFrame, "png", 85, $filename, $saveandprint);
        }

        //----------------------------------------------------------------------
        public static function jpg($frame, $filename = false, $pixelPerPoint = 8, $outerFrame = 4, $q = 85) 
        {
            $image = self::image($frame, $pixelPerPoint, $outerFrame, "jpeg", $q, $filename, $saveandprint);
        }

        //----------------------------------------------------------------------
        private static function image($frame, $pixelPerPoint = 4, $outerFrame = 4, 
            $format = "png", $quality = 85, $filename = FALSE, $saveandprint = FALSE) 
        {
            $imgH = count($frame);
            $imgW = strlen($frame[0]);

            $col[0] = new ImagickPixel("white");
            $col[1] = new ImagickPixel("black");

            $image = new Imagick();
            $image->newImage($imgW, $imgH, $col[0]);

            $image->setCompressionQuality($quality);
            $image->setImageFormat($format); 

            $draw = new ImagickDraw();
            $draw->setFillColor($col[1]);

            for($y=0; $y<$imgH; $y++) {
                for($x=0; $x<$imgW; $x++) {
                    if ($frame[$y][$x] == '1') {
                        $draw->point($x,$y); 
                    }
                }
            }

            $image->drawImage($draw);
            $image->borderImage($col[0],$outerFrame,$outerFrame);
            $image->scaleImage( $imgW * $pixelPerPoint, 0 );

            if ($filename === FALSE) {
                Header("Content-type: image/jpeg");
                echo $image;
            } else {
                if($saveandprint===TRUE){
                    $image->writeImages($filename, true);        
                    Header("Content-type: image/" . $format);
                    echo $image;
                } else {
                    echo $image;
                }
            }
        }    
    }

There is a merged file called phpqrcode.php that contains the entire qrimage.php, so you will either have to remerge that file, or else replace the relevant section.

If you use a different filename for the above code, you will have to change the reference in the file qrlib.php and merge.php.

like image 91
iND Avatar answered Jan 31 '23 22:01

iND


I tested the above implementation and it worked. There is one mistake : you missed to add the outerframe in the final image size.

$image->scaleImage( ($imgW + 2*$outerFrame) * $pixelPerPoint, 0 );

Also, it seems that GD library is a lot faster than ImageMagick in this case.

I benched the use of GD and imagick on the creation of the same 50 random qr codes. I isolated the part were QR code are generated so in fact the use of QRimage::png.

I only teste png generation. These are my results :

GD :

  • min time : 0,0148401260 s
  • max time : 0,0211210251 s
  • average : 0,0167747593 s

ImageMagick :

  • min time : 0,0799968243 s
  • max time : 0,1147611141 s
  • average : 0,0918840790 s

In the final code, this makes a little difference. The other part of the code takes something like 0.15s to run and on a large amount of codes it makes a difference (I benched QRcode::png with a result like : 0.17s per qrcode ith GD and 0.24s per code with imagemagick).

like image 43
Alexandre Assouad Avatar answered Jan 31 '23 22:01

Alexandre Assouad