Skip to content

Commit

Permalink
图像自适应比例
Browse files Browse the repository at this point in the history
图像自适应比例
  • Loading branch information
fumiama authored Feb 23, 2023
2 parents ff07458 + c8af518 commit 45d29fa
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 81 deletions.
Binary file modified .github/DrawCard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified .github/DrawTitle.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified .github/DrawTitleWithText.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 26 additions & 16 deletions card.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ import (
"errors"
"image"
"math/rand"
"strings"

"github.com/FloatTech/gg"
"github.com/FloatTech/imgfactory"
)

var (
Expand All @@ -28,24 +26,18 @@ func (c *Card) DrawTextCard() (imgForCard image.Image, err error) {
return nil, ErrNilTextFont
}
// 正文数据
textString := ""
if c.IsTextSplitPerElement {
textString = strings.Join(c.Text, "\n")
} else {
textString = strings.Join(c.Text, " ")
}
textImg, err := imgfactory.RenderTextWith(textString, c.TextFontData, width-80, 38)
texts, err := Truncate(c.TextFontData, c.Text, float64(width)-80, 38)
if err != nil {
return
}
textHigh := textImg.Bounds().Dy()
textHigh := float64(len(texts)+1) * 38 * 72 / 96 * 1.5
// 计算图片高度
imgHigh := c.Height
if imgHigh == 0 {
if c.CanTitleShown {
imgHigh = 30 + 100 + textHigh + 20
imgHigh = 30 + 100 + int(textHigh) + 20
} else {
imgHigh = 20 + textHigh + 20
imgHigh = 20 + int(textHigh) + 20
}
}
// 创建画布
Expand All @@ -56,11 +48,21 @@ func (c *Card) DrawTextCard() (imgForCard image.Image, err error) {
canvas.SetRGBA255(rand.Intn(45)+165, rand.Intn(45)+165, rand.Intn(45)+165, 255)
canvas.Fill()
} else {
banner, err := imgfactory.LoadFirstFrame(c.BackgroundImage, width, imgHigh)
banner, err := gg.LoadImage(c.BackgroundImage)
if err == nil {
canvas.DrawImage(imgfactory.Size(banner.Image(), width, imgHigh).Image(), 0, 0)
if float64(banner.Bounds().Dy())/float64(banner.Bounds().Dx()) < float64(canvas.H())/float64(canvas.W()) {
sc := float64(canvas.H()) / float64(banner.Bounds().Dy())
canvas.ScaleAbout(sc, sc, float64(canvas.W())/2, float64(canvas.H())/2)
canvas.DrawImageAnchored(banner, canvas.W()/2, canvas.H()/2, 0.5, 0.5)
} else {
sc := float64(canvas.W()) / float64(banner.Bounds().Dx())
canvas.Scale(sc, sc)
canvas.DrawImage(banner, 0, 0)
}
canvas.Identity()
}
}
y := 0.0
// 标题
if c.CanTitleShown {
if c.TitleFontData == nil {
Expand All @@ -87,10 +89,18 @@ func (c *Card) DrawTextCard() (imgForCard image.Image, err error) {
canvas.SetRGB(0, 0, 0)
canvas.Fill()
// 内容
canvas.DrawImage(textImg, 10, 130)
y = 130 + 38*72/96*1.5
} else {
// 内容
canvas.DrawImage(textImg, 10, 20)
y = 20 + 38*72/96*1.5
}
err = canvas.ParseFontFace(c.TextFontData, 38)
if err != nil {
return
}
for _, s := range texts {
canvas.DrawStringAnchored(s, 10, y, 0, 0.5)
y += canvas.FontHeight() * 1.5
}
// 制图
imgForCard = canvas.Image()
Expand Down
2 changes: 0 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@ go 1.19

require (
github.com/FloatTech/gg v1.1.2
github.com/FloatTech/imgfactory v0.2.2-0.20230215052637-9f7b05520ca9
github.com/disintegration/imaging v1.6.2
github.com/stretchr/testify v1.8.1
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/ericpauley/go-quantize v0.0.0-20200331213906-ae555eb2afa4 // indirect
github.com/fumiama/imgsz v0.0.2 // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
Expand Down
4 changes: 0 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
github.com/FloatTech/gg v1.1.2 h1:YolgOYg3uDHc1+g0bLtt6QuRA/pvLn+b9IBCIhOOX88=
github.com/FloatTech/gg v1.1.2/go.mod h1:uzPzAeT35egARdRuu+1oyjU3CmTwCceoq3Vvje7LpcI=
github.com/FloatTech/imgfactory v0.2.2-0.20230215052637-9f7b05520ca9 h1:Havq0z/N79KeD50L7ms+Hv8F4Sw98Dt8lXM8jECp04o=
github.com/FloatTech/imgfactory v0.2.2-0.20230215052637-9f7b05520ca9/go.mod h1:el5hGpj1C1bDRxcTXYRwEivDCr40zZeJpcrLrB1fajs=
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=
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
github.com/ericpauley/go-quantize v0.0.0-20200331213906-ae555eb2afa4 h1:BBade+JlV/f7JstZ4pitd4tHhpN+w+6I+LyOS7B4fyU=
github.com/ericpauley/go-quantize v0.0.0-20200331213906-ae555eb2afa4/go.mod h1:H7chHJglrhPPzetLdzBleF8d22WYOv7UM/lEKYiwlKM=
github.com/fumiama/imgsz v0.0.2 h1:fAkC0FnIscdKOXwAxlyw3EUba5NzxZdSxGaq3Uyfxak=
github.com/fumiama/imgsz v0.0.2/go.mod h1:dR71mI3I2O5u6+PCpd47M9TZptzP+39tRBcbdIkoqM4=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
Expand Down
86 changes: 48 additions & 38 deletions title.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"image"

"github.com/FloatTech/gg"
"github.com/FloatTech/imgfactory"
)

// DrawTitle 绘制标题
Expand All @@ -24,7 +23,7 @@ func (t *Title) DrawTitle() (imgs image.Image, err error) {
canvas.SetRGBA255(0, 0, 0, 153)
canvas.Fill()

fontsize1, fontsize2 := 108.0+t.TitleFontOffsetPoint, 54.0+t.TextFontOffsetPoint
fontsize1, fontsize2, fontsize3 := 108.0+t.TitleFontOffsetPoint, 72+t.TextFontOffsetPoint, 54.0+t.TextFontOffsetPoint
// 加载size为108的字体
err = canvas.ParseFontFace(t.TitleFontData, fontsize1)
if err != nil {
Expand All @@ -33,37 +32,35 @@ func (t *Title) DrawTitle() (imgs image.Image, err error) {

// 绘制标题
canvas.SetRGBA255(250, 250, 250, 255)
stringwight, _ := canvas.MeasureString(t.LeftTitle)
canvas.DrawStringAnchored(t.LeftTitle, (220-(fontsize1+fontsize2)*72/96)*0.33+stringwight/2+t.OffsetX, 30+40+(220-(fontsize1+fontsize2)*72/96)*0.33+fontsize1*72/96*0.5+t.OffsetY, 0.5, 0.5)
canvas.DrawStringAnchored(t.LeftTitle, (220-fontsize1-fontsize3)/3+t.OffsetX, 30+40+(220-fontsize1-fontsize3)/3+fontsize1/2+t.OffsetY, 0, 0.5)

// 加载size为54的字体
err = canvas.ParseFontFace(t.TextFontData, fontsize2)
err = canvas.ParseFontFace(t.TextFontData, fontsize3)
if err != nil {
return
}

canvas.SetRGBA255(250, 250, 250, 255)
// 绘制副标题
stringwight, _ = canvas.MeasureString(t.LeftSubtitle)
canvas.DrawStringAnchored(t.LeftSubtitle, 3+(220-(fontsize1+fontsize2)*72/96)*0.33+stringwight/2+t.OffsetX, 30+40+(220-(fontsize1+fontsize2)*72/96)*0.66+fontsize1*72/96+fontsize2*72/96*0.5+t.OffsetY, 0.5, 0.5)
canvas.DrawStringAnchored(t.LeftSubtitle, 3+(220-fontsize1-fontsize3)/3+t.OffsetX, 30+40+(220-fontsize1-fontsize3)/3*2+fontsize1+fontsize3/2+t.OffsetY, 0, 0.5)

// 加载icon并绘制
var icon *imgfactory.Factory
icon, err = imgfactory.LoadFirstFrame(t.ImagePath, 220, 220)
// 加载icon并绘制 高限制220
var icon image.Image
icon, err = gg.LoadImage(t.ImagePath)
if err != nil {
return
}
canvas.DrawImage(icon.Image(), int(DefaultWidth)-icon.W(), 40+30)
sc := 220 / float64(icon.Bounds().Dy())
canvas.ScaleAbout(sc, sc, DefaultWidth-float64(icon.Bounds().Dx())*sc/2, 40+30+220/2)
canvas.DrawImageAnchored(icon, int(DefaultWidth)-int(float64(icon.Bounds().Dx())*sc/2), 40+30+220/2, 0.5, 0.5)
canvas.Identity()
// 加载size为72的字体
fontsize1 = 72 + t.TextFontOffsetPoint
err = canvas.ParseFontFace(t.TextFontData, fontsize1)
err = canvas.ParseFontFace(t.TextFontData, fontsize2)
if err != nil {
return
}
stringwight, _ = canvas.MeasureString(t.RightTitle)
canvas.DrawStringAnchored(t.RightTitle, DefaultWidth-25-float64(icon.W())-stringwight/2+t.OffsetX, 30+40+(220-fontsize1*72/96*2)*0.33+fontsize1*72/96*0.5+t.OffsetY, 0.5, 0.5)
stringwight, _ = canvas.MeasureString(t.RightSubtitle)
canvas.DrawStringAnchored(t.RightSubtitle, DefaultWidth-25-float64(icon.W())-stringwight/2+t.OffsetX, 30+40+(220-fontsize1*72/96*2)*0.66+fontsize1*72/96*1.5+t.OffsetY, 0.5, 0.5)
canvas.DrawStringAnchored(t.RightTitle, DefaultWidth-float64(icon.Bounds().Dx())*sc-25+t.OffsetX, 30+40+(220-fontsize2*2)/3+fontsize2/2+t.OffsetY, 1, 0.5)
canvas.DrawStringAnchored(t.RightSubtitle, DefaultWidth-float64(icon.Bounds().Dx())*sc-25+t.OffsetX, 30+40+(220-fontsize2*2)/3*2+fontsize2+fontsize2/2+t.OffsetY, 1, 0.5)

imgs = canvas.Image()
return
Expand All @@ -83,15 +80,24 @@ func (t *Title) DrawTitleWithText(info []string) (imgs image.Image, err error) {
canvas.Clear()

// 加载icon
var icon *imgfactory.Factory
icon, err = imgfactory.LoadFirstFrame(t.ImagePath, 512, 512)
var icon image.Image
icon, err = gg.LoadImage(t.ImagePath)
if err != nil {
return
}
canvas.DrawImage(icon.Image(), DefaultWidth-icon.W(), imgh-icon.H())
sc := 0.0
if float64(icon.Bounds().Dy())/float64(icon.Bounds().Dx()) >= 1 {
sc = DefaultWidth / 2 / float64(icon.Bounds().Dy())
} else {
sc = DefaultWidth / 2 / float64(icon.Bounds().Dx())
}
canvas.ScaleAbout(sc, sc, float64(canvas.W()), float64(canvas.H()))
canvas.DrawImageAnchored(icon, canvas.W(), canvas.H(), 1, 1)
canvas.Identity()

// 加载size为108的字体
fontsize1, fontsize2 := 108.0+t.TitleFontOffsetPoint, 54.0+t.TextFontOffsetPoint
fsp1, fsp2 := fontsize1*72/96, fontsize2*72/96
err = canvas.ParseFontFace(t.TitleFontData, fontsize1)
if err != nil {
return
Expand All @@ -100,8 +106,7 @@ func (t *Title) DrawTitleWithText(info []string) (imgs image.Image, err error) {
canvas.SetRGBA255(15, 15, 15, 255)

// 绘制标题
stringwight, _ := canvas.MeasureString(t.LeftTitle)
canvas.DrawStringAnchored(t.LeftTitle, 25+stringwight/2+t.OffsetX, 25+fontsize1*72/96*0.5+t.OffsetY, 0.5, 0.5)
canvas.DrawStringAnchored(t.LeftTitle, 25+t.OffsetX, 25+fsp1/2+t.OffsetY, 0, 0.5)

// 加载size为54的字体
err = canvas.ParseFontFace(t.TextFontData, fontsize2)
Expand All @@ -110,10 +115,9 @@ func (t *Title) DrawTitleWithText(info []string) (imgs image.Image, err error) {
}

// 绘制一系列标题
stringwight, _ = canvas.MeasureString(t.LeftSubtitle)
canvas.DrawStringAnchored(t.LeftSubtitle, 25+3+stringwight/2+t.OffsetX, 25+fontsize1*72/96+25+fontsize2*72/96*0.5+t.OffsetY, 0.5, 0.5)

canvas.DrawRectangle(25+3+t.OffsetX, 25+fontsize1*72/96+25+fontsize2*72/96+7+t.OffsetY, stringwight, 6)
canvas.DrawStringAnchored(t.LeftSubtitle, 25+3+t.OffsetX, 25+fsp1+25+fsp2/2+t.OffsetY, 0, 0.5)
stringwight, _ := canvas.MeasureString(t.LeftSubtitle)
canvas.DrawRectangle(25+3+t.OffsetX, 25+fsp1+25+fsp2+7+t.OffsetY, stringwight, 6)
// 绘制插件开启状态
if t.IsEnabled {
canvas.SetRGBA255(35, 235, 35, 255)
Expand All @@ -129,18 +133,16 @@ func (t *Title) DrawTitleWithText(info []string) (imgs image.Image, err error) {
return
}

stringwight, _ = canvas.MeasureString(t.RightTitle)
canvas.DrawStringAnchored(t.RightTitle, DefaultWidth-40-stringwight/2+t.OffsetX, 40+fontsize2*72/96*0.5+t.OffsetY, 0.5, 0.5)
stringwight, _ = canvas.MeasureString(t.RightSubtitle)
canvas.DrawStringAnchored(t.RightSubtitle, DefaultWidth-40-stringwight/2+t.OffsetX, 40+25+fontsize2*72/96*1.5+t.OffsetY, 0.5, 0.5)
canvas.DrawStringAnchored(t.RightTitle, DefaultWidth-40+t.OffsetX, 40+fsp2/2+t.OffsetY, 1, 0.5)
canvas.DrawStringAnchored(t.RightSubtitle, DefaultWidth-40+t.OffsetX, 40+fsp2+25+fsp2/2+t.OffsetY, 1, 0.5)

// 加载size为38的字体
err = canvas.ParseFontFace(t.TextFontData, 38+t.TextFontOffsetPoint)
if err != nil {
return
}

y := 25 + fontsize1*72/96 + 25 + fontsize2*72/96
y := 25 + fsp1 + 25 + fsp2
for _, text := range info {
canvas.DrawString(text, 25.0, y+canvas.FontHeight()*2)
y += 20 + canvas.FontHeight()
Expand All @@ -154,14 +156,21 @@ func (t *Title) DrawCard() (imgs image.Image, err error) {
recw, rech := 384.0, 256.0
canvas := gg.NewContext(int(recw), int(rech))
// 绘制图片
var banner *imgfactory.Factory
banner, err = imgfactory.LoadFirstFrame(t.ImagePath, int(recw)*2, int(rech)*2)
var banner image.Image
banner, err = gg.LoadImage(t.ImagePath)
if err == nil {
canvas.DrawImage(imgfactory.Size(banner.Image(), int(recw), int(rech)).Image(), 0, 0)
sc := 0.0
if float64(banner.Bounds().Dy())/float64(banner.Bounds().Dx()) < rech/recw {
sc = rech / float64(banner.Bounds().Dy())
} else {
sc = recw / float64(banner.Bounds().Dx())
}
canvas.ScaleAbout(sc, sc, recw/2, rech/2)
canvas.DrawImageAnchored(banner, int(recw)/2, int(rech)/2, 0.5, 0.5)
canvas.Identity()
} else {
canvas.DrawRectangle(0, 0, recw, rech)
canvas.SetRGB255(RandJPColor())
canvas.Fill()
canvas.Clear()
}
if t.IsEnabled {
canvas.DrawRectangle(0, rech*0.54, recw, rech-rech*0.54)
Expand All @@ -174,17 +183,18 @@ func (t *Title) DrawCard() (imgs image.Image, err error) {
// 绘制插件信息
canvas.SetRGBA255(240, 240, 240, 255)
fontsize1, fontsize2 := 64.0+t.TitleFontOffsetPoint, 32.0+t.TextFontOffsetPoint
fsp1, fsp2 := fontsize1*72/96, fontsize2*72/96
err = canvas.ParseFontFace(t.TitleFontData, fontsize1)
if err != nil {
return
}
canvas.DrawStringAnchored(t.LeftTitle, recw/2+t.OffsetX, rech*0.54+(rech-rech*0.54-(fontsize1+fontsize2)*72/96)*0.33+fontsize1*72/96*0.5+t.OffsetY, 0.5, 0.5)
canvas.DrawStringAnchored(t.LeftTitle, recw/2+t.OffsetX, rech*0.54+(rech-rech*0.54-(fsp1+fsp2))/3+fsp1/2+t.OffsetY, 0.5, 0.5)

err = canvas.ParseFontFace(t.TextFontData, fontsize2)
if err != nil {
return
}
canvas.DrawStringAnchored(t.LeftSubtitle, recw/2+t.OffsetX, rech*0.54+(rech-rech*0.54-(fontsize1+fontsize2)*72/96)*0.66+fontsize1*72/96+fontsize2*72/96*0.5+t.OffsetY, 0.5, 0.5)
canvas.DrawStringAnchored(t.LeftSubtitle, recw/2+t.OffsetX, rech*0.54+(rech-rech*0.54-(fsp1+fsp2))/3*2+fsp1+fsp2/2+t.OffsetY, 0.5, 0.5)

imgs = canvas.Image()
return
Expand Down
6 changes: 3 additions & 3 deletions title_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func TestDrawTitle(t *testing.T) {
if err != nil {
t.Fatal(err)
}
assert.Equal(t, "28f9f68f3ef7987a9d189b52b9a8b399", hex.EncodeToString(h.Sum(nil)))
assert.Equal(t, "5450734a22186aa176387ff2a91d9a7e", hex.EncodeToString(h.Sum(nil)))
}

func TestDrawTitleWithText(t *testing.T) {
Expand Down Expand Up @@ -77,7 +77,7 @@ func TestDrawTitleWithText(t *testing.T) {
if err != nil {
t.Fatal(err)
}
assert.Equal(t, "bf5ce310c0a565477fa83904a506c08d", hex.EncodeToString(h.Sum(nil)))
assert.Equal(t, "49c0bb06f1b8e16833e73d2bdcbe01ce", hex.EncodeToString(h.Sum(nil)))
}

func TestDrawCard(t *testing.T) {
Expand Down Expand Up @@ -112,5 +112,5 @@ func TestDrawCard(t *testing.T) {
if err != nil {
t.Fatal(err)
}
assert.Equal(t, "4e1b4c439a78d833b0931655d736b02f", hex.EncodeToString(h.Sum(nil)))
assert.Equal(t, "deba289674306c6d674c0c07f6ae458c", hex.EncodeToString(h.Sum(nil)))
}
24 changes: 6 additions & 18 deletions utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,12 @@ import (
)

// Fillet 将矩形图片裁切为圆角矩形
func Fillet(dst image.Image, r int) image.Image {
dstr := gg.ImageToNRGBA(dst)
mx, my := dst.Bounds().Max.X, dst.Bounds().Max.Y
var xx, yy, rr float64
for y := 0; y < my/2; y++ {
for x := 0; x < mx/2; x++ {
if x <= r && y <= r {
xx, yy, rr = float64(r-x), float64(y-r), float64(r)
if xx*xx+yy*yy >= rr*rr {
dstr.Set(x, y, color.NRGBA{})
dstr.Set(mx-1-x, y, color.NRGBA{})
dstr.Set(x, my-1-y, color.NRGBA{})
dstr.Set(mx-1-x, my-1-y, color.NRGBA{})
}
}
}
}
return dstr
func Fillet(dst image.Image, r float64) image.Image {
canvas := gg.NewContext(dst.Bounds().Dx(), dst.Bounds().Dy())
canvas.DrawRoundedRectangle(0, 0, float64(dst.Bounds().Dx()), float64(dst.Bounds().Dy()), r)
canvas.Clip()
canvas.DrawImage(dst, 0, 0)
return canvas.Image()
}

// Transparency 更改透明度 magnification 倍率值
Expand Down

0 comments on commit 45d29fa

Please sign in to comment.