80 lines
2.1 KiB
Go
80 lines
2.1 KiB
Go
package vision
|
|
|
|
import (
|
|
"image"
|
|
"image/color"
|
|
"image/draw"
|
|
|
|
"github.com/fogleman/gg"
|
|
)
|
|
|
|
// JigsawResult 滑块拼图结果
|
|
type JigsawResult struct {
|
|
Background *Canvas // 带槽口的背景
|
|
Piece *Canvas // 拼图块
|
|
X, Y int // 槽口位置
|
|
}
|
|
|
|
// GenerateJigsaw 生成滑块拼图物料
|
|
func (c *Canvas) GenerateJigsaw(x, y, size int) *JigsawResult {
|
|
sw, sh := c.Width(), c.Height()
|
|
if x < 0 { x = 0 }
|
|
if y < 0 { y = 0 }
|
|
if x+size > sw { x = sw - size }
|
|
if y+size > sh { y = sh - size }
|
|
|
|
// 1. 创建背景副本并绘制槽口
|
|
bg := c.Clone()
|
|
piece := New(size, size)
|
|
|
|
// 定义拼图路径 (带有四个圆润突起/凹陷的拼图块形状)
|
|
drawPuzzlePath := func(dc *gg.Context, px, py, s float64) {
|
|
r := s / 4.0
|
|
dc.MoveTo(px, py)
|
|
dc.LineTo(px+s/2-r, py)
|
|
dc.QuadraticTo(px+s/2, py-r*1.5, px+s/2+r, py) // 上凸起
|
|
dc.LineTo(px+s, py)
|
|
dc.LineTo(px+s, py+s/2-r)
|
|
dc.QuadraticTo(px+s+r*1.5, py+s/2, px+s, py+s/2+r) // 右凸起
|
|
dc.LineTo(px+s, py+s)
|
|
dc.LineTo(px+s/2+r, py+s)
|
|
dc.QuadraticTo(px+s/2, py+s-r*1.5, px+s/2-r, py+s) // 下凹陷 (可以改反向)
|
|
dc.LineTo(px, py+s)
|
|
dc.LineTo(px, py+s/2+r)
|
|
dc.QuadraticTo(px-r*1.5, py+s/2, px, py+s/2-r) // 左凹陷
|
|
dc.ClosePath()
|
|
}
|
|
|
|
// 2. 提取拼图块内容
|
|
// 我们需要一个蒙版来裁剪
|
|
mask := gg.NewContext(sw, sh)
|
|
drawPuzzlePath(mask, float64(x), float64(y), float64(size))
|
|
mask.SetFillRule(gg.FillRuleWinding)
|
|
mask.Fill()
|
|
|
|
// 裁剪 Piece
|
|
draw.DrawMask(piece.dc.Image().(draw.Image), image.Rect(0, 0, size, size), c.dc.Image(), image.Pt(x, y), mask.Image(), image.Pt(x, y), draw.Src)
|
|
|
|
// 3. 在背景上绘制半透明槽口 (遮罩)
|
|
bg.dc.Push()
|
|
drawPuzzlePath(bg.dc, float64(x), float64(y), float64(size))
|
|
bg.dc.SetColor(color.RGBA{0, 0, 0, 160})
|
|
bg.dc.Fill()
|
|
bg.dc.Pop()
|
|
|
|
// 4. 给拼图块加一点描边或投影增强识别度
|
|
piece.dc.Push()
|
|
drawPuzzlePath(piece.dc, 0, 0, float64(size))
|
|
piece.dc.SetColor(color.RGBA{255, 255, 255, 128})
|
|
piece.dc.SetLineWidth(2)
|
|
piece.dc.Stroke()
|
|
piece.dc.Pop()
|
|
|
|
return &JigsawResult{
|
|
Background: bg,
|
|
Piece: piece,
|
|
X: x,
|
|
Y: y,
|
|
}
|
|
}
|