Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

readFromFile/readFromBlob result returning also the QR code coordinates inside the source image #248

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
21 changes: 20 additions & 1 deletion src/Decoder/Decoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ final class Decoder{
private EccLevel|null $eccLevel = null;
private MaskPattern|null $maskPattern = null;
private BitBuffer $bitBuffer;
private int $topLeftX;
private int $topLeftY;
private int $topRightX;
private int $topRightY;
private int $bottomLeftX;
private int $bottomLeftY;

public function __construct(SettingsContainerInterface|QROptions $options = new QROptions){
$this->options = $options;
Expand All @@ -45,7 +51,14 @@ public function __construct(SettingsContainerInterface|QROptions $options = new
* @throws \Throwable|\chillerlan\QRCode\Decoder\QRCodeDecoderException
*/
public function decode(LuminanceSourceInterface $source):DecoderResult{
$matrix = (new Detector($source))->detect();
$detector = new Detector($source);
$matrix = $detector->detect();
$this->topLeftX = $detector->topLeftX;
$this->topLeftY = $detector->topLeftY;
$this->topRightX = $detector->topRightX;
$this->topRightY = $detector->topRightY;
$this->bottomLeftX = $detector->bottomLeftX;
$this->bottomLeftY = $detector->bottomLeftY;
Copy link
Member

@codemasher codemasher Mar 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here I'd just assign the Detector instance to a property and call $this->detector->getFinderPatterns() only right before assigning the variables to the result object.

Further i think we could add a getCoordinates() method to the ResultPoint class, which does the floor()-ing and all


try{
// clone the BitMatrix to avoid errors in case we run into mirroring
Expand Down Expand Up @@ -159,6 +172,12 @@ private function decodeBitStream(BitBuffer $bitBuffer):DecoderResult{
'maskPattern' => $this->maskPattern,
'structuredAppendParity' => $parityData,
'structuredAppendSequence' => $symbolSequence,
'topLeftX' => $this->topLeftX,
'topLeftY' => $this->topLeftY,
'topRightX' => $this->topRightX,
'topRightY' => $this->topRightY,
'bottomLeftX' => $this->bottomLeftX,
'bottomLeftY' => $this->bottomLeftY,
]);
}

Expand Down
6 changes: 6 additions & 0 deletions src/Decoder/DecoderResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ final class DecoderResult{
private string $data = '';
private int $structuredAppendParity = -1;
private int $structuredAppendSequence = -1;
private int $topLeftX;
private int $topLeftY;
private int $topRightX;
private int $topRightY;
private int $bottomLeftX;
private int $bottomLeftY;
Copy link
Member

@codemasher codemasher Mar 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd just add 3 properties with the FinderPattern type here. I'm not sure yet what is returned when a pattern is not found - when in doubt, make the fields nullable. (edit: it seems like it will always return 3 instances)


/**
* DecoderResult constructor.
Expand Down
13 changes: 13 additions & 0 deletions src/Detector/Detector.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@
final class Detector{

private BitMatrix $matrix;
public int $topLeftX;
public int $topLeftY;
public int $topRightX;
public int $topRightY;
public int $bottomLeftX;
public int $bottomLeftY;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't do public properties here :)

I think we can hand down the whole result from the finder pattern finder as the objects hold other useful values such as the estimated module size, so just add one property (with a getter) that holds the result array private array|null $finderPatterns = null (nullable in case it gets called from the getter before Detector::detect() was called).


/**
* Detector constructor.
Expand All @@ -40,6 +46,13 @@ public function __construct(LuminanceSourceInterface $source){
public function detect():BitMatrix{
[$bottomLeft, $topLeft, $topRight] = (new FinderPatternFinder($this->matrix))->find();

$this->topLeftX = (int)floor($topLeft->getX());
$this->topLeftY = (int)floor($topLeft->getY());
$this->topRightX = (int)ceil($topRight->getX());
$this->topRightY = (int)floor($topRight->getY());
$this->bottomLeftX = (int)floor($bottomLeft->getX());
$this->bottomLeftY = (int)ceil($bottomLeft->getY());

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here just assign the result from the FinderPatternFinder call to the property and unpack the list from that property afterwards:

$this->finderPatterns = (new FinderPatternFinder($this->matrix))->find();
[$bottomLeft, $topLeft, $topRight] = $this->finderPatterns;

$moduleSize = $this->calculateModuleSize($topLeft, $topRight, $bottomLeft);
$dimension = $this->computeDimension($topLeft, $topRight, $bottomLeft, $moduleSize);
$provisionalVersion = new Version(intdiv(($dimension - 17), 4));
Expand Down