对齐 Tag v1.5.0 (By AI)

This commit is contained in:
AI Engineer 2026-06-03 20:10:43 +08:00
parent f269f92527
commit a0e2a2b47b
3 changed files with 170 additions and 15 deletions

11
go.mod
View File

@ -3,9 +3,10 @@ module apigo.cc/go/vision
go 1.25.0
require (
apigo.cc/go/cast v1.3.3
apigo.cc/go/file v1.3.2
apigo.cc/go/rand v1.3.1
apigo.cc/go/cast v1.5.0
apigo.cc/go/file v1.5.0
apigo.cc/go/jsmod v1.5.0
apigo.cc/go/rand v1.5.0
github.com/boombuler/barcode v1.1.0
github.com/disintegration/imaging v1.6.2
github.com/flopp/go-findfont v0.1.0
@ -16,8 +17,8 @@ require (
)
require (
apigo.cc/go/encoding v1.3.1 // indirect
apigo.cc/go/safe v1.3.1 // indirect
apigo.cc/go/encoding v1.5.0 // indirect
apigo.cc/go/safe v1.5.0 // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/kr/text v0.2.0 // indirect
golang.org/x/crypto v0.51.0 // indirect

22
go.sum
View File

@ -1,13 +1,15 @@
apigo.cc/go/cast v1.3.3 h1:aln5eDR5DZVWVzZ/y5SJh1gQNgWv2sT82I25NaO9g34=
apigo.cc/go/cast v1.3.3/go.mod h1:lGlwImiOvHxG7buyMWhFzcdvQzmSaoKbmr7bcDfUpHk=
apigo.cc/go/encoding v1.3.1 h1:y8O58KYAyulkThg1O2ji2BqjnFoSvk42sit9I3z+K7Y=
apigo.cc/go/encoding v1.3.1/go.mod h1:xAJk5b83VZ31mXMTnyp0dfMoBKfT/AHDn0u+cQfojgY=
apigo.cc/go/file v1.3.2 h1:pu4oiDyiqgj3/eykfnJf+/6+A9v/Z0b3ClP5XK+lwG4=
apigo.cc/go/file v1.3.2/go.mod h1:vci4h0Pz94mV6dkniQkuyBYERVYeq7/LX4jJVuCg9hs=
apigo.cc/go/rand v1.3.1 h1:7FvsI6PtQ5XrWER0dTiLVo0p7GIxRidT/TBKhVy93j8=
apigo.cc/go/rand v1.3.1/go.mod h1:mZ/4Soa3bk+XvDaqPWJuUe1bfEi4eThBj1XmEAuYxsk=
apigo.cc/go/safe v1.3.1 h1:irTCqPAC97gGsX/Lw5AzLelDt1xXLEZIAaVhLELWe9Q=
apigo.cc/go/safe v1.3.1/go.mod h1:XdOpBhN2vkImalaykYXXmEpczqWa1y3ah6/Q72cdRqE=
apigo.cc/go/cast v1.5.0 h1:UBGJtFQ8eJPMQXs37cUgqd7YQo1zI9opuSDBDmn2/pE=
apigo.cc/go/cast v1.5.0/go.mod h1:z2GW5p5WCZGEqVVIJUdhl232vRbLf2Qu4EDlEakX/D8=
apigo.cc/go/encoding v1.5.0 h1:EJNdRVDOMoI2DAvZwQNQTbYuqB/6zsEzvg7lS5pQI+I=
apigo.cc/go/encoding v1.5.0/go.mod h1:8++NfZj3hWig0qh2g7GQRw/4LpSvCYMWUZ+8J+x58cA=
apigo.cc/go/file v1.5.0 h1:Fh1NSDBqaxjuXYJ71yPHPXVJ8BFEv/AGS3l+jkLi5uw=
apigo.cc/go/file v1.5.0/go.mod h1:4YhOGgBINTpmmmgws3H8LAyXQQBGzBp44hYUoCS+kr0=
apigo.cc/go/jsmod v1.5.0 h1:JgQtJNiJWy1NOP9AzE8NX5VXJkpO/x3GqLsCCSny5Ec=
apigo.cc/go/jsmod v1.5.0/go.mod h1:bmyeZtOAP/j5am+YRnaiM89smysK24K7ebk0koFtsSw=
apigo.cc/go/rand v1.5.0 h1:1o8hh8fhdBuk1/h02IvugvamuT3dkWbVJrqEJVQKB2E=
apigo.cc/go/rand v1.5.0/go.mod h1:Lh98S2dm9UY0X+M+kNQQEKyXHG5pcCKSFPyXN0QCGdk=
apigo.cc/go/safe v1.5.0 h1:W1NblmcU8cex1f9Y5z8mNLUJOzZTE1s6fszb3FbhGnk=
apigo.cc/go/safe v1.5.0/go.mod h1:OfQ5d6COePSGEuPvMeOk6KagX2sezw7nvKh7exj9SeM=
github.com/boombuler/barcode v1.1.0 h1:ChaYjBR63fr4LFyGn8E8nt7dBSt3MiU3zMOZqFvVkHo=
github.com/boombuler/barcode v1.1.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=

152
js_export.go Normal file
View File

@ -0,0 +1,152 @@
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() }