diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3f560cd --- /dev/null +++ b/.gitignore @@ -0,0 +1,40 @@ +# Reference https://github.com/github/gitignore/blob/master/Go.gitignore +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +vendor/ + +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# OS General +Thumbs.db +.DS_Store + +# project +*.cert +*.key +*.log +bin/ + +# Develop tools +.vscode/ +.idea/ +*.swp + +# project directories and files +logs/ +coverage.txt \ No newline at end of file diff --git a/draw.go b/draw.go index 629804a..7da04bd 100644 --- a/draw.go +++ b/draw.go @@ -20,6 +20,9 @@ type Options struct { Palette []color.Color LetterColor color.Color + // FontSize is used to set font size + FontSize int + // PaletteKey is used to pick the background color from the Palette. // Using the same PaletteKey leads to the same background color being picked. // If PaletteKey is empty (default) the background color is picked randomly. @@ -30,7 +33,7 @@ var defaultLetterColor = color.RGBA{0xf0, 0xf0, 0xf0, 0xf0} // Draw generates a new letter-avatar image of the given size using the given letter // with the given options. Default parameters are used if a nil *Options is passed. -func Draw(size int, letter rune, options *Options) (image.Image, error) { +func Draw(size int, letter []rune, options *Options) (image.Image, error) { font := defaultFont if options != nil && options.Font != nil { font = options.Font @@ -55,14 +58,18 @@ func Draw(size int, letter rune, options *Options) (image.Image, error) { } } - return drawAvatar(bgColor, letterColor, font, size, letter) + fontSize := float64(options.FontSize) + if options.FontSize == 0 { + fontSize = float64(size) * 0.6 + } + + return drawAvatar(bgColor, letterColor, font, size, fontSize, letter) } -func drawAvatar(bgColor, fgColor color.Color, font *truetype.Font, size int, letter rune) (image.Image, error) { +func drawAvatar(bgColor, fgColor color.Color, font *truetype.Font, size int, fontSize float64, letter []rune) (image.Image, error) { dst := newRGBA(size, size, bgColor) - fontSize := float64(size) * 0.6 - src, err := drawString(bgColor, fgColor, font, fontSize, string(letter)) + src, err := drawString(bgColor, fgColor, font, fontSize, letter) if err != nil { return nil, err } @@ -73,12 +80,15 @@ func drawAvatar(bgColor, fgColor color.Color, font *truetype.Font, size int, let return dst, nil } -func drawString(bgColor, fgColor color.Color, font *truetype.Font, fontSize float64, str string) (image.Image, error) { +func drawString(bgColor, fgColor color.Color, font *truetype.Font, fontSize float64, letter []rune) (image.Image, error) { c := freetype.NewContext() c.SetDPI(72) bb := font.Bounds(c.PointToFixed(fontSize)) w := bb.Max.X.Ceil() - bb.Min.X.Floor() + if len(letter) > 0 { + w = w + int(fontSize)*(len(letter)-1) + } h := bb.Max.Y.Ceil() - bb.Min.Y.Floor() dst := newRGBA(w, h, bgColor) @@ -90,7 +100,7 @@ func drawString(bgColor, fgColor color.Color, font *truetype.Font, fontSize floa c.SetFontSize(fontSize) c.SetFont(font) - p, err := c.DrawString(str, fixed.Point26_6{X: 0, Y: bb.Max.Y}) + p, err := c.DrawString(string(letter), fixed.Point26_6{X: 0, Y: bb.Max.Y}) if err != nil { return nil, err } diff --git a/example/Alice.png b/example/Alice.png deleted file mode 100644 index c62876a..0000000 Binary files a/example/Alice.png and /dev/null differ diff --git a/example/Bob.png b/example/Bob.png deleted file mode 100644 index 945d650..0000000 Binary files a/example/Bob.png and /dev/null differ diff --git a/example/Carol.png b/example/Carol.png deleted file mode 100644 index bffdf4d..0000000 Binary files a/example/Carol.png and /dev/null differ diff --git a/example/Dave.png b/example/Dave.png deleted file mode 100644 index 89e73b9..0000000 Binary files a/example/Dave.png and /dev/null differ diff --git a/example/Eve.png b/example/Eve.png deleted file mode 100644 index f7090d9..0000000 Binary files a/example/Eve.png and /dev/null differ diff --git a/example/Frank.png b/example/Frank.png deleted file mode 100644 index d3c6f64..0000000 Binary files a/example/Frank.png and /dev/null differ diff --git a/example/Gloria.png b/example/Gloria.png deleted file mode 100644 index 2cd02f3..0000000 Binary files a/example/Gloria.png and /dev/null differ diff --git a/example/Henry.png b/example/Henry.png deleted file mode 100644 index f7dcfd7..0000000 Binary files a/example/Henry.png and /dev/null differ diff --git a/example/Isabella.png b/example/Isabella.png deleted file mode 100644 index 39e227c..0000000 Binary files a/example/Isabella.png and /dev/null differ diff --git a/example/James.png b/example/James.png deleted file mode 100644 index 50d2355..0000000 Binary files a/example/James.png and /dev/null differ diff --git a/example/firstletter/Alice.png b/example/firstletter/Alice.png new file mode 100644 index 0000000..2d17c2a Binary files /dev/null and b/example/firstletter/Alice.png differ diff --git a/example/firstletter/Bob.png b/example/firstletter/Bob.png new file mode 100644 index 0000000..a1384f3 Binary files /dev/null and b/example/firstletter/Bob.png differ diff --git a/example/firstletter/Carol.png b/example/firstletter/Carol.png new file mode 100644 index 0000000..70116d3 Binary files /dev/null and b/example/firstletter/Carol.png differ diff --git a/example/firstletter/Dave.png b/example/firstletter/Dave.png new file mode 100644 index 0000000..48e5964 Binary files /dev/null and b/example/firstletter/Dave.png differ diff --git a/example/firstletter/Eve.png b/example/firstletter/Eve.png new file mode 100644 index 0000000..eb009cc Binary files /dev/null and b/example/firstletter/Eve.png differ diff --git a/example/firstletter/Frank.png b/example/firstletter/Frank.png new file mode 100644 index 0000000..9999f4e Binary files /dev/null and b/example/firstletter/Frank.png differ diff --git a/example/firstletter/Gloria.png b/example/firstletter/Gloria.png new file mode 100644 index 0000000..0566f27 Binary files /dev/null and b/example/firstletter/Gloria.png differ diff --git a/example/firstletter/Henry.png b/example/firstletter/Henry.png new file mode 100644 index 0000000..c14f2e1 Binary files /dev/null and b/example/firstletter/Henry.png differ diff --git a/example/firstletter/Isabella.png b/example/firstletter/Isabella.png new file mode 100644 index 0000000..56c54f9 Binary files /dev/null and b/example/firstletter/Isabella.png differ diff --git a/example/firstletter/James.png b/example/firstletter/James.png new file mode 100644 index 0000000..67c327c Binary files /dev/null and b/example/firstletter/James.png differ diff --git a/example/example.go b/example/firstletter/example.go similarity index 81% rename from example/example.go rename to example/firstletter/example.go index 6f889df..155e340 100644 --- a/example/example.go +++ b/example/firstletter/example.go @@ -6,7 +6,7 @@ import ( "os" "unicode/utf8" - "github.com/disintegration/letteravatar" + "github.com/UnderTreeTech/letteravatar" ) var names = []string{ @@ -28,7 +28,7 @@ func main() { for _, name := range names { firstLetter, _ := utf8.DecodeRuneInString(name) - img, err := letteravatar.Draw(75, firstLetter, nil) + img, err := letteravatar.Draw(75, []rune{firstLetter}, &letteravatar.Options{}) if err != nil { log.Fatal(err) } diff --git "a/example/firstletter/\320\226\320\276\320\267\320\265\321\204\320\270\320\275\320\260.png" "b/example/firstletter/\320\226\320\276\320\267\320\265\321\204\320\270\320\275\320\260.png" new file mode 100644 index 0000000..0d540c5 Binary files /dev/null and "b/example/firstletter/\320\226\320\276\320\267\320\265\321\204\320\270\320\275\320\260.png" differ diff --git "a/example/firstletter/\320\257\321\200\320\276\321\201\320\273\320\260\320\262.png" "b/example/firstletter/\320\257\321\200\320\276\321\201\320\273\320\260\320\262.png" new file mode 100644 index 0000000..9880192 Binary files /dev/null and "b/example/firstletter/\320\257\321\200\320\276\321\201\320\273\320\260\320\262.png" differ diff --git a/example/multiletter/Alice.png b/example/multiletter/Alice.png new file mode 100644 index 0000000..7a01b68 Binary files /dev/null and b/example/multiletter/Alice.png differ diff --git a/example/multiletter/Bob.png b/example/multiletter/Bob.png new file mode 100644 index 0000000..cda65ff Binary files /dev/null and b/example/multiletter/Bob.png differ diff --git a/example/multiletter/Carol.png b/example/multiletter/Carol.png new file mode 100644 index 0000000..80aaabc Binary files /dev/null and b/example/multiletter/Carol.png differ diff --git a/example/multiletter/Dave.png b/example/multiletter/Dave.png new file mode 100644 index 0000000..3d13223 Binary files /dev/null and b/example/multiletter/Dave.png differ diff --git a/example/multiletter/Eve.png b/example/multiletter/Eve.png new file mode 100644 index 0000000..5ab15a6 Binary files /dev/null and b/example/multiletter/Eve.png differ diff --git a/example/multiletter/Frank.png b/example/multiletter/Frank.png new file mode 100644 index 0000000..daea4d2 Binary files /dev/null and b/example/multiletter/Frank.png differ diff --git a/example/multiletter/Gloria.png b/example/multiletter/Gloria.png new file mode 100644 index 0000000..d385c04 Binary files /dev/null and b/example/multiletter/Gloria.png differ diff --git a/example/multiletter/Henry.png b/example/multiletter/Henry.png new file mode 100644 index 0000000..9d053c1 Binary files /dev/null and b/example/multiletter/Henry.png differ diff --git a/example/multiletter/Isabella.png b/example/multiletter/Isabella.png new file mode 100644 index 0000000..a82214f Binary files /dev/null and b/example/multiletter/Isabella.png differ diff --git a/example/multiletter/James.png b/example/multiletter/James.png new file mode 100644 index 0000000..74e2ed6 Binary files /dev/null and b/example/multiletter/James.png differ diff --git a/example/multiletter/PingFang-SC-Regular.ttf b/example/multiletter/PingFang-SC-Regular.ttf new file mode 100644 index 0000000..abe72b0 Binary files /dev/null and b/example/multiletter/PingFang-SC-Regular.ttf differ diff --git a/example/multiletter/example.go b/example/multiletter/example.go new file mode 100644 index 0000000..1f4e993 --- /dev/null +++ b/example/multiletter/example.go @@ -0,0 +1,69 @@ +package main + +import ( + "image/png" + "io/ioutil" + "log" + "os" + + "github.com/golang/freetype/truetype" + + "github.com/UnderTreeTech/letteravatar" +) + +var names = []string{ + "Alice", + "Bob", + "Carol", + "Dave", + "Eve", + "Frank", + "Gloria", + "Henry", + "Isabella", + "James", + "Жозефина", + "Ярослав", + "中国文化", +} + +func main() { + font, err := loadFont("./PingFang-SC-Regular.ttf") + if err != nil { + log.Fatal(err) + } + + opt := &letteravatar.Options{ + FontSize: 20, + Font: font, + } + for _, name := range names { + + img, err := letteravatar.Draw(100, ([]rune(name))[:5], opt) + if err != nil { + log.Fatal(err) + } + + file, err := os.Create(name + ".png") + if err != nil { + log.Fatal(err) + } + + err = png.Encode(file, img) + if err != nil { + log.Fatal(err) + } + } +} + +func loadFont(path string) (*truetype.Font, error) { + fontBytes, err := ioutil.ReadFile(path) + if err != nil { + return nil, err + } + f, err := truetype.Parse(fontBytes) + if err != nil { + return nil, err + } + return f, nil +} diff --git "a/example/multiletter/\320\226\320\276\320\267\320\265\321\204\320\270\320\275\320\260.png" "b/example/multiletter/\320\226\320\276\320\267\320\265\321\204\320\270\320\275\320\260.png" new file mode 100644 index 0000000..a68815e Binary files /dev/null and "b/example/multiletter/\320\226\320\276\320\267\320\265\321\204\320\270\320\275\320\260.png" differ diff --git "a/example/multiletter/\320\257\321\200\320\276\321\201\320\273\320\260\320\262.png" "b/example/multiletter/\320\257\321\200\320\276\321\201\320\273\320\260\320\262.png" new file mode 100644 index 0000000..4f7a3c4 Binary files /dev/null and "b/example/multiletter/\320\257\321\200\320\276\321\201\320\273\320\260\320\262.png" differ diff --git "a/example/multiletter/\344\270\255\345\233\275\346\226\207\345\214\226.png" "b/example/multiletter/\344\270\255\345\233\275\346\226\207\345\214\226.png" new file mode 100644 index 0000000..dcc3b13 Binary files /dev/null and "b/example/multiletter/\344\270\255\345\233\275\346\226\207\345\214\226.png" differ diff --git "a/example/\320\226\320\276\320\267\320\265\321\204\320\270\320\275\320\260.png" "b/example/\320\226\320\276\320\267\320\265\321\204\320\270\320\275\320\260.png" deleted file mode 100644 index a4f75b1..0000000 Binary files "a/example/\320\226\320\276\320\267\320\265\321\204\320\270\320\275\320\260.png" and /dev/null differ diff --git "a/example/\320\257\321\200\320\276\321\201\320\273\320\260\320\262.png" "b/example/\320\257\321\200\320\276\321\201\320\273\320\260\320\262.png" deleted file mode 100644 index 8e59ef1..0000000 Binary files "a/example/\320\257\321\200\320\276\321\201\320\273\320\260\320\262.png" and /dev/null differ diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..7891290 --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module github.com/UnderTreeTech/letteravatar + +go 1.14 + +require ( + github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 + golang.org/x/image v0.0.0-20211028202545-6944b10bf410 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..fc85b76 --- /dev/null +++ b/go.sum @@ -0,0 +1,6 @@ +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +golang.org/x/image v0.0.0-20211028202545-6944b10bf410 h1:hTftEOvwiOq2+O8k2D5/Q7COC7k5Qcrgc2TFURJYnvQ= +golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=