diff --git a/agent.go b/agent.go index 24b434b..70682b2 100644 --- a/agent.go +++ b/agent.go @@ -3,18 +3,18 @@ package goba import ( "bytes" - "crypto/sha256" - "encoding/binary" "encoding/json" "fmt" "image" "io" + "math" "net/http" "strings" "time" "github.com/FloatTech/imgfactory" "github.com/FloatTech/ttl" + "github.com/corona10/goimagehash" "github.com/fumiama/deepinfra" "github.com/fumiama/deepinfra/chat" "github.com/fumiama/deepinfra/model" @@ -121,19 +121,37 @@ func (ag *Agent) SetViewImageAPI(api deepinfra.API, p model.Protocol) { logrus.Debugln("[goba] SetViewImageAPI read body err:", err) continue } - sum := sha256.Sum256(data) - k := binary.LittleEndian.Uint64(sum[:8]) - if desc := ag.imgpcache.Get(k); desc != "" { - msgs[i].Data["__agent_desc__"] = desc - hasset = true - logrus.Debugln("[goba] SetViewImageAPI hit cache") - continue - } img, _, err := image.Decode(bytes.NewReader(data)) if err != nil { logrus.Debugln("[goba] SetViewImageAPI decode img err:", err) continue } + hsh, err := goimagehash.PerceptionHash(img) + if err != nil { + logrus.Debugln("[goba] SetViewImageAPI calc phash err:", err) + continue + } + d := math.MaxInt + desc := "" + _ = ag.imgpcache.Range(func(u uint64, s string) error { + ds, err := goimagehash.NewImageHash(u, goimagehash.PHash).Distance(hsh) + if err != nil { + logrus.Debugln("[goba] SetViewImageAPI calc phash distance err:", err) + return nil + } + if d > ds { + d = ds + desc = s + } + return nil + }) + if d < 8 { // very similar (>87.5%) + msgs[i].Data["__agent_desc__"] = desc + hasset = true + logrus.Debugln("[goba] SetViewImageAPI hit cache with d:", d) + continue + } + img = imgfactory.Limit(img, 1024, 1024) data, err = imgfactory.ToBytes(img) if err != nil { @@ -149,13 +167,13 @@ func (ag *Agent) SetViewImageAPI(api deepinfra.API, p model.Protocol) { model.NewContentImageURL(imgs), model.NewContentText("使用简洁清晰明确的一段中文纯文本描述图片"), ) - desc, err := api.Request(m) + desc, err = api.Request(m) if err != nil { logrus.Debugln("[goba] SetViewImageAPI request API err:", err) continue } msgs[i].Data["__agent_desc__"] = desc - ag.imgpcache.Set(k, desc) + ag.imgpcache.Set(hsh.GetHash(), desc) hasset = true } if hasset { diff --git a/go.mod b/go.mod index 900d605..55c400b 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/FloatTech/imgfactory v0.2.2-0.20230413152719-e101cc3606ef github.com/FloatTech/ttl v0.0.0-20240716161252-965925764562 github.com/RomiChan/syncx v0.0.0-20240418144900-b7402ffdebc7 + github.com/corona10/goimagehash v1.1.1-0.20240121134706-d8115886f360 github.com/fumiama/deepinfra v0.0.0-20250924162107-cf156d49a0fa github.com/pkg/errors v0.9.1 github.com/sirupsen/logrus v1.9.3 @@ -19,6 +20,7 @@ require ( github.com/ericpauley/go-quantize v0.0.0-20200331213906-ae555eb2afa4 // indirect github.com/fumiama/imgsz v0.0.4 // indirect github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect + github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect github.com/tidwall/gjson v1.17.3 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect diff --git a/go.sum b/go.sum index 7306e29..0d65ead 100644 --- a/go.sum +++ b/go.sum @@ -6,6 +6,8 @@ github.com/FloatTech/ttl v0.0.0-20240716161252-965925764562 h1:snfw7FNFym1eNnLrQ github.com/FloatTech/ttl v0.0.0-20240716161252-965925764562/go.mod h1:fHZFWGquNXuHttu9dUYoKuNbm3dzLETnIOnm1muSfDs= github.com/RomiChan/syncx v0.0.0-20240418144900-b7402ffdebc7 h1:S/ferNiehVjNaBMNNBxUjLtVmP/YWD6Yh79RfPv4ehU= github.com/RomiChan/syncx v0.0.0-20240418144900-b7402ffdebc7/go.mod h1:vD7Ra3Q9onRtojoY5sMCLQ7JBgjUsrXDnDKyFxqpf9w= +github.com/corona10/goimagehash v1.1.1-0.20240121134706-d8115886f360 h1:SvD9vQN+3r0wskoSrQ7IOyDmOtRIXhT3rlnf819r/bY= +github.com/corona10/goimagehash v1.1.1-0.20240121134706-d8115886f360/go.mod h1:PFDP0Q0oYvEuipJHMSbeK8tjbuRzkQqjPDYm3n71ITA= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -19,6 +21,8 @@ github.com/fumiama/imgsz v0.0.4 h1:Lsasu2hdSSFS+vnD+nvR1UkiRMK7hcpyYCC0FzgSMFI= github.com/fumiama/imgsz v0.0.4/go.mod h1:bISOQVTlw9sRytPwe8ir7tAaEmyz9hSNj9n8mXMBG0E= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= +github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=