Update PNG output to match PHP impl. better

This commit is contained in:
Maddie Zhan 2020-12-21 00:17:35 +08:00
parent fe438802ca
commit 890bc10096

View File

@ -42,11 +42,15 @@ var (
ipv6Regex = regexp.MustCompile(`(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4})?:)?((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9]))`) ipv6Regex = regexp.MustCompile(`(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4})?:)?((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9]))`)
hostnameRegex = regexp.MustCompile(`"hostname":"([^\\\\"]|\\\\")*"`) hostnameRegex = regexp.MustCompile(`"hostname":"([^\\\\"]|\\\\")*"`)
fontLight, fontBold *truetype.Font fontLight, fontBold *truetype.Font
labelFace, valueFace, smallLabelFace, orgFace, watermarkFace font.Face pingJitterLabelFace, upDownLabelFace, pingJitterValueFace, upDownValueFace, smallLabelFace, ispFace, watermarkFace font.Face
canvasWidth, canvasHeight = 800, 600 canvasWidth, canvasHeight = 500, 286
dpi = 150.0 dpi = 150.0
topOffset = 10
middleOffset = topOffset + 5
bottomOffset = middleOffset - 10
ispOffset = bottomOffset + 8
colorLabel = image.NewUniform(color.RGBA{40, 40, 40, 255}) colorLabel = image.NewUniform(color.RGBA{40, 40, 40, 255})
colorDownload = image.NewUniform(color.RGBA{96, 96, 170, 255}) colorDownload = image.NewUniform(color.RGBA{96, 96, 170, 255})
colorUpload = image.NewUniform(color.RGBA{96, 96, 96, 255}) colorUpload = image.NewUniform(color.RGBA{96, 96, 96, 255})
@ -99,32 +103,44 @@ func Initialize(c *config.Config) {
fontBold = f fontBold = f
} }
labelFace = truetype.NewFace(fontBold, &truetype.Options{ pingJitterLabelFace = truetype.NewFace(fontBold, &truetype.Options{
Size: 26, Size: 12,
DPI: dpi, DPI: dpi,
Hinting: font.HintingFull, Hinting: font.HintingFull,
}) })
valueFace = truetype.NewFace(fontLight, &truetype.Options{ upDownLabelFace = truetype.NewFace(fontBold, &truetype.Options{
Size: 36, Size: 14,
DPI: dpi, DPI: dpi,
Hinting: font.HintingFull, Hinting: font.HintingFull,
}) })
smallLabelFace = truetype.NewFace(fontBold, &truetype.Options{ pingJitterValueFace = truetype.NewFace(fontLight, &truetype.Options{
Size: 20,
DPI: dpi,
Hinting: font.HintingFull,
})
orgFace = truetype.NewFace(fontBold, &truetype.Options{
Size: 16, Size: 16,
DPI: dpi, DPI: dpi,
Hinting: font.HintingFull, Hinting: font.HintingFull,
}) })
upDownValueFace = truetype.NewFace(fontLight, &truetype.Options{
Size: 18,
DPI: dpi,
Hinting: font.HintingFull,
})
smallLabelFace = truetype.NewFace(fontBold, &truetype.Options{
Size: 10,
DPI: dpi,
Hinting: font.HintingFull,
})
ispFace = truetype.NewFace(fontBold, &truetype.Options{
Size: 8,
DPI: dpi,
Hinting: font.HintingFull,
})
watermarkFace = truetype.NewFace(fontLight, &truetype.Options{ watermarkFace = truetype.NewFace(fontLight, &truetype.Options{
Size: 14, Size: 6,
DPI: dpi, DPI: dpi,
Hinting: font.HintingFull, Hinting: font.HintingFull,
}) })
@ -215,7 +231,7 @@ func DrawPNG(w http.ResponseWriter, r *http.Request) {
drawer := &font.Drawer{ drawer := &font.Drawer{
Dst: canvas, Dst: canvas,
Face: labelFace, Face: pingJitterLabelFace,
} }
drawer.Src = colorLabel drawer.Src = colorLabel
@ -223,40 +239,41 @@ func DrawPNG(w http.ResponseWriter, r *http.Request) {
// labels // labels
p := drawer.MeasureString(labelPing) p := drawer.MeasureString(labelPing)
x := canvasWidth/4 - p.Round()/2 x := canvasWidth/4 - p.Round()/2
drawer.Dot = freetype.Pt(x, canvasHeight/10) drawer.Dot = freetype.Pt(x, canvasHeight/10+topOffset)
drawer.DrawString(labelPing) drawer.DrawString(labelPing)
p = drawer.MeasureString(labelJitter) p = drawer.MeasureString(labelJitter)
x = canvasWidth*3/4 - p.Round()/2 x = canvasWidth*3/4 - p.Round()/2
drawer.Dot = freetype.Pt(x, canvasHeight/10) drawer.Dot = freetype.Pt(x, canvasHeight/10+topOffset)
drawer.DrawString(labelJitter) drawer.DrawString(labelJitter)
drawer.Face = upDownLabelFace
p = drawer.MeasureString(labelDownload) p = drawer.MeasureString(labelDownload)
x = canvasWidth/4 - p.Round()/2 x = canvasWidth/4 - p.Round()/2
drawer.Dot = freetype.Pt(x, canvasHeight/2) drawer.Dot = freetype.Pt(x, canvasHeight/2-middleOffset)
drawer.DrawString(labelDownload) drawer.DrawString(labelDownload)
p = drawer.MeasureString(labelUpload) p = drawer.MeasureString(labelUpload)
x = canvasWidth*3/4 - p.Round()/2 x = canvasWidth*3/4 - p.Round()/2
drawer.Dot = freetype.Pt(x, canvasHeight/2) drawer.Dot = freetype.Pt(x, canvasHeight/2-middleOffset)
drawer.DrawString(labelUpload) drawer.DrawString(labelUpload)
drawer.Face = smallLabelFace drawer.Face = smallLabelFace
drawer.Src = colorMeasure drawer.Src = colorMeasure
p = drawer.MeasureString(labelMbps) p = drawer.MeasureString(labelMbps)
x = canvasWidth/4 - p.Round()/2 x = canvasWidth/4 - p.Round()/2
drawer.Dot = freetype.Pt(x, canvasHeight*8/10) drawer.Dot = freetype.Pt(x, canvasHeight*8/10-middleOffset)
drawer.DrawString(labelMbps) drawer.DrawString(labelMbps)
p = drawer.MeasureString(labelMbps) p = drawer.MeasureString(labelMbps)
x = canvasWidth*3/4 - p.Round()/2 x = canvasWidth*3/4 - p.Round()/2
drawer.Dot = freetype.Pt(x, canvasHeight*8/10) drawer.Dot = freetype.Pt(x, canvasHeight*8/10-middleOffset)
drawer.DrawString(labelMbps) drawer.DrawString(labelMbps)
msLength := drawer.MeasureString(labelMS) msLength := drawer.MeasureString(labelMS)
// ping value // ping value
drawer.Face = valueFace drawer.Face = pingJitterValueFace
pingValue := strings.Split(record.Ping, ".")[0] pingValue := strings.Split(record.Ping, ".")[0]
p = drawer.MeasureString(pingValue) p = drawer.MeasureString(pingValue)
@ -271,13 +288,12 @@ func DrawPNG(w http.ResponseWriter, r *http.Request) {
drawer.DrawString(labelMS) drawer.DrawString(labelMS)
// jitter value // jitter value
drawer.Face = valueFace drawer.Face = pingJitterValueFace
jitterValue := strings.Split(record.Jitter, ".")[0] p = drawer.MeasureString(record.Jitter)
p = drawer.MeasureString(jitterValue)
x = canvasWidth*3/4 - (p.Round()+msLength.Round())/2 x = canvasWidth*3/4 - (p.Round()+msLength.Round())/2
drawer.Dot = freetype.Pt(x, canvasHeight*11/40) drawer.Dot = freetype.Pt(x, canvasHeight*11/40)
drawer.Src = colorJitter drawer.Src = colorJitter
drawer.DrawString(jitterValue) drawer.DrawString(record.Jitter)
drawer.Face = smallLabelFace drawer.Face = smallLabelFace
x = x + p.Round() x = x + p.Round()
drawer.Dot = freetype.Pt(x, canvasHeight*11/40) drawer.Dot = freetype.Pt(x, canvasHeight*11/40)
@ -285,17 +301,17 @@ func DrawPNG(w http.ResponseWriter, r *http.Request) {
drawer.DrawString(labelMS) drawer.DrawString(labelMS)
// download value // download value
drawer.Face = valueFace drawer.Face = upDownValueFace
p = drawer.MeasureString(record.Download) p = drawer.MeasureString(record.Download)
x = canvasWidth/4 - p.Round()/2 x = canvasWidth/4 - p.Round()/2
drawer.Dot = freetype.Pt(x, canvasHeight*27/40) drawer.Dot = freetype.Pt(x, canvasHeight*27/40-middleOffset)
drawer.Src = colorDownload drawer.Src = colorDownload
drawer.DrawString(record.Download) drawer.DrawString(record.Download)
// upload value // upload value
p = drawer.MeasureString(record.Upload) p = drawer.MeasureString(record.Upload)
x = canvasWidth*3/4 - p.Round()/2 x = canvasWidth*3/4 - p.Round()/2
drawer.Dot = freetype.Pt(x, canvasHeight*27/40) drawer.Dot = freetype.Pt(x, canvasHeight*27/40-middleOffset)
drawer.Src = colorUpload drawer.Src = colorUpload
drawer.DrawString(record.Upload) drawer.DrawString(record.Upload)
@ -310,28 +326,33 @@ func DrawPNG(w http.ResponseWriter, r *http.Request) {
drawer.Src = colorWatermark drawer.Src = colorWatermark
p = drawer.MeasureString(watermark) p = drawer.MeasureString(watermark)
x = canvasWidth - p.Round() - 5 x = canvasWidth - p.Round() - 5
drawer.Dot = freetype.Pt(x, canvasHeight-10) drawer.Dot = freetype.Pt(x, canvasHeight-bottomOffset)
drawer.DrawString(watermark) drawer.DrawString(watermark)
// timestamp
ts := record.Timestamp.Format("2006-01-02 15:04:05")
p = drawer.MeasureString(ts)
drawer.Dot = freetype.Pt(8, canvasHeight-bottomOffset)
drawer.DrawString(ts)
// separator // separator
for i := canvas.Bounds().Min.X; i < canvas.Bounds().Max.X; i++ { for i := canvas.Bounds().Min.X; i < canvas.Bounds().Max.X; i++ {
canvas.Set(i, canvasHeight-ctx.PointToFixed(14).Round()-10, colorSeparator) canvas.Set(i, canvasHeight-ctx.PointToFixed(6).Round()-bottomOffset, colorSeparator)
} }
// ISP info // ISP info
drawer.Face = orgFace drawer.Face = ispFace
drawer.Src = colorISP drawer.Src = colorISP
drawer.Dot = freetype.Pt(6, canvasHeight-ctx.PointToFixed(14).Round()-15) drawer.Dot = freetype.Pt(8, canvasHeight-ctx.PointToFixed(6).Round()-ispOffset)
if result.RawISPInfo.Organization != "" { var ispString string
removeRegexp := regexp.MustCompile(`AS\d+\s`) if strings.Contains(result.ProcessedString, "-") {
org := removeRegexp.ReplaceAllString(result.RawISPInfo.Organization, "") str := strings.SplitN(result.ProcessedString, "-", 2)
if result.RawISPInfo.Country != "" { if strings.Contains(str[0], "(") {
org += ", " + result.RawISPInfo.Country str = strings.SplitN(str[0], "(", 2)
} }
drawer.DrawString(org) ispString = str[0]
} else {
drawer.DrawString(result.ProcessedString)
} }
drawer.DrawString("ISP: " + ispString)
w.Header().Set("Content-Disposition", "inline; filename="+uuid+".png") w.Header().Set("Content-Disposition", "inline; filename="+uuid+".png")
w.Header().Set("Content-Type", "image/png") w.Header().Set("Content-Type", "image/png")