mirror of
https://github.com/aljazceru/njump.git
synced 2025-12-17 14:24:27 +01:00
Add text preview for Facebook / Instagram
This commit is contained in:
@@ -107,12 +107,19 @@ func drawImage(
|
|||||||
paddingLeft := 25
|
paddingLeft := 25
|
||||||
gradientRectHeight := 140
|
gradientRectHeight := 140
|
||||||
barHeight := 70
|
barHeight := 70
|
||||||
|
barScale := 1.0
|
||||||
switch style {
|
switch style {
|
||||||
case StyleTelegram:
|
case StyleTelegram:
|
||||||
paddingLeft += 10
|
paddingLeft += 10
|
||||||
width -= 10
|
width -= 10
|
||||||
case StyleTwitter:
|
case StyleTwitter:
|
||||||
height = width * 268 / 512
|
height = width * 268 / 512
|
||||||
|
case StyleFacebook:
|
||||||
|
height = width * 355 / 680
|
||||||
|
paddingLeft = 180
|
||||||
|
barScale = 0.55
|
||||||
|
barHeight = int(float64(barHeight) * barScale)
|
||||||
|
fontSize = 18
|
||||||
}
|
}
|
||||||
|
|
||||||
img := gg.NewContext(width, height)
|
img := gg.NewContext(width, height)
|
||||||
@@ -145,7 +152,7 @@ func drawImage(
|
|||||||
fontData, _ := fonts.ReadFile("fonts/NotoSans.ttf")
|
fontData, _ := fonts.ReadFile("fonts/NotoSans.ttf")
|
||||||
ttf, _ := truetype.Parse(fontData)
|
ttf, _ := truetype.Parse(fontData)
|
||||||
img.SetFontFace(truetype.NewFace(ttf, &truetype.Options{
|
img.SetFontFace(truetype.NewFace(ttf, &truetype.Options{
|
||||||
Size: 6,
|
Size: (6 * barScale),
|
||||||
DPI: 260,
|
DPI: 260,
|
||||||
Hinting: xfont.HintingFull,
|
Hinting: xfont.HintingFull,
|
||||||
}))
|
}))
|
||||||
@@ -168,46 +175,57 @@ func drawImage(
|
|||||||
|
|
||||||
// draw author's name
|
// draw author's name
|
||||||
authorTextX := paddingLeft
|
authorTextX := paddingLeft
|
||||||
|
picHeight := barHeight - 20
|
||||||
if metadata.Picture != "" {
|
if metadata.Picture != "" {
|
||||||
authorImage, err := fetchImageFromURL(metadata.Picture)
|
authorImage, err := fetchImageFromURL(metadata.Picture)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
resizedAuthorImage := resize.Resize(uint(barHeight-20), uint(barHeight-20), roundImage(cropToSquare(authorImage)), resize.Lanczos3)
|
resizedAuthorImage := resize.Resize(uint(barHeight-20), uint(picHeight), roundImage(cropToSquare(authorImage)), resize.Lanczos3)
|
||||||
img.DrawImage(resizedAuthorImage, paddingLeft, height-barHeight+10)
|
img.DrawImage(resizedAuthorImage, paddingLeft, height-barHeight+10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
authorTextY := height - barHeight + (barHeight-picHeight)/2 + 4
|
||||||
|
|
||||||
|
if style == StyleFacebook {
|
||||||
|
authorTextY = height - barHeight + (barHeight-picHeight)/2 - 5
|
||||||
|
authorTextX += 25
|
||||||
|
} else {
|
||||||
authorTextX += 65
|
authorTextX += 65
|
||||||
}
|
}
|
||||||
}
|
|
||||||
authorTextY := height - barHeight + 15
|
|
||||||
authorMaxWidth := width/2.0 - paddingLeft*2
|
|
||||||
img.SetColor(color.White)
|
img.SetColor(color.White)
|
||||||
textImg, _ = drawParagraphs([]string{metadata.ShortName()}, fontSize, width, barHeight)
|
textImg, _ = drawParagraphs([]string{metadata.ShortName()}, fontSize, width, barHeight)
|
||||||
img.DrawImage(textImg, authorTextX, authorTextY)
|
img.DrawImage(textImg, authorTextX, authorTextY)
|
||||||
|
|
||||||
// a gradient to cover too long names
|
// a gradient to cover too long names
|
||||||
|
authorMaxWidth := width/2.0 - paddingLeft*2
|
||||||
img.SetColor(BAR_BACKGROUND)
|
img.SetColor(BAR_BACKGROUND)
|
||||||
img.DrawRectangle(float64(authorTextX+authorMaxWidth), float64(height-barHeight), float64(width-authorTextX-authorMaxWidth), float64(barHeight))
|
img.DrawRectangle(float64(paddingLeft+authorTextX+authorMaxWidth), float64(height-barHeight), float64(width-authorTextX-authorMaxWidth), float64(barHeight))
|
||||||
gradientLength := 60
|
gradientLength := 60
|
||||||
for x := 0; x < gradientLength; x++ {
|
for x := 0; x < gradientLength; x++ {
|
||||||
alpha := uint8(255 - 255*(math.Pow(float64(x)/float64(gradientLength), 2)))
|
alpha := uint8(255 - 255*(math.Pow(float64(x)/float64(gradientLength), 2)))
|
||||||
img.SetRGBA255(int(BAR_BACKGROUND.R), int(BAR_BACKGROUND.G), int(BAR_BACKGROUND.B), int(alpha))
|
img.SetRGBA255(int(BAR_BACKGROUND.R), int(BAR_BACKGROUND.G), int(BAR_BACKGROUND.B), int(alpha))
|
||||||
img.DrawRectangle(float64(authorTextX+authorMaxWidth-x), float64(height-barHeight), 1, float64(barHeight))
|
img.DrawRectangle(float64(paddingLeft+authorTextX+authorMaxWidth-x), float64(height-barHeight), 1, float64(barHeight))
|
||||||
img.Fill()
|
img.Fill()
|
||||||
}
|
}
|
||||||
|
|
||||||
// bottom bar logo
|
// bottom bar logo
|
||||||
logo, _ := static.ReadFile("static/logo.png")
|
logo, _ := static.ReadFile("static/logo.png")
|
||||||
stampImg, _ := png.Decode(bytes.NewBuffer(logo))
|
stampImg, _ := png.Decode(bytes.NewBuffer(logo))
|
||||||
stampWidth := stampImg.Bounds().Dx()
|
stampRatio := float64(stampImg.Bounds().Dx() / stampImg.Bounds().Dy())
|
||||||
stampHeight := stampImg.Bounds().Dy()
|
stampHeight := float64(barHeight) * 0.45
|
||||||
stampX := width - stampWidth - paddingLeft
|
stampWidth := stampHeight * stampRatio
|
||||||
stampY := height - stampHeight - 20
|
resizedStampImg := resize.Resize(uint(stampWidth), uint(stampHeight), stampImg, resize.Lanczos3)
|
||||||
img.DrawImage(stampImg, stampX, stampY)
|
stampX := width - int(stampWidth) - paddingLeft
|
||||||
|
stampY := height - barHeight + (barHeight-int(stampHeight))/2
|
||||||
|
img.DrawImage(resizedStampImg, stampX, stampY)
|
||||||
|
|
||||||
// Draw event date
|
// Draw event date
|
||||||
layout := "2006-01-02 15:04:05"
|
layout := "2006-01-02 15:04:05"
|
||||||
parsedTime, _ := time.Parse(layout, date)
|
parsedTime, _ := time.Parse(layout, date)
|
||||||
formattedDate := parsedTime.Format("Jan 02, 2006")
|
formattedDate := parsedTime.Format("Jan 02, 2006")
|
||||||
img.SetColor(color.RGBA{160, 160, 160, 255})
|
img.SetColor(color.RGBA{160, 160, 160, 255})
|
||||||
img.DrawStringWrapped(formattedDate, float64(width-paddingLeft-stampWidth-260), float64(height-barHeight+22), 0, 0, float64(240), 1.5, gg.AlignRight)
|
img.DrawStringWrapped(formattedDate, float64(width-paddingLeft-int(stampWidth)-250), float64(height-barHeight+(barHeight-int(stampHeight))/2)+3, 0, 0, float64(240), 1.5, gg.AlignRight)
|
||||||
|
|
||||||
return img.Image(), nil
|
return img.Image(), nil
|
||||||
}
|
}
|
||||||
|
|||||||
4
utils.go
4
utils.go
@@ -133,6 +133,7 @@ type Style string
|
|||||||
const (
|
const (
|
||||||
StyleTelegram Style = "telegram"
|
StyleTelegram Style = "telegram"
|
||||||
StyleTwitter = "twitter"
|
StyleTwitter = "twitter"
|
||||||
|
StyleFacebook = "facebook" // Both Facebook and Instagram
|
||||||
StyleIOS = "ios"
|
StyleIOS = "ios"
|
||||||
StyleAndroid = "android"
|
StyleAndroid = "android"
|
||||||
StyleMattermost = "mattermost"
|
StyleMattermost = "mattermost"
|
||||||
@@ -152,12 +153,13 @@ func getPreviewStyle(r *http.Request) Style {
|
|||||||
|
|
||||||
ua := strings.ToLower(r.Header.Get("User-Agent"))
|
ua := strings.ToLower(r.Header.Get("User-Agent"))
|
||||||
accept := r.Header.Get("Accept")
|
accept := r.Header.Get("Accept")
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case strings.Contains(ua, "telegrambot"):
|
case strings.Contains(ua, "telegrambot"):
|
||||||
return StyleTelegram
|
return StyleTelegram
|
||||||
case strings.Contains(ua, "twitterbot"):
|
case strings.Contains(ua, "twitterbot"):
|
||||||
return StyleTwitter
|
return StyleTwitter
|
||||||
|
case strings.Contains(ua, "facebookexternalhit"):
|
||||||
|
return StyleFacebook
|
||||||
case strings.Contains(ua, "iphone"), strings.Contains(ua, "ipad"), strings.Contains(ua, "ipod"):
|
case strings.Contains(ua, "iphone"), strings.Contains(ua, "ipad"), strings.Contains(ua, "ipod"):
|
||||||
return StyleIOS
|
return StyleIOS
|
||||||
case strings.Contains(ua, "android"):
|
case strings.Contains(ua, "android"):
|
||||||
|
|||||||
Reference in New Issue
Block a user