chore: complete update

This commit is contained in:
2025-07-17 16:24:20 +02:00
parent 899227b0a4
commit 64a7051137
1300 changed files with 85570 additions and 2756 deletions

View File

@@ -0,0 +1,204 @@
<?php
declare(strict_types=1);
namespace App\Domain\QrCode\Service;
use App\Domain\QrCode\ValueObject\MaskPattern;
class QrCodeMasker
{
/**
* Findet die beste Maske für die Matrix
*/
public function findBestMask(array $matrix, int $size): MaskPattern
{
$lowestPenalty = PHP_INT_MAX;
$bestMask = MaskPattern::PATTERN_0;
foreach (MaskPattern::cases() as $mask) {
$testMatrix = $matrix;
$this->applyMask($testMatrix, $size, $mask);
$penalty = $this->calculateMaskPenalty($testMatrix, $size);
if ($penalty < $lowestPenalty) {
$lowestPenalty = $penalty;
$bestMask = $mask;
}
}
return $bestMask;
}
/**
* Wendet eine Maske auf die Matrix an
*/
public function applyMask(array &$matrix, int $size, MaskPattern $maskPattern): void
{
for ($row = 0; $row < $size; $row++) {
for ($col = 0; $col < $size; $col++) {
if ($matrix[$row][$col] === null) {
continue;
}
if (!$this->isFunctionModule($row, $col, $size)) {
if ($maskPattern->shouldMask($row, $col)) {
$matrix[$row][$col] = !$matrix[$row][$col];
}
}
}
}
}
/**
* Berechnet die Strafpunkte für eine maskierte Matrix
*/
public function calculateMaskPenalty(array $matrix, int $size): int
{
$penalty = 0;
// Regel 1: Aufeinanderfolgende Module gleicher Farbe
$penalty += $this->evaluateConsecutiveModulesPenalty($matrix, $size);
// Regel 2: Blöcke gleicher Farbe
$penalty += $this->evaluateSameColorBlocksPenalty($matrix, $size);
// Regel 3: Muster, die Finder-Pattern ähneln
$penalty += $this->evaluateFinderPatternLikePenalty($matrix, $size);
// Regel 4: Ausgewogenheit schwarzer und weißer Module
$penalty += $this->evaluateBalancePenalty($matrix, $size);
return $penalty;
}
/**
* Evaluiert die Strafe für aufeinanderfolgende Module gleicher Farbe
*/
private function evaluateConsecutiveModulesPenalty(array $matrix, int $size): int
{
$penalty = 0;
// Zeilen prüfen
for ($row = 0; $row < $size; $row++) {
$count = 1;
for ($col = 1; $col < $size; $col++) {
if ($matrix[$row][$col] === $matrix[$row][$col - 1]) {
$count++;
} else {
if ($count >= 5) {
$penalty += 3 + ($count - 5);
}
$count = 1;
}
}
if ($count >= 5) {
$penalty += 3 + ($count - 5);
}
}
// Spalten prüfen
for ($col = 0; $col < $size; $col++) {
$count = 1;
for ($row = 1; $row < $size; $row++) {
if ($matrix[$row][$col] === $matrix[$row - 1][$col]) {
$count++;
} else {
if ($count >= 5) {
$penalty += 3 + ($count - 5);
}
$count = 1;
}
}
if ($count >= 5) {
$penalty += 3 + ($count - 5);
}
}
return $penalty;
}
/**
* Evaluiert die Strafe für 2x2 Blöcke gleicher Farbe
*/
private function evaluateSameColorBlocksPenalty(array $matrix, int $size): int
{
$penalty = 0;
for ($row = 0; $row < $size - 1; $row++) {
for ($col = 0; $col < $size - 1; $col++) {
$color = $matrix[$row][$col];
if ($color === $matrix[$row][$col + 1] &&
$color === $matrix[$row + 1][$col] &&
$color === $matrix[$row + 1][$col + 1]) {
$penalty += 3;
}
}
}
return $penalty;
}
/**
* Evaluiert die Strafe für Muster, die wie Finder-Pattern aussehen
*/
private function evaluateFinderPatternLikePenalty(array $matrix, int $size): int
{
$penalty = 0;
// Vereinfachte Implementation
return $penalty;
}
/**
* Evaluiert die Strafe für unausgewogene schwarze/weiße Module
*/
private function evaluateBalancePenalty(array $matrix, int $size): int
{
$darkCount = 0;
$totalCount = $size * $size;
for ($row = 0; $row < $size; $row++) {
for ($col = 0; $col < $size; $col++) {
if ($matrix[$row][$col] === true) {
$darkCount++;
}
}
}
$darkPercentage = $darkCount * 100 / $totalCount;
$deviation = abs($darkPercentage - 50) / 5;
return (int) ($deviation * 10);
}
/**
* Prüft, ob ein Modul ein Funktionsmodul ist (also nicht maskiert werden sollte)
*/
private function isFunctionModule(int $row, int $col, int $size): bool
{
// Finder-Pattern und Separatoren
if (($row < 9 && $col < 9) ||
($row < 9 && $col >= $size - 8) ||
($row >= $size - 8 && $col < 9)) {
return true;
}
// Timing-Pattern
if ($row === 6 || $col === 6) {
return true;
}
// Format-Informationen
if (($row < 9 && $col === 8) || ($row === 8 && $col < 9) ||
($row === 8 && $col >= $size - 8) || ($row >= $size - 8 && $col === 8)) {
return true;
}
// Dark Module bei Version 1
if ($row === 8 && $col === 13) {
return true;
}
return false;
}
}