123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- package base64Captcha
- import (
- "image/color"
- "math/rand"
- "strings"
- "github.com/golang/freetype/truetype"
- )
- //DriverChinese is a driver of unicode Chinese characters.
- type DriverChinese struct {
- //Height png height in pixel.
- Height int
- //Width Captcha png width in pixel.
- Width int
- //NoiseCount text noise count.
- NoiseCount int
- //ShowLineOptions := OptionShowHollowLine | OptionShowSlimeLine | OptionShowSineLine .
- ShowLineOptions int
- //Length random string length.
- Length int
- //Source is a unicode which is the rand string from.
- Source string
- //BgColor captcha image background color (optional)
- BgColor *color.RGBA
- //fontsStorage font storage (optional)
- fontsStorage FontsStorage
- //Fonts loads by name see fonts.go's comment
- Fonts []string
- fontsArray []*truetype.Font
- }
- //NewDriverChinese creates a driver of Chinese characters
- func NewDriverChinese(height int, width int, noiseCount int, showLineOptions int, length int, source string, bgColor *color.RGBA, fontsStorage FontsStorage, fonts []string) *DriverChinese {
- if fontsStorage == nil {
- fontsStorage = DefaultEmbeddedFonts
- }
- tfs := []*truetype.Font{}
- for _, fff := range fonts {
- tf := fontsStorage.LoadFontByName("fonts/" + fff)
- tfs = append(tfs, tf)
- }
- if len(tfs) == 0 {
- tfs = fontsAll
- }
- return &DriverChinese{Height: height, Width: width, NoiseCount: noiseCount, ShowLineOptions: showLineOptions, Length: length, Source: source, BgColor: bgColor, fontsStorage: fontsStorage, fontsArray: tfs}
- }
- //ConvertFonts loads fonts by names
- func (d *DriverChinese) ConvertFonts() *DriverChinese {
- if d.fontsStorage == nil {
- d.fontsStorage = DefaultEmbeddedFonts
- }
- tfs := []*truetype.Font{}
- for _, fff := range d.Fonts {
- tf := d.fontsStorage.LoadFontByName("fonts/" + fff)
- tfs = append(tfs, tf)
- }
- if len(tfs) == 0 {
- tfs = fontsAll
- }
- d.fontsArray = tfs
- return d
- }
- //GenerateIdQuestionAnswer generates captcha content and its answer
- func (d *DriverChinese) GenerateIdQuestionAnswer() (id, content, answer string) {
- id = RandomId()
- ss := strings.Split(d.Source, ",")
- length := len(ss)
- if length == 1 {
- c := RandText(d.Length, ss[0])
- return id, c, c
- }
- if length <= d.Length {
- c := RandText(d.Length, TxtNumbers+TxtAlphabet)
- return id, c, c
- }
- res := make([]string, d.Length)
- for k := range res {
- res[k] = ss[rand.Intn(length)]
- }
- content = strings.Join(res, "")
- return id, content, content
- }
- //DrawCaptcha generates captcha item(image)
- func (d *DriverChinese) DrawCaptcha(content string) (item Item, err error) {
- var bgc color.RGBA
- if d.BgColor != nil {
- bgc = *d.BgColor
- } else {
- bgc = RandLightColor()
- }
- itemChar := NewItemChar(d.Width, d.Height, bgc)
- //draw hollow line
- if d.ShowLineOptions&OptionShowHollowLine == OptionShowHollowLine {
- itemChar.drawHollowLine()
- }
- //draw slime line
- if d.ShowLineOptions&OptionShowSlimeLine == OptionShowSlimeLine {
- itemChar.drawSlimLine(3)
- }
- //draw sine line
- if d.ShowLineOptions&OptionShowSineLine == OptionShowSineLine {
- itemChar.drawSineLine()
- }
- //draw noise
- if d.NoiseCount > 0 {
- source := TxtNumbers + TxtAlphabet + ",.[]<>"
- noise := RandText(d.NoiseCount, strings.Repeat(source, d.NoiseCount))
- err = itemChar.drawNoise(noise, d.fontsArray)
- if err != nil {
- return
- }
- }
- //draw content
- err = itemChar.drawText(content, d.fontsArray)
- if err != nil {
- return
- }
- return itemChar, nil
- }
|