153 lines
4.7 KiB
Go
153 lines
4.7 KiB
Go
|
|
package vision
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
|
||
|
|
"apigo.cc/go/file"
|
||
|
|
"apigo.cc/go/jsmod"
|
||
|
|
)
|
||
|
|
|
||
|
|
func init() {
|
||
|
|
jsmod.Register("vision", map[string]any{
|
||
|
|
// 基础操作
|
||
|
|
"load": func(ctx context.Context, path string) (*jsCanvas, error) {
|
||
|
|
p, err := file.VerifyPathForSafeMode(ctx, path)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
c, err := Load(p)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
return &jsCanvas{ctx: ctx, c: c}, nil
|
||
|
|
},
|
||
|
|
"new": func(ctx context.Context, w, h int, bg ...string) *jsCanvas {
|
||
|
|
return &jsCanvas{ctx: ctx, c: New(w, h, bg...)}
|
||
|
|
},
|
||
|
|
"save": func(ctx context.Context, j *jsCanvas, path string, quality ...int) error {
|
||
|
|
p, err := file.VerifyPathForSafeMode(ctx, path)
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
return Save(j.c, p, quality...)
|
||
|
|
},
|
||
|
|
|
||
|
|
// 生成类
|
||
|
|
"generateQRCode": func(ctx context.Context, content string, size int) (*jsCanvas, error) {
|
||
|
|
c, err := GenerateQRCode(content, size)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
return &jsCanvas{ctx: ctx, c: c}, nil
|
||
|
|
},
|
||
|
|
"generateBarcode": func(ctx context.Context, content string, w, h int) (*jsCanvas, error) {
|
||
|
|
c, err := GenerateBarcode(content, w, h)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
return &jsCanvas{ctx: ctx, c: c}, nil
|
||
|
|
},
|
||
|
|
"generateCaptcha": func(ctx context.Context, opt *CaptchaOption) *jsCanvas {
|
||
|
|
return &jsCanvas{ctx: ctx, c: GenerateCaptcha(opt)}
|
||
|
|
},
|
||
|
|
|
||
|
|
// 预览类 (直接写文件)
|
||
|
|
"generateImagePreview": func(ctx context.Context, src, out string, w, h int) error {
|
||
|
|
pSrc, err := file.VerifyPathForSafeMode(ctx, src)
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
pOut, err := file.VerifyPathForSafeMode(ctx, out)
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
return GenerateImagePreview(pSrc, pOut, w, h)
|
||
|
|
},
|
||
|
|
"generateVideoPreview": func(ctx context.Context, src, out string, w, h int, interval ...int) error {
|
||
|
|
pSrc, err := file.VerifyPathForSafeMode(ctx, src)
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
pOut, err := file.VerifyPathForSafeMode(ctx, out)
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
return GenerateVideoPreview(pSrc, pOut, w, h, interval...)
|
||
|
|
},
|
||
|
|
|
||
|
|
// 转换类
|
||
|
|
"convert": func(ctx context.Context, src, dst string, quality ...int) error {
|
||
|
|
pSrc, err := file.VerifyPathForSafeMode(ctx, src)
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
pDst, err := file.VerifyPathForSafeMode(ctx, dst)
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
return Convert(pSrc, pDst, quality...)
|
||
|
|
},
|
||
|
|
"optimize": func(ctx context.Context, path string, maxWidth int, quality int) error {
|
||
|
|
p, err := file.VerifyPathForSafeMode(ctx, path)
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
return Optimize(p, maxWidth, quality)
|
||
|
|
},
|
||
|
|
|
||
|
|
// 辅助工具
|
||
|
|
"loadFonts": LoadFonts,
|
||
|
|
"recognize": func(ctx context.Context, path string) (string, error) {
|
||
|
|
p, err := file.VerifyPathForSafeMode(ctx, path)
|
||
|
|
if err != nil {
|
||
|
|
return "", err
|
||
|
|
}
|
||
|
|
return Recognize(p)
|
||
|
|
},
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// jsCanvas 包装器,支持链式调用
|
||
|
|
type jsCanvas struct {
|
||
|
|
ctx context.Context
|
||
|
|
c *Canvas
|
||
|
|
}
|
||
|
|
|
||
|
|
func (j *jsCanvas) Width() int { return j.c.Width() }
|
||
|
|
func (j *jsCanvas) Height() int { return j.c.Height() }
|
||
|
|
|
||
|
|
func (j *jsCanvas) Save(path string, quality ...int) error {
|
||
|
|
p, err := file.VerifyPathForSafeMode(j.ctx, path)
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
return Save(j.c, p, quality...)
|
||
|
|
}
|
||
|
|
|
||
|
|
// 效果与绘图 (返回自身以支持链式)
|
||
|
|
func (j *jsCanvas) Resize(w, h int) *jsCanvas { j.c.Resize(w, h); return j }
|
||
|
|
func (j *jsCanvas) Blur(sigma float64) *jsCanvas { j.c.Blur(sigma); return j }
|
||
|
|
func (j *jsCanvas) Grayscale() *jsCanvas { j.c.Grayscale(); return j }
|
||
|
|
func (j *jsCanvas) Invert() *jsCanvas { j.c.Invert(); return j }
|
||
|
|
func (j *jsCanvas) Rotate(angle float64) *jsCanvas { j.c.Rotate(angle); return j }
|
||
|
|
func (j *jsCanvas) FlipH() *jsCanvas { j.c.FlipH(); return j }
|
||
|
|
func (j *jsCanvas) FlipV() *jsCanvas { j.c.FlipV(); return j }
|
||
|
|
func (j *jsCanvas) Sharpen(sigma float64) *jsCanvas { j.c.Sharpen(sigma); return j }
|
||
|
|
func (j *jsCanvas) AdjustBrightness(p float64) *jsCanvas { j.c.AdjustBrightness(p); return j }
|
||
|
|
|
||
|
|
func (j *jsCanvas) Rect(x, y, w, h float64, opt *DrawStyle) *jsCanvas { j.c.Rect(x, y, w, h, opt); return j }
|
||
|
|
func (j *jsCanvas) Circle(x, y, r float64, opt *DrawStyle) *jsCanvas { j.c.Circle(x, y, r, opt); return j }
|
||
|
|
func (j *jsCanvas) Line(x1, y1, x2, y2 float64, opt *DrawStyle) *jsCanvas {
|
||
|
|
j.c.Line(x1, y1, x2, y2, opt)
|
||
|
|
return j
|
||
|
|
}
|
||
|
|
func (j *jsCanvas) DrawText(x, y float64, text string, opt *TextOption) *jsCanvas {
|
||
|
|
j.c.DrawText(x, y, text, opt)
|
||
|
|
return j
|
||
|
|
}
|
||
|
|
|
||
|
|
// 识别类
|
||
|
|
func (j *jsCanvas) DecodeAll() (string, error) { return j.c.DecodeAll() }
|
||
|
|
func (j *jsCanvas) Recognize() (string, error) { return j.c.Recognize() }
|
||
|
|
func (j *jsCanvas) DecodeQRCode() (string, error) { return j.c.DecodeQRCode() }
|