diff --git a/app/Captcha/Contracts/Image.php b/app/Captcha/Contracts/Image.php new file mode 100644 index 0000000..15cb650 --- /dev/null +++ b/app/Captcha/Contracts/Image.php @@ -0,0 +1,17 @@ +image = imagecreatetruecolor($width, $height); + } + + public function getWidth(): int + { + return imagesx($this->image); + } + + public function getHeight(): int + { + return imagesy($this->image); + } + + public function insertBackground(string $pathToFile): ImageContract + { + list($backgroundWidth, $backgroundHeight) = getimagesize($pathToFile); + $background = $this->createImageFromPathToFile($pathToFile); + imagecopyresampled( + dst_image: $this->image, + src_image: $background, + dst_x: 0, + dst_y: 0, + src_x: 0, + src_y: 0, + dst_width: $this->getWidth(), + dst_height: $this->getHeight(), + src_width: $backgroundWidth, + src_height: $backgroundHeight + ); + imagedestroy($background); + + return $this; + } + + public function addText(string $text, int $x, int $y, float $size, float $angle, string $hexColor, string $fontName): Coordinators + { + $y += intval($size); + $result = imagefttext( + image: $this->image, + size: $size, + angle: $angle, + x: $x, + y: $y, + color: $this->colorConvertHexToColorIndex($hexColor), + font_filename: $fontName, + text: $text + ); + + return new Coordinators( + x1: $result[0], + y1: $result[1], + x2: $result[2], + y2: $result[3], + x3: $result[4], + y3: $result[5], + x4: $result[6], + y4: $result[7] + ); + } + + public function addLine(int $x1, int $y1, int $x2, int $y2, string $hexColor): self + { + imageline( + image: $this->image, + x1: $x1, + y1: $y1, + x2: $x2, + y2: $y2, + color: $this->colorConvertHexToColorIndex($hexColor) + ); + + return $this; + } + + public function encode(): string + { + ob_start(); + imagealphablending($this->image, false); + imagesavealpha($this->image, true); + imagepng($this->image, null, -1); + $mime = image_type_to_mime_type(IMAGETYPE_PNG); + $buffer = ob_get_contents(); + ob_end_clean(); + + return sprintf('data:%s;base64,%s', + $mime, + base64_encode($buffer) + ); + } + + public function __destruct() { + imagedestroy($this->image); + } + + private function createImageFromPathToFile(string $pathToFile): \GdImage + { + return match (mime_content_type($pathToFile)) { + 'image/jpeg' => imagecreatefromjpeg($pathToFile), + 'image/png' => imagecreatefrompng($pathToFile), + default => throw new CaptchaException('Couldn\'t open the file. Not a valid type. File ' . $pathToFile . '.') + }; + } + + private function colorConvertHexToColorIndex(string $hexColor): int + { + $hexColor = str_replace('#', '', $hexColor); + + if (strlen($hexColor) === 3) { + return imagecolorexact( + image: $this->image, + red: hexdec(str_repeat(substr($hexColor, 0, 1), 2)), + blue: hexdec(str_repeat(substr($hexColor, 1, 1), 2)), + green: hexdec(str_repeat(substr($hexColor, 2, 1), 2)) + ); + } + + $colorVal = hexdec($hexColor); + return imagecolorexact( + image: $this->image, + red: 0xFF & ($colorVal >> 0x10), + blue: 0xFF & ($colorVal >> 0x8), + green: 0xFF & $colorVal + ); + } +}