getModuleAt(8, $col)->isDark() ? '1' : '0'; } echo "Our QR Code:\n"; echo " Format Info: $ourFormat\n"; echo " Decoded: M, Mask 2\n\n"; // 2. Load Python reference $pythonImg = imagecreatefrompng('/var/www/html/public/qrcode-python-large.png'); function getPythonBit($img, $row, $col): string { $scale = 20; $qz = 4; $x = ($qz + $col) * $scale + 10; $y = ($qz + $row) * $scale + 10; $rgb = imagecolorat($img, $x, $y); $r = ($rgb >> 16) & 0xFF; return $r < 128 ? '1' : '0'; } $pythonFormat = ''; foreach ($formatCols as $col) { $pythonFormat .= getPythonBit($pythonImg, 8, $col); } echo "Python QR Code:\n"; echo " Format Info: $pythonFormat\n"; echo " Decoded: M, Mask 0\n\n"; // 3. Create comparison image (side-by-side) $scale = 15; $qz = 4; $qrSize = ($size + 2 * $qz) * $scale; $totalWidth = $qrSize * 2 + 60; // Two QR codes + spacing $totalHeight = $qrSize + 80; $image = imagecreatetruecolor($totalWidth, $totalHeight); $white = imagecolorallocate($image, 255, 255, 255); $black = imagecolorallocate($image, 0, 0, 0); $red = imagecolorallocate($image, 255, 0, 0); $gray = imagecolorallocate($image, 200, 200, 200); imagefill($image, 0, 0, $white); // Draw labels imagestring($image, 5, 40, 10, "OUR CODE (Mask 2)", $black); imagestring($image, 5, $qrSize + 80, 10, "PYTHON (Mask 0 - WORKS!)", $black); // Draw grid background for ($r = 0; $r < $size; $r++) { for ($c = 0; $c < $size; $c++) { // Our code (left) $x1 = ($qz + $c) * $scale + 20; $y1 = ($qz + $r) * $scale + 40; imagerectangle($image, $x1, $y1, $x1+$scale-1, $y1+$scale-1, $gray); // Python (right) $x2 = $qrSize + 40 + ($qz + $c) * $scale; $y2 = ($qz + $r) * $scale + 40; imagerectangle($image, $x2, $y2, $x2+$scale-1, $y2+$scale-1, $gray); } } // Draw modules $diffCount = 0; for ($r = 0; $r < $size; $r++) { for ($c = 0; $c < $size; $c++) { $ourDark = $ourMatrix->getModuleAt($r, $c)->isDark(); $pythonDark = getPythonBit($pythonImg, $r, $c) === '1'; // Our code if ($ourDark) { $x = ($qz + $c) * $scale + 20; $y = ($qz + $r) * $scale + 40; imagefilledrectangle($image, $x, $y, $x+$scale-1, $y+$scale-1, $black); } // Python code if ($pythonDark) { $x = $qrSize + 40 + ($qz + $c) * $scale; $y = ($qz + $r) * $scale + 40; imagefilledrectangle($image, $x, $y, $x+$scale-1, $y+$scale-1, $black); } // Mark differences in red if ($ourDark !== $pythonDark) { $diffCount++; // Mark on our code $x = ($qz + $c) * $scale + 20 + $scale/2; $y = ($qz + $r) * $scale + 40 + $scale/2; imagefilledellipse($image, (int)$x, (int)$y, 3, 3, $red); } } } // Add diff count $diffText = "Differences: $diffCount modules (" . number_format($diffCount / 441 * 100, 1) . "%)"; imagestring($image, 3, 20, $qrSize + 50, $diffText, $black); imagepng($image, '/var/www/html/public/qr-comparison.png'); imagedestroy($image); imagedestroy($pythonImg); echo "✅ Generated comparison: qr-comparison.png\n"; echo " Differences: $diffCount / 441 modules (" . number_format($diffCount / 441 * 100, 1) . "%)\n"; echo "\nURL: https://localhost/qr-comparison.png\n";