mirror of
https://github.com/openimsdk/open-im-server.git
synced 2026-07-01 07:18:15 +08:00
71 lines
1.9 KiB
Go
71 lines
1.9 KiB
Go
package captcha
|
|
|
|
import (
|
|
"fmt"
|
|
"image"
|
|
_ "image/jpeg"
|
|
_ "image/png"
|
|
|
|
"github.com/golang/freetype"
|
|
"github.com/golang/freetype/truetype"
|
|
"github.com/wenlng/go-captcha/v2/base/option"
|
|
"github.com/wenlng/go-captcha/v2/click"
|
|
"golang.org/x/image/font/gofont/goregular"
|
|
)
|
|
|
|
// buildClickCaptcha constructs a click.Captcha instance configured with
|
|
// alphanumeric characters, a bundled Go font, and the embedded background images.
|
|
func buildClickCaptcha() (click.Captcha, error) {
|
|
font, err := loadGoRegularFont()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("load font: %w", err)
|
|
}
|
|
backgrounds, err := loadBackgrounds()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("load captcha backgrounds: %w", err)
|
|
}
|
|
|
|
builder := click.NewBuilder(
|
|
click.WithRangeLen(option.RangeVal{Min: 6, Max: 8}),
|
|
click.WithRangeVerifyLen(option.RangeVal{Min: 3, Max: 4}),
|
|
click.WithRangeSize(option.RangeVal{Min: 26, Max: 34}),
|
|
click.WithDisplayShadow(true),
|
|
)
|
|
builder.SetResources(
|
|
click.WithChars(alphanumChars),
|
|
click.WithFonts([]*truetype.Font{font}),
|
|
click.WithBackgrounds(backgrounds),
|
|
)
|
|
return builder.Make(), nil
|
|
}
|
|
|
|
// loadGoRegularFont parses the bundled Go Regular TTF font.
|
|
func loadGoRegularFont() (*truetype.Font, error) {
|
|
return freetype.ParseFont(goregular.TTF)
|
|
}
|
|
|
|
// loadBackgrounds decodes the embedded JPEG background images.
|
|
func loadBackgrounds() ([]image.Image, error) {
|
|
const count = 5
|
|
images := make([]image.Image, 0, count)
|
|
for i := 1; i <= count; i++ {
|
|
path := fmt.Sprintf("resources/images/image-%d.jpg", i)
|
|
img, err := decodeEmbedImage(path)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("decode %s: %w", path, err)
|
|
}
|
|
images = append(images, img)
|
|
}
|
|
return images, nil
|
|
}
|
|
|
|
func decodeEmbedImage(path string) (image.Image, error) {
|
|
f, err := resourceFS.Open(path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer f.Close()
|
|
img, _, err := image.Decode(f)
|
|
return img, err
|
|
}
|