diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..df55cd7
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,20 @@
+root = true
+
+[*]
+indent_style = space
+indent_size = 4
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = false
+
+[*.{vue,js,scss}]
+charset = utf-8
+indent_style = space
+indent_size = 2
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.md]
+trim_trailing_whitespace = false
\ No newline at end of file
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..9af3157
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,11 @@
+* text=auto
+
+/tests export-ignore
+.gitattributes export-ignore
+.gitignore export-ignore
+.scrutinizer.yml export-ignore
+.travis.yml export-ignore
+phpunit.php export-ignore
+phpunit.xml.dist export-ignore
+phpunit.xml export-ignore
+.php_cs export-ignore
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..497c4e2
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,8 @@
+.idea
+*.DS_Store
+/vendor
+/coverage
+sftp-config.json
+composer.lock
+.subsplit
+.php_cs.cache
diff --git a/.php_cs b/.php_cs
new file mode 100644
index 0000000..afd82dc
--- /dev/null
+++ b/.php_cs
@@ -0,0 +1,27 @@
+
+
+This source file is subject to the MIT license that is bundled.
+EOF;
+
+return PhpCsFixer\Config::create()
+ ->setRiskyAllowed(true)
+ ->setRules(array(
+ '@Symfony' => true,
+ 'header_comment' => array('header' => $header),
+ 'array_syntax' => array('syntax' => 'short'),
+ 'ordered_imports' => true,
+ 'no_useless_else' => true,
+ 'no_useless_return' => true,
+ 'php_unit_construct' => true,
+ 'php_unit_strict' => true,
+ ))
+ ->setFinder(
+ PhpCsFixer\Finder::create()
+ ->exclude('vendor')
+ ->in(__DIR__)
+ )
+;
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..c4c2864
--- /dev/null
+++ b/README.md
@@ -0,0 +1,19 @@
+
identicon-avatar
+
+ php生成identicon头像.
+
+
+## Installing
+
+```shell
+$ composer require valiner/identicon-avatar -vvv
+```
+
+## Usage
+
+TODO
+
+
+## License
+
+MIT
\ No newline at end of file
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..896131e
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,26 @@
+{
+ "name": "valiner\/identicon-avatar",
+ "description": "php生成identicon头像",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "valiner",
+ "email": "coder.sdp@gmail.com"
+ }
+ ],
+ "require": {
+ "phpunit/phpunit": "^7.5"
+ },
+ "autoload": {
+ "psr-4": {
+ "Valiner\\IdenticonAvatar\\": "./src/"
+ }
+ },
+ "extra": {
+ "laravel": {
+ "providers": [
+ "Valiner\\IdenticonAvatar\\ServiceProvider"
+ ]
+ }
+ }
+}
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
new file mode 100644
index 0000000..e47284c
--- /dev/null
+++ b/phpunit.xml.dist
@@ -0,0 +1,21 @@
+
+
+
+
+ ./tests/
+
+
+
+
+ src/
+
+
+
diff --git a/src/.gitkeep b/src/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/src/Generator/Generator.php b/src/Generator/Generator.php
new file mode 100644
index 0000000..d18ec57
--- /dev/null
+++ b/src/Generator/Generator.php
@@ -0,0 +1,57 @@
+generatedImage = imagecreatetruecolor($size, $size);
+ $perPixel = (int)$size/5;
+
+ $background = imagecolorallocate($this->generatedImage, 255, 255, 255);
+ imagefill($this->generatedImage, 0, 0, $background);
+ $gdColor = imagecolorallocate($this->generatedImage, $color[0], $color[1], $color[2]);
+
+ foreach ($matrixArr as $lineKey => $lineValue) {
+ foreach ($lineValue as $colKey => $colValue) {
+ if (true === $colValue) {
+ imagefilledrectangle($this->generatedImage, $colKey * $perPixel, $lineKey * $perPixel, ($colKey + 1) * $perPixel, ($lineKey + 1) * $perPixel, $gdColor);
+ }
+ }
+ }
+ return $this->generatedImage;
+ }
+
+ /**
+ * 获取图片
+ * @param $matrixArr
+ * @param $size
+ * @param $color
+ * @return false|string
+ */
+ public function getImage($matrixArr,$size,$color)
+ {
+ $imageResource = $this->getImageResource($matrixArr,$size,$color);
+ ob_start();
+ imagepng($imageResource);
+ $imageData = ob_get_contents();
+ ob_end_clean();
+ return $imageData;
+ }
+}
+
diff --git a/src/Identicon.php b/src/Identicon.php
new file mode 100644
index 0000000..6233901
--- /dev/null
+++ b/src/Identicon.php
@@ -0,0 +1,63 @@
+matrix = new Matrix();
+ $this->generator = new generator();
+ }
+
+ /**
+ * 输出图片到浏览器
+ * @param $str
+ * @param int $size
+ */
+ public function getAvatar($str, $size = 125)
+ {
+ $matrixArr = $this->matrix->getMatrix($str);
+ header('Content-Type: image/png');
+ echo $this->generator->getImage($matrixArr, $size, $this->matrix->getColor());
+
+ }
+
+ /**
+ * 保存图片
+ * @param $str
+ * @param int $size
+ * @param string $path
+ * @throws \Exception
+ */
+ public function saveAvatar($str, $size = 125, $path = '')
+ {
+ if (!$path) {
+ throw new \Exception('路径不能为空');
+ }
+ $matrixArr = $this->matrix->getMatrix($str);
+ imagepng($this->generator->getImageResource($matrixArr, $size, $this->matrix->getColor()), $path);
+ }
+
+ /**
+ * 获取base64
+ * @param $str
+ * @param int $size
+ * @return string
+ */
+ public function getAvatarDataUri($str, $size = 125)
+ {
+ $matrixArr = $this->matrix->getMatrix($str);
+ $imageData = $this->generator->getImage($matrixArr, $size, $this->matrix->getColor());
+ return sprintf('data:%s;base64,%s', 'image/png', base64_encode($imageData));
+ }
+}
+
+$ide = new Identicon();
+$ide->getAvatarDataUri('sdp', 25);
\ No newline at end of file
diff --git a/src/Matrix/Matrix.php b/src/Matrix/Matrix.php
new file mode 100644
index 0000000..560be61
--- /dev/null
+++ b/src/Matrix/Matrix.php
@@ -0,0 +1,90 @@
+setColor($this->converColor($hex));
+ foreach ($hexArr as $line => $val) {
+ $hexArr[$line] = (bool)round(hexdec($val) / pow(2, 7));
+ }
+ $matrix = $this->getMatrixArr($hexArr);
+ return $matrix;
+ }
+
+ /**
+ * 获取背景色
+ * @param $hexadecimal
+ * @return array
+ */
+ public function converColor($hexadecimal)
+ {
+ return [base_convert(substr($hexadecimal, 0, 2), 16, 10),
+ base_convert(substr($hexadecimal, 2, 2), 16, 10),
+ base_convert(substr($hexadecimal, 4, 2), 16, 10)];
+ }
+
+
+ /**
+ * 组装矩阵
+ * @param $hexArr
+ * @return array
+ */
+ public function getMatrixArr($hexArr)
+ {
+ $matrixLeft = [];
+ $matrix = [];
+ for ($i = 0; $i < count($hexArr) - 1; $i++) {
+ $matrixLeft[$i / 3][$i % 3] = $hexArr[$i];
+ }
+
+ array_unshift($matrixLeft, null);
+ $turnMatrixLeft = array_reverse(call_user_func_array("array_map", $matrixLeft));
+ array_unshift($turnMatrixLeft, null);
+ $matrixRight = call_user_func_array("array_map", $turnMatrixLeft);
+ array_shift($matrixLeft);
+
+ for ($i = 0; $i < count($matrixLeft); $i++) {
+ for ($j = 0; $j < count($matrixLeft); $j++) {
+ if ($j <= count($matrixLeft) / 2) {
+ $matrix[$i][$j] = $matrixLeft[$i][$j];
+ } else {
+ $matrix[$i][$j] = $matrixRight[$i][$j - count($matrixLeft[$i]) + 1];
+ }
+ }
+ }
+ return $matrix;
+ }
+
+
+ /**
+ * @return array
+ */
+ public function getColor(): array
+ {
+ return $this->color;
+ }
+
+ /**
+ * @param array $color
+ */
+ public function setColor(array $color): void
+ {
+ $this->color = $color;
+ }
+
+
+}
diff --git a/src/ServiceProvider.php b/src/ServiceProvider.php
new file mode 100644
index 0000000..3a349e9
--- /dev/null
+++ b/src/ServiceProvider.php
@@ -0,0 +1,23 @@
+app->singleton(Identicon::class, function(){
+ return new Identicon();
+ });
+
+ $this->app->alias(Identicon::class, 'identicon');
+ }
+
+ public function provides()
+ {
+ return [Identicon::class, 'identicon'];
+ }
+}
\ No newline at end of file
diff --git a/tests/.gitkeep b/tests/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/tests/IdenticonTest.php b/tests/IdenticonTest.php
new file mode 100644
index 0000000..8917655
--- /dev/null
+++ b/tests/IdenticonTest.php
@@ -0,0 +1,22 @@
+saveAvatar('sdp',25,'sdp.png');
+ $this->assertTrue(true);
+ }
+
+ public function testGetAvatarDataUri(){
+ $ide = new Identicon();
+ $ide->getAvatarDataUri('sdp',25);
+ $this->assertTrue(true);
+ }
+}
\ No newline at end of file