Co-authored-by: zeripath <art27@cantab.net>tags/v1.21.12.1
| @@ -54,7 +54,7 @@ require ( | |||||
| github.com/hashicorp/go-retryablehttp v0.6.6 // indirect | github.com/hashicorp/go-retryablehttp v0.6.6 // indirect | ||||
| github.com/huandu/xstrings v1.3.0 | github.com/huandu/xstrings v1.3.0 | ||||
| github.com/issue9/assert v1.3.2 // indirect | github.com/issue9/assert v1.3.2 // indirect | ||||
| github.com/issue9/identicon v0.0.0-20160320065130-d36b54562f4c | |||||
| github.com/issue9/identicon v1.0.1 | |||||
| github.com/jaytaylor/html2text v0.0.0-20160923191438-8fb95d837f7d | github.com/jaytaylor/html2text v0.0.0-20160923191438-8fb95d837f7d | ||||
| github.com/jmhodges/levigo v1.0.0 // indirect | github.com/jmhodges/levigo v1.0.0 // indirect | ||||
| github.com/joho/godotenv v1.3.0 // indirect | github.com/joho/godotenv v1.3.0 // indirect | ||||
| @@ -372,10 +372,11 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO | |||||
| github.com/huandu/xstrings v1.3.0 h1:gvV6jG9dTgFEncxo+AF7PH6MZXi/vZl25owA/8Dg8Wo= | github.com/huandu/xstrings v1.3.0 h1:gvV6jG9dTgFEncxo+AF7PH6MZXi/vZl25owA/8Dg8Wo= | ||||
| github.com/huandu/xstrings v1.3.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= | github.com/huandu/xstrings v1.3.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= | ||||
| github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= | github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= | ||||
| github.com/issue9/assert v1.3.1/go.mod h1:9Ger+iz8X7r1zMYYwEhh++2wMGWcNN2oVI+zIQXxcio= | |||||
| github.com/issue9/assert v1.3.2 h1:IaTa37u4m1fUuTH9K9ldO5IONKVDXjLiUO1T9vj0OF0= | github.com/issue9/assert v1.3.2 h1:IaTa37u4m1fUuTH9K9ldO5IONKVDXjLiUO1T9vj0OF0= | ||||
| github.com/issue9/assert v1.3.2/go.mod h1:9Ger+iz8X7r1zMYYwEhh++2wMGWcNN2oVI+zIQXxcio= | github.com/issue9/assert v1.3.2/go.mod h1:9Ger+iz8X7r1zMYYwEhh++2wMGWcNN2oVI+zIQXxcio= | ||||
| github.com/issue9/identicon v0.0.0-20160320065130-d36b54562f4c h1:A/PDn117UYld5mlxe58EpMguqpkeTMw5/FCo0ZPS/Ko= | |||||
| github.com/issue9/identicon v0.0.0-20160320065130-d36b54562f4c/go.mod h1:5mTb/PQNkqmq2x3IxlQZE0aSnTksJg7fg/oWmJ5SKXQ= | |||||
| github.com/issue9/identicon v1.0.1 h1:pCDfjMDM6xWK0Chxo8Lif+ST/nOEtmXgMITgV1YA9Og= | |||||
| github.com/issue9/identicon v1.0.1/go.mod h1:UKNVkUFI68RPz/RlLhsAr1aX6bBSaYEWRHVfdjrMUmk= | |||||
| github.com/jarcoal/httpmock v0.0.0-20180424175123-9c70cfe4a1da/go.mod h1:ks+b9deReOc7jgqp+e7LuFiCBH6Rm5hL32cLcEAArb4= | github.com/jarcoal/httpmock v0.0.0-20180424175123-9c70cfe4a1da/go.mod h1:ks+b9deReOc7jgqp+e7LuFiCBH6Rm5hL32cLcEAArb4= | ||||
| github.com/jaytaylor/html2text v0.0.0-20160923191438-8fb95d837f7d h1:ig/iUfDDg06RVW8OMby+GrmW6K2nPO3AFHlEIdvJSd4= | github.com/jaytaylor/html2text v0.0.0-20160923191438-8fb95d837f7d h1:ig/iUfDDg06RVW8OMby+GrmW6K2nPO3AFHlEIdvJSd4= | ||||
| github.com/jaytaylor/html2text v0.0.0-20160923191438-8fb95d837f7d/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk= | github.com/jaytaylor/html2text v0.0.0-20160923191438-8fb95d837f7d/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk= | ||||
| @@ -29,4 +29,4 @@ _testmain.go | |||||
| #osx | #osx | ||||
| .DS_Store | .DS_Store | ||||
| testdata | |||||
| /testdata/*.png | |||||
| @@ -1,10 +1,20 @@ | |||||
| language: go | language: go | ||||
| os: | |||||
| - linux | |||||
| - osx | |||||
| - windows | |||||
| go: | go: | ||||
| - tip | |||||
| - 1.6 | |||||
| - 1.5 | |||||
| - 1.4 | |||||
| - 1.3 | |||||
| install: | |||||
| - go get github.com/issue9/assert | |||||
| - mkdir ./testdata | |||||
| - tip | |||||
| - 1.12 | |||||
| - 1.11 | |||||
| script: | |||||
| - GO111MODULE=on go test -v -coverprofile=coverage.txt -covermode=atomic ./... | |||||
| after_success: bash <(curl -s https://codecov.io/bash) | |||||
| matrix: | |||||
| allow_failures: | |||||
| - go: tip | |||||
| @@ -1,7 +1,8 @@ | |||||
| identicon [](https://travis-ci.org/issue9/identicon) | |||||
| identicon | |||||
| [](https://travis-ci.org/issue9/identicon) | |||||
| ====== | ====== | ||||
| 根据用户的IP、邮箱名等任意数据为用户产生漂亮的随机头像。 | |||||
| 根据用户的 IP 、邮箱名等任意数据为用户产生漂亮的随机头像。 | |||||
|  |  | ||||
|  |  | ||||
| @@ -31,10 +32,10 @@ go get github.com/issue9/identicon | |||||
| ### 文档 | ### 文档 | ||||
| [](http://gowalker.org/github.com/issue9/identicon) | |||||
| [](https://gowalker.org/github.com/issue9/identicon) | |||||
| [](https://godoc.org/github.com/issue9/identicon) | [](https://godoc.org/github.com/issue9/identicon) | ||||
| ### 版权 | ### 版权 | ||||
| 本项目采用[MIT](http://opensource.org/licenses/MIT)开源授权许可证,完整的授权说明可在[LICENSE](LICENSE)文件中找到。 | |||||
| 本项目采用 [MIT](https://opensource.org/licenses/MIT) 开源授权许可证,完整的授权说明可在 [LICENSE](LICENSE) 文件中找到。 | |||||
| @@ -21,14 +21,14 @@ var ( | |||||
| blocks = []blockFunc{b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, b16} | blocks = []blockFunc{b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, b16} | ||||
| ) | ) | ||||
| // 所有block函数的类型 | |||||
| // 所有 block 函数的类型 | |||||
| type blockFunc func(img *image.Paletted, x, y, size float64, angle int) | type blockFunc func(img *image.Paletted, x, y, size float64, angle int) | ||||
| // 将多边形points旋转angle个角度,然后输出到img上,起点为x,y坐标 | |||||
| // 将多边形 points 旋转 angle 个角度,然后输出到 img 上,起点为 x,y 坐标 | |||||
| func drawBlock(img *image.Paletted, x, y, size float64, angle int, points []float64) { | func drawBlock(img *image.Paletted, x, y, size float64, angle int, points []float64) { | ||||
| if angle > 0 { // 0角度不需要转换 | |||||
| // 中心坐标与x,y的距离,方便下面指定中心坐标(x+m,y+m), | |||||
| // 0.5的偏移值不能少,否则坐靠右,非正中央 | |||||
| if angle > 0 { // 0 角度不需要转换 | |||||
| // 中心坐标与 x、y 的距离,方便下面指定中心坐标(x+m,y+m), | |||||
| // 0.5 的偏移值不能少,否则坐标靠右,非正中央 | |||||
| m := size/2 - 0.5 | m := size/2 - 0.5 | ||||
| rotate(points, x+m, y+m, angle) | rotate(points, x+m, y+m, angle) | ||||
| } | } | ||||
| @@ -2,14 +2,14 @@ | |||||
| // Use of this source code is governed by a MIT | // Use of this source code is governed by a MIT | ||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||
| // 一个基于hash值生成随机图像的包。 | |||||
| // Package identicon 一个基于 hash 值生成随机图像的包。 | |||||
| // | // | ||||
| // 关于identicon并没有统一的标准,一般用于在用户注册时, | |||||
| // 取用户的邮箱或是访问IP等数据(也可以是其它任何数据), | |||||
| // 进行hash运算,之后根据hash数据,产生一张图像, | |||||
| // identicon 并没有统一的标准,一般用于在用户注册时, | |||||
| // 取用户的邮箱或是访问 IP 等数据(也可以是其它任何数据), | |||||
| // 进行 hash 运算,之后根据 hash 数据,产生一张图像, | |||||
| // 这样即可以为用户产生一张独特的头像,又不会泄漏用户的隐藏。 | // 这样即可以为用户产生一张独特的头像,又不会泄漏用户的隐藏。 | ||||
| // | // | ||||
| // 在identicon中,把图像分成以下九个部分: | |||||
| // 在 identicon 中,把图像分成以下九个部分: | |||||
| // ------------- | // ------------- | ||||
| // | 1 | 2 | 3 | | // | 1 | 2 | 3 | | ||||
| // ------------- | // ------------- | ||||
| @@ -17,11 +17,11 @@ | |||||
| // ------------- | // ------------- | ||||
| // | 7 | 8 | 9 | | // | 7 | 8 | 9 | | ||||
| // ------------- | // ------------- | ||||
| // 其中1、3、9、7为不同角度(依次增加90度)的同一张图片, | |||||
| // 2、6、8、4也是如此,这样可以保持图像是对称的,比较美观。 | |||||
| // 5则单独使用一张图片。 | |||||
| // 其中 1、3、9、7 为不同角度(依次增加 90 度)的同一张图片, | |||||
| // 2、6、8、4 也是如此,这样可以保持图像是对称的,比较美观。 | |||||
| // 5 则单独使用一张图片。 | |||||
| // | // | ||||
| // // 根据用户访问的IP,为其生成一张头像 | |||||
| // // 根据用户访问的 IP ,为其生成一张头像 | |||||
| // img, _ := identicon.Make(128, color.NRGBA{},color.NRGBA{}, []byte("192.168.1.1")) | // img, _ := identicon.Make(128, color.NRGBA{},color.NRGBA{}, []byte("192.168.1.1")) | ||||
| // fi, _ := os.Create("/tmp/u1.png") | // fi, _ := os.Create("/tmp/u1.png") | ||||
| // png.Encode(fi, img) | // png.Encode(fi, img) | ||||
| @@ -32,6 +32,6 @@ | |||||
| // img := ii.Make([]byte("192.168.1.1")) | // img := ii.Make([]byte("192.168.1.1")) | ||||
| // img = ii.Make([]byte("192.168.1.2")) | // img = ii.Make([]byte("192.168.1.2")) | ||||
| // | // | ||||
| // NOTE: go test 会在当前目录的testdata文件夹下产生大量的随机图片。 | |||||
| // NOTE: go test 会在当前目录的 testdata 文件夹下产生大量的随机图片。 | |||||
| // 要运行测试,必须保证该文件夹是存在的,且有相应的写入权限。 | // 要运行测试,必须保证该文件夹是存在的,且有相应的写入权限。 | ||||
| package identicon | package identicon | ||||
| @@ -0,0 +1,3 @@ | |||||
| module github.com/issue9/identicon | |||||
| require github.com/issue9/assert v1.3.1 | |||||
| @@ -0,0 +1,2 @@ | |||||
| github.com/issue9/assert v1.3.1 h1:L8pRpbnzMIPFJqrMKR/oG03uWrtVeZyYBpI2U2Jx1JE= | |||||
| github.com/issue9/assert v1.3.1/go.mod h1:9Ger+iz8X7r1zMYYwEhh++2wMGWcNN2oVI+zIQXxcio= | |||||
| @@ -25,11 +25,10 @@ type Identicon struct { | |||||
| rect image.Rectangle | rect image.Rectangle | ||||
| } | } | ||||
| // 声明一个Identicon实例。 | |||||
| // size表示整个头像的大小。 | |||||
| // back表示前景色。 | |||||
| // fore表示所有可能的前景色,会为每个图像随机挑选一个作为其前景色。 | |||||
| // NOTE:前景色不要与背景色太相近。 | |||||
| // New 声明一个 Identicon 实例。 | |||||
| // size 表示整个头像的大小; | |||||
| // back 表示前景色; | |||||
| // fore 表示所有可能的前景色,会为每个图像随机挑选一个作为其前景色。 | |||||
| func New(size int, back color.Color, fore ...color.Color) (*Identicon, error) { | func New(size int, back color.Color, fore ...color.Color) (*Identicon, error) { | ||||
| if len(fore) == 0 || len(fore) > maxForeColors { | if len(fore) == 0 || len(fore) > maxForeColors { | ||||
| return nil, fmt.Errorf("前景色数量必须介于[1]~[%v]之间,当前为[%v]", maxForeColors, len(fore)) | return nil, fmt.Errorf("前景色数量必须介于[1]~[%v]之间,当前为[%v]", maxForeColors, len(fore)) | ||||
| @@ -49,7 +48,7 @@ func New(size int, back color.Color, fore ...color.Color) (*Identicon, error) { | |||||
| }, nil | }, nil | ||||
| } | } | ||||
| // 根据data数据产生一张唯一性的头像图片。 | |||||
| // Make 根据 data 数据产生一张唯一性的头像图片。 | |||||
| func (i *Identicon) Make(data []byte) image.Image { | func (i *Identicon) Make(data []byte) image.Image { | ||||
| h := md5.New() | h := md5.New() | ||||
| h.Write(data) | h.Write(data) | ||||
| @@ -78,7 +77,7 @@ func (i *Identicon) Make(data []byte) image.Image { | |||||
| return p | return p | ||||
| } | } | ||||
| // 根据data数据产生一张唯一性的头像图片。 | |||||
| // Make 根据 data 数据产生一张唯一性的头像图片。 | |||||
| // size 头像的大小。 | // size 头像的大小。 | ||||
| // back, fore头像的背景和前景色。 | // back, fore头像的背景和前景色。 | ||||
| func Make(size int, back, fore color.Color, data []byte) (image.Image, error) { | func Make(size int, back, fore color.Color, data []byte) (image.Image, error) { | ||||
| @@ -112,16 +111,16 @@ func Make(size int, back, fore color.Color, data []byte) (image.Image, error) { | |||||
| } | } | ||||
| // 将九个方格都填上内容。 | // 将九个方格都填上内容。 | ||||
| // p为画板。 | |||||
| // c为中间方格的填充函数。 | |||||
| // b1,b2为边上8格的填充函数。 | |||||
| // angle为b1,b2的起始旋转角度。 | |||||
| // p 为画板; | |||||
| // c 为中间方格的填充函数; | |||||
| // b1、b2 为边上 8 格的填充函数; | |||||
| // angle 为 b1、b2 的起始旋转角度。 | |||||
| func drawBlocks(p *image.Paletted, size int, c, b1, b2 blockFunc, angle int) { | func drawBlocks(p *image.Paletted, size int, c, b1, b2 blockFunc, angle int) { | ||||
| // 每个格子的长宽。先转换成float,再计算! | |||||
| // 每个格子的长宽。先转换成 float,再计算! | |||||
| blockSize := float64(size) / 3 | blockSize := float64(size) / 3 | ||||
| twoBlockSize := 2 * blockSize | twoBlockSize := 2 * blockSize | ||||
| incr := func() { // 增加angle的值,但不会大于3 | |||||
| incr := func() { // 增加 angle 的值,但不会大于 3 | |||||
| angle++ | angle++ | ||||
| if angle > 3 { | if angle > 3 { | ||||
| angle = 0 | angle = 0 | ||||
| @@ -5,15 +5,15 @@ | |||||
| package identicon | package identicon | ||||
| var ( | var ( | ||||
| // 4个元素分别表示cos(0),cos(90),cos(180),cos(270) | |||||
| // 4个元素分别表示 cos(0),cos(90),cos(180),cos(270) | |||||
| cos = []float64{1, 0, -1, 0} | cos = []float64{1, 0, -1, 0} | ||||
| // 4个元素分别表示sin(0),sin(90),sin(180),sin(270) | |||||
| // 4个元素分别表示 sin(0),sin(90),sin(180),sin(270) | |||||
| sin = []float64{0, 1, 0, -1} | sin = []float64{0, 1, 0, -1} | ||||
| ) | ) | ||||
| // 将points中的所有点,以x,y为原点旋转angle个角度。 | |||||
| // angle取值只能是[0,1,2,3],分别表示[0,90,180,270] | |||||
| // 将 points 中的所有点,以 x,y 为原点旋转 angle 个角度。 | |||||
| // angle 取值只能是 [0,1,2,3],分别表示 [0,90,180,270] | |||||
| func rotate(points []float64, x, y float64, angle int) { | func rotate(points []float64, x, y float64, angle int) { | ||||
| if angle < 0 || angle > 3 { | if angle < 0 || angle > 3 { | ||||
| panic("rotate:参数angle必须0,1,2,3三值之一") | panic("rotate:参数angle必须0,1,2,3三值之一") | ||||
| @@ -39,8 +39,8 @@ func pointInPolygon(x float64, y float64, points []float64) bool { | |||||
| // 把整个平面以给定的测试点为原点分两部分: | // 把整个平面以给定的测试点为原点分两部分: | ||||
| // - y>0,包含(x>0 && y==0) | // - y>0,包含(x>0 && y==0) | ||||
| // - y<0,包含(x<0 && y==0) | // - y<0,包含(x<0 && y==0) | ||||
| // 依次扫描每一个点,当该点与前一个点处于不同部分时(即一个在y>0区,一个在y<0区), | |||||
| // 则判断从前一点到当前点是顺时针还是逆时针(以给定的测试点为原点),如果是顺时针r++,否则r--。 | |||||
| // 依次扫描每一个点,当该点与前一个点处于不同部分时(即一个在 y>0 区,一个在 y<0 区), | |||||
| // 则判断从前一点到当前点是顺时针还是逆时针(以给定的测试点为原点),如果是顺时针 r++,否则 r--。 | |||||
| // 结果为:2==abs(r)。 | // 结果为:2==abs(r)。 | ||||
| r := 0 | r := 0 | ||||
| @@ -387,7 +387,7 @@ github.com/hashicorp/hcl/json/token | |||||
| github.com/huandu/xstrings | github.com/huandu/xstrings | ||||
| # github.com/issue9/assert v1.3.2 | # github.com/issue9/assert v1.3.2 | ||||
| ## explicit | ## explicit | ||||
| # github.com/issue9/identicon v0.0.0-20160320065130-d36b54562f4c | |||||
| # github.com/issue9/identicon v1.0.1 | |||||
| ## explicit | ## explicit | ||||
| github.com/issue9/identicon | github.com/issue9/identicon | ||||
| # github.com/jaytaylor/html2text v0.0.0-20160923191438-8fb95d837f7d | # github.com/jaytaylor/html2text v0.0.0-20160923191438-8fb95d837f7d | ||||