/** * Draw the image */ public function draw() { $moduleCount = $this->qrcode->getModuleCount(); $tileWidth = $this->width / $moduleCount; $tileHeight = $this->height / $moduleCount; $this->img = imagecreatetruecolor($this->width, $this->height); if ($this->img) { $fg = imagecolorallocate($this->img, 0, 0, 0); if ($fg === false) { $this->finish(); throw new QR_CodeImageException('Could not allocate foreground color!'); } $bg = imagecolorallocate($this->img, 255, 255, 255); if ($bg === false) { $this->finish(); throw new QR_CodeImageException('Could not allocate background color!'); } for ($row = 0; $row < $moduleCount; $row++) { for ($col = 0; $col < $moduleCount; $col++) { $fillStyle = $this->qrcode->isDark($row, $col) ? $fg : $bg; $x = round($col * $tileWidth); $y = round($row * $tileHeight); $w = ceil(($col + 1) * $tileWidth) - floor($col * $tileWidth); if ($x + $w > $this->width) { $w = $this->width - $x; } $h = ceil(($row + 1) * $tileWidth) - floor($row * $tileWidth); if ($y + $h > $this->height) { $h = $this->height - $y; } if (!imagefilledrectangle($this->img, $x, $y, $x + $w, $y + $h, $fillStyle)) { $this->finish(); throw new QR_CodeImageException(sprintf('Could not fill the rectangle using desired coordinates (x = %d, y = %d, w = %d, h = %d, c = %d)', $x, $y, $w, $h, $fillStyle)); } } } } else { throw new QR_CodeImageException('Could not create true color image buffer!'); } }
/** * Calculate the lost point * * @param QR_Code $qrCode * * @return number */ public function getLostPoint(QR_Code $qrCode) { $moduleCount = $qrCode->getModuleCount(); $lostPoint = 0; // Level 1 for ($row = 0; $row < $moduleCount; $row++) { for ($col = 0; $col < $moduleCount; $col++) { $sameCount = 0; $dark = $qrCode->isDark($row, $col); for ($r = -1; $r <= 1; $r++) { if ($row + $r < 0 || $moduleCount <= $row + $r) { continue; } for ($c = -1; $c <= 1; $c++) { if ($col + $c < 0 || $moduleCount <= $col + $c) { continue; } if ($r == 0 && $c == 0) { continue; } if ($dark == $qrCode->isDark($row + $r, $col + $c)) { $sameCount++; } } } if ($sameCount > 5) { $lostPoint += 3 + $sameCount - 5; } } } // Level 2 for ($row = 0; $row < $moduleCount - 1; $row++) { for ($col = 0; $col < $moduleCount - 1; $col++) { $count = 0; if ($qrCode->isDark($row, $col)) { $count++; } if ($qrCode->isDark($row + 1, $col)) { $count++; } if ($qrCode->isDark($row, $col + 1)) { $count++; } if ($qrCode->isDark($row + 1, $col + 1)) { $count++; } if ($count == 0 || $count == 4) { $lostPoint += 3; } } } // Level 3 for ($row = 0; $row < $moduleCount; $row++) { for ($col = 0; $col < $moduleCount - 6; $col++) { if ($qrCode->isDark($row, $col) && !$qrCode->isDark($row, $col + 1) && $qrCode->isDark($row, $col + 2) && $qrCode->isDark($row, $col + 3) && $qrCode->isDark($row, $col + 4) && !$qrCode->isDark($row, $col + 5) && $qrCode->isDark($row, $col + 6)) { $lostPoint += 40; } } } for ($col = 0; $col < $moduleCount; $col++) { for ($row = 0; $row < $moduleCount - 6; $row++) { if ($qrCode->isDark($row, $col) && !$qrCode->isDark($row + 1, $col) && $qrCode->isDark($row + 2, $col) && $qrCode->isDark($row + 3, $col) && $qrCode->isDark($row + 4, $col) && !$qrCode->isDark($row + 5, $col) && $qrCode->isDark($row + 6, $col)) { $lostPoint += 40; } } } // Level 4 $darkCount = 0; for ($col = 0; $col < $moduleCount; $col++) { for ($row = 0; $row < $moduleCount; $row++) { if ($qrCode->isDark($row, $col)) { $darkCount++; } } } $ratio = abs(100 * $darkCount / $moduleCount / $moduleCount - 50) / 5; $lostPoint += $ratio * 10; return $lostPoint; }