| <?php |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| namespace Zxing\Qrcode; |
|
|
| use Zxing\BinaryBitmap; |
| use Zxing\ChecksumException; |
| use Zxing\FormatException; |
| use Zxing\NotFoundException; |
| use Zxing\Reader; |
| use Zxing\Result; |
| use Zxing\Common\BitMatrix; |
| use Zxing\Qrcode\Decoder\Decoder; |
| use Zxing\Qrcode\Detector\Detector; |
|
|
| |
| |
| |
| |
| |
| class QRCodeReader implements Reader |
| { |
| private static $NO_POINTS = []; |
| private $decoder; |
|
|
| public function __construct() |
| { |
| $this->decoder = new Decoder(); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| public function decode(BinaryBitmap $image, $hints = null) |
| { |
| $decoderResult = null; |
| if ($hints !== null && $hints['PURE_BARCODE']) { |
| $bits = self::extractPureBits($image->getBlackMatrix()); |
| $decoderResult = $this->decoder->decode($bits, $hints); |
| $points = self::$NO_POINTS; |
| } else { |
| $detector = new Detector($image->getBlackMatrix()); |
| $detectorResult = $detector->detect($hints); |
|
|
| $decoderResult = $this->decoder->decode($detectorResult->getBits(), $hints); |
| $points = $detectorResult->getPoints(); |
| } |
| $result = new Result($decoderResult->getText(), $decoderResult->getRawBytes(), $points, 'QR_CODE'); |
|
|
| $byteSegments = $decoderResult->getByteSegments(); |
| if ($byteSegments !== null) { |
| $result->putMetadata('BYTE_SEGMENTS', $byteSegments); |
| } |
| $ecLevel = $decoderResult->getECLevel(); |
| if ($ecLevel !== null) { |
| $result->putMetadata('ERROR_CORRECTION_LEVEL', $ecLevel); |
| } |
| if ($decoderResult->hasStructuredAppend()) { |
| $result->putMetadata( |
| 'STRUCTURED_APPEND_SEQUENCE',//ResultMetadataType.STRUCTURED_APPEND_SEQUENCE |
| $decoderResult->getStructuredAppendSequenceNumber() |
| ); |
| $result->putMetadata( |
| 'STRUCTURED_APPEND_PARITY',//ResultMetadataType.STRUCTURED_APPEND_PARITY |
| $decoderResult->getStructuredAppendParity() |
| ); |
| } |
|
|
| return $result; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| private static function extractPureBits(BitMatrix $image) |
| { |
| $leftTopBlack = $image->getTopLeftOnBit(); |
| $rightBottomBlack = $image->getBottomRightOnBit(); |
| if ($leftTopBlack === null || $rightBottomBlack == null) { |
| throw NotFoundException::getNotFoundInstance(); |
| } |
|
|
| $moduleSize = self::moduleSize($leftTopBlack, $image); |
|
|
| $top = $leftTopBlack[1]; |
| $bottom = $rightBottomBlack[1]; |
| $left = $leftTopBlack[0]; |
| $right = $rightBottomBlack[0]; |
|
|
| |
| if ($left >= $right || $top >= $bottom) { |
| throw NotFoundException::getNotFoundInstance(); |
| } |
|
|
| if ($bottom - $top != $right - $left) { |
| |
| |
| $right = $left + ($bottom - $top); |
| } |
|
|
| $matrixWidth = round(($right - $left + 1) / $moduleSize); |
| $matrixHeight = round(($bottom - $top + 1) / $moduleSize); |
| if ($matrixWidth <= 0 || $matrixHeight <= 0) { |
| throw NotFoundException::getNotFoundInstance(); |
| } |
| if ($matrixHeight != $matrixWidth) { |
| |
| throw NotFoundException::getNotFoundInstance(); |
| } |
|
|
| |
| |
| |
| $nudge = (int)($moduleSize / 2.0); |
| $top += $nudge; |
| $left += $nudge; |
|
|
| |
| |
| |
| $nudgedTooFarRight = $left + (int)(($matrixWidth - 1) * $moduleSize) - $right; |
| if ($nudgedTooFarRight > 0) { |
| if ($nudgedTooFarRight > $nudge) { |
| |
| throw NotFoundException::getNotFoundInstance(); |
| } |
| $left -= $nudgedTooFarRight; |
| } |
| |
| $nudgedTooFarDown = $top + (int)(($matrixHeight - 1) * $moduleSize) - $bottom; |
| if ($nudgedTooFarDown > 0) { |
| if ($nudgedTooFarDown > $nudge) { |
| |
| throw NotFoundException::getNotFoundInstance(); |
| } |
| $top -= $nudgedTooFarDown; |
| } |
|
|
| |
| $bits = new BitMatrix($matrixWidth, $matrixHeight); |
| for ($y = 0; $y < $matrixHeight; $y++) { |
| $iOffset = $top + (int)($y * $moduleSize); |
| for ($x = 0; $x < $matrixWidth; $x++) { |
| if ($image->get($left + (int)($x * $moduleSize), $iOffset)) { |
| $bits->set($x, $y); |
| } |
| } |
| } |
|
|
| return $bits; |
| } |
|
|
| private static function moduleSize($leftTopBlack, BitMatrix $image) |
| { |
| $height = $image->getHeight(); |
| $width = $image->getWidth(); |
| $x = $leftTopBlack[0]; |
| $y = $leftTopBlack[1]; |
| |
| |
| $inBlack = true; |
| $transitions = 0; |
| while ($x < $width && $y < $height) { |
| if ($inBlack != $image->get($x, $y)) { |
| if (++$transitions == 5) { |
| break; |
| } |
| $inBlack = !$inBlack; |
| } |
| $x++; |
| $y++; |
| } |
| if ($x == $width || $y == $height) { |
| throw NotFoundException::getNotFoundInstance(); |
| } |
|
|
| return ($x - $leftTopBlack[0]) / 7.0; |
| } |
|
|
| public function reset() |
| { |
| |
| } |
|
|
| protected final function getDecoder() |
| { |
| return $this->decoder; |
| } |
| } |
|
|