File size: 3,323 Bytes
0d5b03e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
<?php

namespace Zxing;

use Zxing\Common\HybridBinarizer;
use Zxing\Qrcode\QRCodeReader;

final class QrReader
{
    const SOURCE_TYPE_FILE     = 'file';
    const SOURCE_TYPE_BLOB     = 'blob';
    const SOURCE_TYPE_RESOURCE = 'resource';

    private $bitmap;
    private $reader;
    private $result;

    public function __construct($imgSource, $sourceType = QrReader::SOURCE_TYPE_FILE, $useImagickIfAvailable = true)
    {
        if (!in_array($sourceType, [
            self::SOURCE_TYPE_FILE,
            self::SOURCE_TYPE_BLOB,
            self::SOURCE_TYPE_RESOURCE,
        ], true)) {
            throw new \InvalidArgumentException('Invalid image source.');
        }
        $im = null;
        switch ($sourceType) {
            case QrReader::SOURCE_TYPE_FILE:
                if ($useImagickIfAvailable && extension_loaded('imagick')) {
                    $im = new \Imagick();
                    $im->readImage($imgSource);
                } else {
                    $image = file_get_contents($imgSource);
                    $im    = imagecreatefromstring($image);
                }
                break;

            case QrReader::SOURCE_TYPE_BLOB:
                if ($useImagickIfAvailable && extension_loaded('imagick')) {
                    $im = new \Imagick();
                    $im->readImageBlob($imgSource);
                } else {
                    $im = imagecreatefromstring($imgSource);
                }
                break;

            case QrReader::SOURCE_TYPE_RESOURCE:
                $im = $imgSource;
                if ($useImagickIfAvailable && extension_loaded('imagick')) {
                    $useImagickIfAvailable = true;
                } else {
                    $useImagickIfAvailable = false;
                }
                break;
        }
        if ($useImagickIfAvailable && extension_loaded('imagick')) {
            if (!$im instanceof \Imagick) {
                throw new \InvalidArgumentException('Invalid image source.');
            }
            $width  = $im->getImageWidth();
            $height = $im->getImageHeight();
            $source = new IMagickLuminanceSource($im, $width, $height);
        } else {
            if (!is_resource($im) && !is_object($im)) {
                throw new \InvalidArgumentException('Invalid image source.');
            }
            $width  = imagesx($im);
            $height = imagesy($im);
            $source = new GDLuminanceSource($im, $width, $height);
        }
        $histo        = new HybridBinarizer($source);
        $this->bitmap = new BinaryBitmap($histo);
        $this->reader = new QRCodeReader();
    }

    public function decode()
    {
        try {
            $this->result = $this->reader->decode($this->bitmap);
        } catch (NotFoundException $er) {
            $this->result = false;
        } catch (FormatException $er) {
            $this->result = false;
        } catch (ChecksumException $er) {
            $this->result = false;
        }
    }

    public function text()
    {
        $this->decode();

        if ($this->result !== false && method_exists($this->result, 'toString')) {
            return $this->result->toString();
        }

        return $this->result;
    }

    public function getResult()
    {
        return $this->result;
    }
}