driver_chinese.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. package base64Captcha
  2. import (
  3. "image/color"
  4. "math/rand"
  5. "strings"
  6. "github.com/golang/freetype/truetype"
  7. )
  8. //DriverChinese is a driver of unicode Chinese characters.
  9. type DriverChinese struct {
  10. //Height png height in pixel.
  11. Height int
  12. //Width Captcha png width in pixel.
  13. Width int
  14. //NoiseCount text noise count.
  15. NoiseCount int
  16. //ShowLineOptions := OptionShowHollowLine | OptionShowSlimeLine | OptionShowSineLine .
  17. ShowLineOptions int
  18. //Length random string length.
  19. Length int
  20. //Source is a unicode which is the rand string from.
  21. Source string
  22. //BgColor captcha image background color (optional)
  23. BgColor *color.RGBA
  24. //fontsStorage font storage (optional)
  25. fontsStorage FontsStorage
  26. //Fonts loads by name see fonts.go's comment
  27. Fonts []string
  28. fontsArray []*truetype.Font
  29. }
  30. //NewDriverChinese creates a driver of Chinese characters
  31. func NewDriverChinese(height int, width int, noiseCount int, showLineOptions int, length int, source string, bgColor *color.RGBA, fontsStorage FontsStorage, fonts []string) *DriverChinese {
  32. if fontsStorage == nil {
  33. fontsStorage = DefaultEmbeddedFonts
  34. }
  35. tfs := []*truetype.Font{}
  36. for _, fff := range fonts {
  37. tf := fontsStorage.LoadFontByName("fonts/" + fff)
  38. tfs = append(tfs, tf)
  39. }
  40. if len(tfs) == 0 {
  41. tfs = fontsAll
  42. }
  43. return &DriverChinese{Height: height, Width: width, NoiseCount: noiseCount, ShowLineOptions: showLineOptions, Length: length, Source: source, BgColor: bgColor, fontsStorage: fontsStorage, fontsArray: tfs}
  44. }
  45. //ConvertFonts loads fonts by names
  46. func (d *DriverChinese) ConvertFonts() *DriverChinese {
  47. if d.fontsStorage == nil {
  48. d.fontsStorage = DefaultEmbeddedFonts
  49. }
  50. tfs := []*truetype.Font{}
  51. for _, fff := range d.Fonts {
  52. tf := d.fontsStorage.LoadFontByName("fonts/" + fff)
  53. tfs = append(tfs, tf)
  54. }
  55. if len(tfs) == 0 {
  56. tfs = fontsAll
  57. }
  58. d.fontsArray = tfs
  59. return d
  60. }
  61. //GenerateIdQuestionAnswer generates captcha content and its answer
  62. func (d *DriverChinese) GenerateIdQuestionAnswer() (id, content, answer string) {
  63. id = RandomId()
  64. ss := strings.Split(d.Source, ",")
  65. length := len(ss)
  66. if length == 1 {
  67. c := RandText(d.Length, ss[0])
  68. return id, c, c
  69. }
  70. if length <= d.Length {
  71. c := RandText(d.Length, TxtNumbers+TxtAlphabet)
  72. return id, c, c
  73. }
  74. res := make([]string, d.Length)
  75. for k := range res {
  76. res[k] = ss[rand.Intn(length)]
  77. }
  78. content = strings.Join(res, "")
  79. return id, content, content
  80. }
  81. //DrawCaptcha generates captcha item(image)
  82. func (d *DriverChinese) DrawCaptcha(content string) (item Item, err error) {
  83. var bgc color.RGBA
  84. if d.BgColor != nil {
  85. bgc = *d.BgColor
  86. } else {
  87. bgc = RandLightColor()
  88. }
  89. itemChar := NewItemChar(d.Width, d.Height, bgc)
  90. //draw hollow line
  91. if d.ShowLineOptions&OptionShowHollowLine == OptionShowHollowLine {
  92. itemChar.drawHollowLine()
  93. }
  94. //draw slime line
  95. if d.ShowLineOptions&OptionShowSlimeLine == OptionShowSlimeLine {
  96. itemChar.drawSlimLine(3)
  97. }
  98. //draw sine line
  99. if d.ShowLineOptions&OptionShowSineLine == OptionShowSineLine {
  100. itemChar.drawSineLine()
  101. }
  102. //draw noise
  103. if d.NoiseCount > 0 {
  104. source := TxtNumbers + TxtAlphabet + ",.[]<>"
  105. noise := RandText(d.NoiseCount, strings.Repeat(source, d.NoiseCount))
  106. err = itemChar.drawNoise(noise, d.fontsArray)
  107. if err != nil {
  108. return
  109. }
  110. }
  111. //draw content
  112. err = itemChar.drawText(content, d.fontsArray)
  113. if err != nil {
  114. return
  115. }
  116. return itemChar, nil
  117. }