diff --git a/go.mod b/go.mod index 16b69ff..e1b1302 100644 --- a/go.mod +++ b/go.mod @@ -1,15 +1,15 @@ module apigo.cc/gojs/img -go 1.24 +go 1.24.0 require ( - apigo.cc/gojs v0.0.25 - apigo.cc/gojs/console v0.0.2 + apigo.cc/gojs v0.0.29 + apigo.cc/gojs/console v0.0.3 github.com/disintegration/imaging v1.6.2 github.com/flopp/go-findfont v0.1.0 github.com/fogleman/gg v1.3.0 - github.com/ssgo/u v1.7.21 - golang.org/x/image v0.29.0 + github.com/ssgo/u v1.7.23 + golang.org/x/image v0.33.0 ) require ( @@ -17,12 +17,12 @@ require ( github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/go-sourcemap/sourcemap v2.1.4+incompatible // indirect github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect - github.com/google/pprof v0.0.0-20250630185457-6e76a2b096b5 // indirect - github.com/ssgo/config v1.7.9 // indirect + github.com/google/pprof v0.0.0-20250903194437-c28834ac2320 // indirect + github.com/ssgo/config v1.7.10 // indirect github.com/ssgo/log v1.7.9 // indirect github.com/ssgo/standard v1.7.7 // indirect github.com/ssgo/tool v0.4.29 // indirect - golang.org/x/sys v0.34.0 // indirect - golang.org/x/text v0.27.0 // indirect + golang.org/x/sys v0.38.0 // indirect + golang.org/x/text v0.31.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/img.go b/img.go index 09492b2..7c19f9b 100644 --- a/img.go +++ b/img.go @@ -14,6 +14,7 @@ import ( "strings" "apigo.cc/gojs" + "apigo.cc/gojs/goja" "github.com/disintegration/imaging" "github.com/fogleman/gg" "golang.org/x/image/font" @@ -61,7 +62,8 @@ func CreateImage(width, height int, c *string) *Graphics { } // LoadImage 从文件加载图像 -func LoadImage(filePath string) (*Graphics, error) { +func LoadImage(filePath string, vm *goja.Runtime) (*Graphics, error) { + filePath = gojs.FixPath(vm, filePath) file, err := os.Open(filePath) if err != nil { return nil, err @@ -256,7 +258,8 @@ func (g *Graphics) FillAreaWithImage(src *Graphics, x, y, width, height int) { } // ExportImage 导出图像到文件 -func (g *Graphics) ExportImage(filePath string, quality *int) error { +func (g *Graphics) ExportImage(filePath string, quality *int, vm *goja.Runtime) error { + filePath = gojs.FixPath(vm, filePath) file, err := os.Create(filePath) if err != nil { return err diff --git a/img_test.js b/img_test.js index aa4d972..5e65980 100644 --- a/img_test.js +++ b/img_test.js @@ -8,25 +8,25 @@ g.setSansSerifFont(16) // 创建区块网格 const b = [] for (let i = 0; i < 40; i++) { - const col = i % 5 - const row = Math.floor(i / 5) - const x = 25 + col * (250 + 25) - const y = 25 + row * (250 + 25) - g.rect(x, y, 250, 250, { lineColor: "#666", lineWidth: 2 }) - b.push({ x, y, width: 250, height: 250, idx: i }) + const col = i % 5 + const row = Math.floor(i / 5) + const x = 25 + col * (250 + 25) + const y = 25 + row * (250 + 25) + g.rect(x, y, 250, 250, { lineColor: "#666", lineWidth: 2 }) + b.push({ x, y, width: 250, height: 250, idx: i }) } function title(i, text) { - g.text(b[i].x, b[i].y + 250 - 30, text, { color: "#fff", bgColor: '#666', width: 250, height: 30, align: 'center', vAlign: 'middle' }) + g.text(b[i].x, b[i].y + 250 - 30, text, { color: "#fff", bgColor: '#666', width: 250, height: 30, align: 'center', vAlign: 'middle' }) } i = 0 title(i, "点") for (x = 10; x < 250; x += 10) { - for (y = 10; y < 220; y += 10) { - g.point(b[i].x + x, b[i].y + y, img.randColor()) - } + for (y = 10; y < 220; y += 10) { + g.point(b[i].x + x, b[i].y + y, img.randColor()) + } } i++ @@ -57,159 +57,159 @@ i++ title(i, "多边形") g.triangle(b[i].x + 10, b[i].y + 10, b[i].x + 10, b[i].y + 150, b[i].x + 120, b[i].y + 10) g.polygon([b[i].x + 125, b[i].y + 50, b[i].x + 50, b[i].y + 150, b[i].x + 200, b[i].y + 150], { - lineColor: '#00f', - lineWidth: 3, - fillColor: '#ccf' + lineColor: '#00f', + lineWidth: 3, + fillColor: '#ccf' }) g.regularPolygon(6, b[i].x + 125, b[i].y + 170, 40, { - lineColor: '#f0f', - lineWidth: 2, - fillColor: '#fcf', - shadowOffset: 2 + lineColor: '#f0f', + lineWidth: 2, + fillColor: '#fcf', + shadowOffset: 2 }) i++ title(i, "弧和扇形") g.arc(b[i].x + 70, b[i].y + 70, 50, 0, Math.PI * 1.5, { - lineColor: '#f00', - lineWidth: 3 + lineColor: '#f00', + lineWidth: 3 }) g.sector(b[i].x + 190, b[i].y + 120, 50, Math.PI / 4, Math.PI * 1.5, { - lineColor: '#0f0', - lineWidth: 2, - fillColor: '#cfc', - shadowOffset: 2, + lineColor: '#0f0', + lineWidth: 2, + fillColor: '#cfc', + shadowOffset: 2, }) i++ title(i, "圆环和弧环") g.ring(b[i].x + 70, b[i].y + 70, 30, 50, { - lineColor: '#00f', - lineWidth: 3, + lineColor: '#00f', + lineWidth: 3, }) g.arcRing(b[i].x + 190, b[i].y + 120, 20, 50, Math.PI / 4, Math.PI * 1.5, { - lineColor: '#f0f', - lineWidth: 2, - fillColor: '#fcf', - shadowColor: '#0ff', - shadowOffset: -4, + lineColor: '#f0f', + lineWidth: 2, + fillColor: '#fcf', + shadowColor: '#0ff', + shadowOffset: -4, }) i++ title(i, "箭头和十字") g.arrow(b[i].x + 50, b[i].y + 70, b[i].x + 200, b[i].y + 70, 15, { - lineColor: '#f00', - lineWidth: 3 + lineColor: '#f00', + lineWidth: 3 }) g.arrow(b[i].x + 200, b[i].y + 150, b[i].x + 50, b[i].y + 150, 20, { - lineColor: '#00f', - lineWidth: 4, - shadowOffset: 2, + lineColor: '#00f', + lineWidth: 4, + shadowOffset: 2, }) g.cross(b[i].x + 125, b[i].y + 110, 40, { - lineColor: '#0a0', - lineWidth: 10, - shadowOffset: 4, + lineColor: '#0a0', + lineWidth: 10, + shadowOffset: 4, }) i++ title(i, "曲线") g.bezierCurve([ - b[i].x + 20, b[i].y + 150, - b[i].x + 100, b[i].y + 50, - b[i].x + 150, b[i].y + 200, - b[i].x + 230, b[i].y + 100 + b[i].x + 20, b[i].y + 150, + b[i].x + 100, b[i].y + 50, + b[i].x + 150, b[i].y + 200, + b[i].x + 230, b[i].y + 100 ], { - lineColor: '#f00', - lineWidth: 2 + lineColor: '#f00', + lineWidth: 2 }) g.quadraticCurve([ - b[i].x + 20, b[i].y + 100, - b[i].x + 125, b[i].y + 200, - b[i].x + 230, b[i].y + 100 + b[i].x + 20, b[i].y + 100, + b[i].x + 125, b[i].y + 200, + b[i].x + 230, b[i].y + 100 ], { - lineColor: '#00f', - lineWidth: 2 + lineColor: '#00f', + lineWidth: 2 }) i++ title(i, "虚线样式") g.line(b[i].x + 20, b[i].y + 50, b[i].x + 230, b[i].y + 50, { - lineColor: '#f00', - lineWidth: 3, - dash: [10, 5] + lineColor: '#f00', + lineWidth: 3, + dash: [10, 5] }) g.line(b[i].x + 20, b[i].y + 100, b[i].x + 230, b[i].y + 100, { - lineColor: '#0f0', - lineWidth: 3, - dash: [5, 5] + lineColor: '#0f0', + lineWidth: 3, + dash: [5, 5] }) g.line(b[i].x + 20, b[i].y + 150, b[i].x + 230, b[i].y + 150, { - lineColor: '#00f', - lineWidth: 3, - dash: [15, 5, 5, 5] + lineColor: '#00f', + lineWidth: 3, + dash: [15, 5, 5, 5] }) i++ title(i, "线帽样式") g.line(b[i].x + 50, b[i].y + 50, b[i].x + 200, b[i].y + 50, { - lineColor: '#f00', - lineWidth: 10, - lineCap: img.lineCap.butt + lineColor: '#f00', + lineWidth: 10, + lineCap: img.lineCap.butt }) g.line(b[i].x + 50, b[i].y + 100, b[i].x + 200, b[i].y + 100, { - lineColor: '#0f0', - lineWidth: 10, - lineCap: img.lineCap.round + lineColor: '#0f0', + lineWidth: 10, + lineCap: img.lineCap.round }) g.line(b[i].x + 50, b[i].y + 150, b[i].x + 200, b[i].y + 150, { - lineColor: '#00f', - lineWidth: 10, - lineCap: img.lineCap.square + lineColor: '#00f', + lineWidth: 10, + lineCap: img.lineCap.square }) i++ title(i, "线连接样式") g.lines([b[i].x + 50, b[i].y + 50, b[i].x + 150, b[i].y + 100, b[i].x + 50, b[i].y + 150], { - lineColor: '#f00', - lineWidth: 8, - lineJoin: img.lineJoin.bevel + lineColor: '#f00', + lineWidth: 8, + lineJoin: img.lineJoin.bevel }) g.lines([b[i].x + 150, b[i].y + 50, b[i].x + 50, b[i].y + 100, b[i].x + 150, b[i].y + 150], { - lineColor: '#0f0', - lineWidth: 8, - lineJoin: img.lineJoin.miter + lineColor: '#0f0', + lineWidth: 8, + lineJoin: img.lineJoin.miter }) g.lines([b[i].x + 100, b[i].y + 50, b[i].x + 200, b[i].y + 100, b[i].x + 100, b[i].y + 150], { - lineColor: '#00f', - lineWidth: 8, - lineJoin: img.lineJoin.round + lineColor: '#00f', + lineWidth: 8, + lineJoin: img.lineJoin.round }) i++ title(i, "星形") g.star(5, b[i].x + 70, b[i].y + 70, 50, 20, { - lineColor: '#f00', - lineWidth: 2, + lineColor: '#f00', + lineWidth: 2, }) g.star(6, b[i].x + 180, b[i].y + 70, 50, 25, { - lineColor: '#0f0', - lineWidth: 2, - fillColor: '#cfc' + lineColor: '#0f0', + lineWidth: 2, + fillColor: '#cfc' }) g.star(8, b[i].x + 125, b[i].y + 160, 50, 20, { - lineColor: '#00f', - lineWidth: 2, - fillColor: '#ccf' + lineColor: '#00f', + lineWidth: 2, + fillColor: '#ccf' }) i++ title(i, "网格") g.grid(b[i].x + 25, b[i].y + 10, 200, 200, 20, { - lineColor: '#ccc', - lineWidth: 1 + lineColor: '#ccc', + lineWidth: 1 }) i++ @@ -225,15 +225,15 @@ g.text(b[i].x + 10, b[i].y + 120, "你好呀", { color: "#f00", width: 100, heig g.text(b[i].x + 10, b[i].y + 180, "截断测试", { color: "#f00", width: 50, noWrap: true, borderColor: '#f90', paddingX: 4, shadowOffset: 2, borderRadius: 4 }) g.text(b[i].x + 120, b[i].y + 10, "这是一段长文本,Cut me cut me cut me\nabcdefg1234567890\n\r【结束】", { - color: "#00f", - width: 120, - align: 'center', - bgColor: '#cff', - borderWidth: 2, - borderRadius: 4, - paddingX: 8, - paddingY: 4, - lineHeight: 1.2, + color: "#00f", + width: 120, + align: 'center', + bgColor: '#cff', + borderWidth: 2, + borderRadius: 4, + paddingX: 8, + paddingY: 4, + lineHeight: 1.2, }) i++ @@ -423,36 +423,36 @@ g.put(s1, b[i].x, b[i].y) g.rect(b[i].x, b[i].y, 250, 70, { lineColor: '#f90' }) for (let j = 1; j <= 5; j++) { - let lvB = j - let lvT = j <= 3 ? 1 : 2 - title(i, "验证码 背景Lv " + lvB + '+' + lvT) - s1 = img.createImage(250, 70) - s1.setSansSerifFont(24) - s1.randBG(lvB) - s1.randText("123456") - s1.randBG(lvT) - g.put(s1, b[i].x, b[i].y) - g.rect(b[i].x, b[i].y, 250, 70, { lineColor: '#f90' }) + let lvB = j + let lvT = j <= 3 ? 1 : 2 + title(i, "验证码 背景Lv " + lvB + '+' + lvT) + s1 = img.createImage(250, 70) + s1.setSansSerifFont(24) + s1.randBG(lvB) + s1.randText("123456") + s1.randBG(lvT) + g.put(s1, b[i].x, b[i].y) + g.rect(b[i].x, b[i].y, 250, 70, { lineColor: '#f90' }) - s1 = img.createImage(250, 70) - s1.setSansSerifFont(24) - s1.randBG(lvB) - let r = s1.randText("你拧情") - s1.randBG(lvT) - for (let rect of r) { - s1.rect(rect[0], rect[1], rect[2], rect[3], { lineColor: '#f90' }) - } - g.put(s1, b[i].x, b[i].y + 75) - g.rect(b[i].x, b[i].y + 75, 250, 70, { lineColor: '#f90' }) + s1 = img.createImage(250, 70) + s1.setSansSerifFont(24) + s1.randBG(lvB) + let r = s1.randText("你拧情") + s1.randBG(lvT) + for (let rect of r) { + s1.rect(rect[0], rect[1], rect[2], rect[3], { lineColor: '#f90' }) + } + g.put(s1, b[i].x, b[i].y + 75) + g.rect(b[i].x, b[i].y + 75, 250, 70, { lineColor: '#f90' }) - s1 = img.createImage(250, 70) - s1.setSansSerifFont(24) - s1.randBG(lvB) - s1.randText("A1CL") - s1.randBG(lvT) - g.put(s1, b[i].x, b[i].y + 150) - g.rect(b[i].x, b[i].y + 150, 250, 70, { lineColor: '#f90' }) - i++ + s1 = img.createImage(250, 70) + s1.setSansSerifFont(24) + s1.randBG(lvB) + s1.randText("A1CL") + s1.randBG(lvT) + g.put(s1, b[i].x, b[i].y + 150) + g.rect(b[i].x, b[i].y + 150, 250, 70, { lineColor: '#f90' }) + i++ } diff --git a/testimg/全面绘图测试.png b/testimg/全面绘图测试.png index df9d6ad..5850696 100644 Binary files a/testimg/全面绘图测试.png and b/testimg/全面绘图测试.png differ