在图像上的动态文本

huangapple go评论87阅读模式
英文:

Dynamic text on image

问题

我有一个应用程序,它创建一个动态图像并在上面写入文本。
英文文本按预期工作,但其他语言完全失败。字母变成方框等。
有什么建议如何解决这个问题吗?

英文:

I have an application that creates a dynamic image and writes text on it.
The English language text works as advertised but other languages fail completely. The letters become boxes, etc.

package main

import (
	"errors"
	"fmt"
	"image"
	"image/color"
	"image/png"
	"math"
	"os"

	"github.com/fogleman/gg"
	guuid "github.com/google/uuid"

	"github.com/jimlawless/whereami"
)

type TextImage struct {
	BgImgPath string
	FontPath  string
	FontSize  float64
	Text      string
}

var sentence = make(map[string]string)
var language string

func init() {
	sentence["arabic"] = "قفز الثعلب البني فوق الكلب الكسول."
	sentence["english"] = "The brown fox jumped over the lazy dog."
	sentence["hebrew"] = "השועל החום קפץ מעל הכלב העצלן."
	sentence["hindi"] = "भूरी लोमड़ी आलसी कुत्ते के ऊपर से कूद गई।."
	sentence["greek"] = "Η καφέ αλεπού πήδηξε πάνω από το τεμπέλικο σκυλί."
}

func main() {
	language = "greek"
	uuid := genUUID()
	createFolder(uuid)
	createImage(len(sentence[language]), uuid)
	writeImage(sentence[language], uuid)
}

func genUUID() string {
	return guuid.New().String()
}

func createFolder(p string) {
	path := "./tmp/" + p
	if _, err := os.Stat(path); errors.Is(err, os.ErrNotExist) {
		err := os.MkdirAll(path, os.ModePerm)
		if err != nil {
			fmt.Println(err.Error() + " @ " + whereami.WhereAmI())
		}
	}
}

func writeImage(text string, path string) {
	ti := TextImage{
		BgImgPath: "./tmp/" + path + "/" + language + ".png",
		FontPath:  "./ttf/PlayfairDisplay-Regular.ttf",
		FontSize:  24,
		Text:      text,
	}
	img, err := textOnImg(ti)
	if err != nil {
		fmt.Println(err.Error() + " @ " + whereami.WhereAmI())
	}
	err = saveImage(img, "./tmp/"+path+"/"+language+".png")
	if err != nil {
		fmt.Println(err.Error() + " @ " + whereami.WhereAmI())
	}
}

func createImage(textlength int, path string) {
	minDim := 300
	scale := 30
	dim := math.Sqrt(float64(textlength))
	width := int(dim) * scale
	height := int(dim) * scale

	if width < minDim || height < minDim {
		width = minDim
		height = minDim
	}

	upLeft := image.Point{0, 0}
	lowRight := image.Point{width, height}

	img := image.NewRGBA(image.Rectangle{upLeft, lowRight})
	//img.Bounds()
	white := color.RGBA{255, 255, 255, 0xff}

	// Set color for each pixel.
	for x := 0; x < width; x++ {
		for y := 0; y < height; y++ {
			switch {
			case x < width/2 && y < height/2: // upper left quadrant
				img.Set(x, y, white)
			case x >= width/2 && y >= height/2: // lower right quadrant
				img.Set(x, y, color.White)
			default:
				img.Set(x, y, color.White)
			}
		}
	}

	f, err := os.Create("./tmp/" + path + "/" + language + ".png")
	if err != nil {
		fmt.Println(err.Error() + " @ " + whereami.WhereAmI())
	}
	err = png.Encode(f, img)
	if err != nil {
		fmt.Println(err.Error() + " @ " + whereami.WhereAmI())
	}
}

func deleteFolder(folder string) {
	err := os.RemoveAll("./tmp/" + folder)
	if err != nil {
		fmt.Println(err.Error() + " @ " + whereami.WhereAmI())
	}
}

func textOnImg(ti TextImage) (image.Image, error) {
	bgImage, err := gg.LoadImage(ti.BgImgPath)
	if err != nil {
		fmt.Println(err.Error() + " @ " + whereami.WhereAmI())
		return nil, err
	}
	imgWidth := bgImage.Bounds().Dx()
	imgHeight := bgImage.Bounds().Dy()

	dc := gg.NewContext(imgWidth, imgHeight)
	dc.DrawImage(bgImage, 0, 0)

	if err := dc.LoadFontFace(ti.FontPath, ti.FontSize); err != nil {
		fmt.Println(err.Error() + " @ " + whereami.WhereAmI())
		return nil, err
	}

	x := float64(imgWidth / 2)
	y := float64((imgHeight / 2) - 80)
	maxWidth := float64(imgWidth) - 60.0
	dc.SetColor(color.Black)
	fmt.Println(ti.Text)
	dc.DrawStringWrapped(ti.Text, x, y, 0.5, 0.5, maxWidth, 1.5, gg.AlignLeft)

	return dc.Image(), nil
}

func saveImage(img image.Image, path string) error {
	if err := gg.SavePNG(path, img); err != nil {
		fmt.Println(err.Error() + " @ " + whereami.WhereAmI())
		return err
	}
	return nil
}

Any recommendations how to fix this?

答案1

得分: 2

我更改了一行代码(如@dmitry建议的),并使其在Windows上工作:

		FontPath: "C:/Windows/Fonts/arial.ttf",

顺便说一句,你可以使用映射字面量代替init()调用。

var sentence = map[string]string{
	"arabic":  "قفز الثعلب البني فوق الكلب الكسول.",
	"english": "The brown fox jumped over the lazy dog.",
	"hebrew":  "השועל החום קפץ מעל הכלב העצלן.",
	"hindi":   "भूरी लोमड़ी आलसी कुत्ते के ऊपर से कूद गई।",
	"greek":   "Η καφέ αλεπού πήδηξε πάνω από το τεμπέλικο σκυλί.",
}
英文:

I changed one line (as @dmitry suggested) and got it to work (Windows):

		FontPath: "C:/Windows/Fonts/arial.ttf",

BTW you can use a map literal instead of the init() call.

var sentence = map[string]string{
	"arabic":  "قفز الثعلب البني فوق الكلب الكسول.",
	"english": "The brown fox jumped over the lazy dog.",
	"hebrew":  "השועל החום קפץ מעל הכלב העצלן.",
	"hindi":   "भूरी लोमड़ी आलसी कुत्ते के ऊपर से कूद गई।.",
	"greek":   "Η καφέ αλεπού πήδηξε πάνω από το τεμπέλικο σκυλί.",
}

huangapple
  • 本文由 发表于 2022年5月31日 06:29:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/72440589.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定