diff --git a/assets/crystay_ball_1f52e.png b/assets/crystay_ball_1f52e.png new file mode 100644 index 0000000..156221b Binary files /dev/null and b/assets/crystay_ball_1f52e.png differ diff --git a/assets/moon.png b/assets/moon.jpg similarity index 100% rename from assets/moon.png rename to assets/moon.jpg diff --git a/assets/sun.png b/assets/sun.png deleted file mode 100644 index 52c4f7d..0000000 Binary files a/assets/sun.png and /dev/null differ diff --git a/cards.go b/cards.go index 4a4042f..3cdfb78 100644 --- a/cards.go +++ b/cards.go @@ -9,8 +9,10 @@ import ( "image/color" "image/draw" "image/jpeg" + "image/png" "io/fs" "math" + "path/filepath" "sync" "github.com/disintegration/imaging" @@ -72,12 +74,17 @@ func mustReadImg(p string) image.Image { panic(err) } - pic, err := jpeg.Decode(bytes.NewReader(data)) + var img image.Image + if filepath.Ext(p) == ".png" { + img, err = png.Decode(bytes.NewReader(data)) + } else { + img, err = jpeg.Decode(bytes.NewReader(data)) + } if err != nil { panic(err) } - return pic + return img } func imageTypeToRGBA64(m image.Image) *image.RGBA64 { @@ -200,8 +207,8 @@ func processIcon(pic image.Image) image.Image { } func initIcon() { - askerImg := processIcon(mustReadImg("assets/sun.png")) - readerImg := processIcon(mustReadImg("assets/moon.png")) + askerImg := processIcon(mustReadImg("assets/moon.jpg")) + readerImg := processIcon(mustReadImg("assets/crystay_ball_1f52e.png")) assets.AskerImg = askerImg assets.ReaderImg = readerImg diff --git a/go.mod b/go.mod index 828f353..5f8eafd 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,5 @@ require ( require ( github.com/fogleman/gg v1.3.0 github.com/sashabaranov/go-openai v1.9.4 - github.com/yanyiwu/gojieba v1.3.0 golang.org/x/sys v0.5.0 // indirect ) diff --git a/go.sum b/go.sum index c6c9f9e..00bb5ea 100644 --- a/go.sum +++ b/go.sum @@ -18,8 +18,6 @@ github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVs github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/yanyiwu/gojieba v1.3.0 h1:6VeaPOR+MawnImdeSvWNr7rP4tvUfnGlEKaoBnR33Ds= -github.com/yanyiwu/gojieba v1.3.0/go.mod h1:54wkP7sMJ6bklf7yPl6F+JG71dzVUU1WigZbR47nGdY= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= diff --git a/reader.go b/reader.go index 9e486a5..9a3c6c4 100644 --- a/reader.go +++ b/reader.go @@ -62,9 +62,6 @@ func (r *Reader) Choose() ([3]Card, error) { const ( defaultSystemPrompt = `你是一位神秘的塔罗牌占卜师,请根据三张牌面和用户占卜的具体事情进行客观解读,语言简练精辟客观,不准回答模棱两可的话,不用提醒用户占卜的局限性或者意义,要明确指出预兆是好的还是坏的。` defaultUserPrompt = `我抽到的三张塔罗牌分别是:{{card1}},{{card2}},{{card3}}。我想占卜的事情是:“{{thing}}”,请解读。` - defaultPrompt = ` -假如你是一位神秘的塔罗牌占卜师,我想要占卜事情是 “{{thing}}”,我抽到的三张牌分别是:{{card1}},{{card2}},{{card3}}。 -请根据三张牌面和这件具体事情进行解读,语言简练精辟客观,不准使用“虽然...但是...”这样模棱两可的话,千万不要建议我或者安慰我,不要提醒我占卜的局限性或者意义。` ) func (r *Reader) sanitizeThing(thing string) string { @@ -224,7 +221,6 @@ func wrapText(text string, maxWidth int, face font.Face) []string { // spacing and text alignment. func DrawStringWrapped(dc *gg.Context, ff font.Face, s string, x, y, ax, ay, width, lineSpacing float64, align gg.Align) float64 { lines := wrapText(s, int(width), ff) - // originalY := y // sync h formula with MeasureMultilineString h := float64(len(lines)) * dc.FontHeight() * lineSpacing @@ -314,18 +310,24 @@ func (r *Reader) Render(cards [3]Card, Q, A string, opt DivineOption) (image.Ima ff = truetype.NewFace(r.assets.Font, &truetype.Options{ Size: 18, }) - dc.SetFontFace(ff) - - dc.DrawImageAnchored(opt.AskerImg, aW-75, 20, 0, 0) - dc.DrawStringAnchored(opt.Asker+":", float64(aW-75+30+5), float64(20+15), 0, 0.5) - yAsker := DrawStringWrapped(dc, ff, Q, - float64(aW-75), float64(20+30+10), 0, 0, float64(defaultImageWidth/3), 1, gg.AlignLeft) - - dc.DrawImageAnchored(opt.ReaderImg, aW-75, int(yAsker)+20, 0, 0) - dc.DrawStringAnchored(opt.Reader+":", float64(aW-75+30+5), float64(yAsker+20+15), 0, 0.5) - DrawStringWrapped(dc, ff, A, - float64(aW-75), float64(yAsker+20+30+10), 0, 0, float64(defaultImageWidth/3), 1, gg.AlignLeft) + // Draw text. + textImg := gg.NewContext(defaultImageWidth-(aW-75), defaultImageHeight) + textImg.SetColor(color.White) + textImg.SetFontFace(ff) + textImg.DrawImageAnchored(opt.AskerImg, 0, 0, 0, 0) + textImg.DrawStringAnchored(opt.Asker+":", float64(30+5), float64(15), 0, 0.5) + yAsker := DrawStringWrapped(textImg, ff, Q, + 0, float64(30+10), 0, 0, float64(defaultImageWidth/3), 1, gg.AlignLeft) + textImg.DrawImageAnchored(opt.ReaderImg, 0, int(yAsker)+20, 0, 0) + textImg.DrawStringAnchored(opt.Reader+":", float64(30+5), float64(yAsker+20+15), 0, 0.5) + yAsker = DrawStringWrapped(textImg, ff, A, + 0, float64(yAsker+20+30+10), 0, 0, float64(defaultImageWidth/3), 1, gg.AlignLeft) + + textImg.ShearAbout(float64(textImg.Width()), float64(yAsker), 0, 0) + cropTextImg := imaging.Crop(textImg.Image(), image.Rect(0, 0, textImg.Width(), int(yAsker+5))) + + dc.DrawImageAnchored(cropTextImg, aW-75, defaultImageHeight/2, 0, 0.5) return dc.Image(), nil }