-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
218 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package foundation | ||
|
||
import ( | ||
"github.com/lyupengpublish/golibs/myutils/calc" | ||
"image/color" | ||
) | ||
var colors = []uint32{ | ||
0xff6200, 0x42c58e, 0x5a8de1, 0x785fe0, | ||
} | ||
//生成头像的方式 | ||
func GeneraterAvater(width int,height int,content string) []byte { | ||
ab := calc.NewAvatarBuilder("../static/SourceHanSansSC-Medium.ttf", &calc.SourceHansSansSCMedium{}) | ||
ab.SetBackgroundColorHex(colors[3]) | ||
ab.SetFrontgroundColor(color.White) | ||
ab.SetFontSize(80) | ||
ab.SetAvatarSize(width, height) | ||
if data,err:=ab.GenerateImage(content);err==nil { | ||
return data | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package foundation | ||
|
||
import ( | ||
"testing" | ||
) | ||
|
||
func Test_ge(t *testing.T) { | ||
|
||
GeneraterAvater() | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package calc | ||
import "regexp" | ||
type SourceHansSansSCMedium struct{} | ||
func (f *SourceHansSansSCMedium) CalculateCenterLocation(s string, ab *AvatarBuilder) (x int, y int) { | ||
cr := regexp.MustCompile("[\u4e00-\u9FA5]{1}") | ||
er := regexp.MustCompile("[a-zA-Z]{1}") | ||
nr := regexp.MustCompile("[0-9]{1}") | ||
cCount := len(cr.FindAllStringSubmatch(s, -1)) | ||
eCount := len(er.FindAllStringSubmatch(s, -1)) | ||
nCount := len(nr.FindAllStringSubmatch(s, -1)) | ||
x = ab.W/2 - (cCount*ab.GetFontWidth()+eCount*ab.GetFontWidth()*3/5+nCount*ab.GetFontWidth()*3/5)/2 | ||
y = ab.H/2 + ab.GetFontWidth()*4/11 | ||
return | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
package calc | ||
|
||
import ( | ||
"bufio" | ||
"bytes" | ||
"errors" | ||
"image" | ||
"image/color" | ||
"image/draw" | ||
"image/png" | ||
"io/ioutil" | ||
"os" | ||
|
||
"github.com/golang/freetype" | ||
"golang.org/x/image/font" | ||
) | ||
|
||
type FontCenterCalculator interface { | ||
// CalculateCenterLocation used to calculate center location in different font style | ||
CalculateCenterLocation(string, *AvatarBuilder) (int, int) | ||
} | ||
|
||
type AvatarBuilder struct { | ||
W int | ||
H int | ||
fontfile string | ||
fontsize float64 | ||
bg color.Color | ||
fg color.Color | ||
ctx *freetype.Context | ||
calc FontCenterCalculator | ||
} | ||
|
||
func NewAvatarBuilder(fontfile string, calc FontCenterCalculator) *AvatarBuilder { | ||
ab := &AvatarBuilder{} | ||
ab.fontfile = fontfile | ||
ab.bg, ab.fg = color.White, color.Black | ||
ab.W, ab.H = 200, 200 | ||
ab.fontsize = 95 | ||
ab.calc = calc | ||
|
||
return ab | ||
} | ||
|
||
func (ab *AvatarBuilder) SetFrontgroundColor(c color.Color) { | ||
ab.fg = c | ||
} | ||
|
||
func (ab *AvatarBuilder) SetBackgroundColor(c color.Color) { | ||
ab.bg = c | ||
} | ||
|
||
func (ab *AvatarBuilder) SetFrontgroundColorHex(hex uint32) { | ||
ab.fg = ab.hexToRGBA(hex) | ||
} | ||
|
||
func (ab *AvatarBuilder) SetBackgroundColorHex(hex uint32) { | ||
ab.bg = ab.hexToRGBA(hex) | ||
} | ||
|
||
func (ab *AvatarBuilder) SetFontSize(size float64) { | ||
ab.fontsize = size | ||
} | ||
|
||
func (ab *AvatarBuilder) SetAvatarSize(w int, h int) { | ||
ab.W = w | ||
ab.H = h | ||
} | ||
|
||
|
||
func (ab *AvatarBuilder) GenerateImageAndSave(s string, outname string) error { | ||
bs, err := ab.GenerateImage(s) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Save that RGBA image to disk. | ||
outFile, err := os.Create(outname) | ||
if err != nil { | ||
return errors.New("create file: " + err.Error()) | ||
} | ||
defer outFile.Close() | ||
|
||
b := bufio.NewWriter(outFile) | ||
if _, err := b.Write(bs); err != nil { | ||
return errors.New("write bytes to file: " + err.Error()) | ||
|
||
} | ||
if err = b.Flush(); err != nil { | ||
return errors.New("flush image: " + err.Error()) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (ab *AvatarBuilder) GenerateImage(s string) ([]byte, error) { | ||
rgba := ab.buildColorImage() | ||
if ab.ctx == nil { | ||
if err := ab.buildDrawContext(rgba); err != nil { | ||
return nil, err | ||
} | ||
} | ||
|
||
x, y := ab.calc.CalculateCenterLocation(s, ab) | ||
pt := freetype.Pt(x, y) | ||
if _, err := ab.ctx.DrawString(s, pt); err != nil { | ||
return nil, errors.New("draw string: " + err.Error()) | ||
} | ||
|
||
buf := &bytes.Buffer{} | ||
if err := png.Encode(buf, rgba); err != nil { | ||
return nil, errors.New("png encode: " + err.Error()) | ||
} | ||
|
||
return buf.Bytes(), nil | ||
} | ||
|
||
func (ab *AvatarBuilder) buildColorImage() *image.RGBA { | ||
bg := image.NewUniform(ab.bg) | ||
rgba := image.NewRGBA(image.Rect(0, 0, ab.W, ab.H)) | ||
draw.Draw(rgba, rgba.Bounds(), bg, image.ZP, draw.Src) | ||
return rgba | ||
} | ||
|
||
func (ab *AvatarBuilder) hexToRGBA(h uint32) *color.RGBA { | ||
rgba := &color.RGBA{ | ||
R: uint8(h >> 16), | ||
G: uint8((h & 0x00ff00) >> 8), | ||
B: uint8(h & 0x0000ff), | ||
A: 255, | ||
} | ||
|
||
return rgba | ||
} | ||
|
||
func (ab *AvatarBuilder) buildDrawContext(rgba *image.RGBA) error { | ||
// Read the font data. | ||
fontBytes, err := ioutil.ReadFile(ab.fontfile) | ||
if err != nil { | ||
return errors.New("error when open font file:" + err.Error()) | ||
} | ||
|
||
f, err := freetype.ParseFont(fontBytes) | ||
if err != nil { | ||
return errors.New("error when parse font file:" + err.Error()) | ||
} | ||
|
||
c := freetype.NewContext() | ||
c.SetDPI(72) | ||
c.SetFont(f) | ||
c.SetFontSize(ab.fontsize) | ||
c.SetClip(rgba.Bounds()) | ||
c.SetDst(rgba) | ||
c.SetSrc(image.NewUniform(ab.fg)) | ||
c.SetHinting(font.HintingNone) | ||
|
||
ab.ctx = c | ||
return nil | ||
} | ||
|
||
func (ab *AvatarBuilder) GetFontWidth() int { | ||
return int(ab.ctx.PointToFixed(ab.fontsize) >> 6) | ||
} |
Binary file not shown.