Skip to content

Instantly share code, notes, and snippets.

@romanitalian
Created November 8, 2020 07:26
Show Gist options
  • Save romanitalian/0a566be6a01f0851015b12ec78dc6647 to your computer and use it in GitHub Desktop.
Save romanitalian/0a566be6a01f0851015b12ec78dc6647 to your computer and use it in GitHub Desktop.
pacakge img
const (
// Default setting
imgColorDefault = "E5E5E5"
msgColorDefault = "AAAAAA"
imgWDefault = 300
imgHDefault = 300
fontSizeDefault = 0
dpiDefault float64 = 72
fontfileDefault = "wqy-zenhei.ttf"
)
// Do - entrypoint.
func Do(params []string) (*bytes.Buffer, error) {
// fetch img params: imgW, imgH, text, etc
// Just make the Text structure
label := Label{Text: msg, FontSize: fontSize, Color: msgColor}
// make the Image structure with the necessary fields - height, width, color, and text
img := Img{Width: imgW, Height: imgH, Color: imgColor, Label: label}
// generate our image with the text
return img.generate()
}
// generate - make the image according to the desired size, color, and text.
func (i Img) generate() (*bytes.Buffer, error) {
// If there are dimensions and there are no requirements for the Text, we will build the default Text.
if ((i.Width > 0 || i.Height > 0) && i.Text == "") || i.Text == "" {
i.Text = fmt.Sprintf("%d x %d", i.Width, i.Height)
}
// If there are no parameters for the font size, we will construct it based on the sizes of the image.
if i.FontSize == 0 {
i.FontSize = i.Width / 10
if i.Height < i.Width {
i.FontSize = i.Height / 5
}
}
// Convert the color from string to color.RGBA.
clr, err := colors.ToRGBA(i.Color)
if err != nil {
return nil, err
}
// Create an in-memory image with the desired size.
m := image.NewRGBA(image.Rect(0, 0, i.Width, i.Height))
//Draw a picture:
// - in the sizes (Bounds)
// - with color (Uniform - wrapper above color.Color with Image functions)
// - based on the point (Point) as the base image
// - fill with color Uniform (draw.Src)
draw.Draw(m, m.Bounds(), image.NewUniform(clr), image.Point{}, draw.Src)
// add a text in the picture.
if err = i.drawLabel(m); err != nil {
return nil, err
}
var im image.Image = m
// Allocate memory for our data (the bytes of the image)
buffer := &bytes.Buffer{}
// Let's encode the image into our allocated memory.
err = jpeg.Encode(buffer, im, nil)
return buffer, err
}
// drawLabel - add a text in the picture
func (i *Img) drawLabel(m *image.RGBA) error {
// Convert string text to RGBA.
clr, err := colors.ToRGBA(i.Label.Color)
if err != nil {
return err
}
// Get the font (should work with both latin and cyrillic).
fontBytes, err := ioutil.ReadFile(fontfileDefault)
if err != nil {
return err
}
fnt, err := truetype.Parse(fontBytes)
if err != nil {
return err
}
// Prepare a Drawer for drawing text on the image.
d := &font.Drawer{
Dst: m,
Src: image.NewUniform(clr),
Face: truetype.NewFace(fnt, &truetype.Options{
Size: float64(i.FontSize),
DPI: dpiDefault,
Hinting: font.HintingNone,
}),
}
//Setting the baseline.
d.Dot = fixed.Point26_6{
X: (fixed.I(i.Width) - d.MeasureString(i.Text)) / 2,
Y: fixed.I((i.Height+i.FontSize)/2 - 12),
}
// Directly rendering text to our RGBA image.
d.DrawString(i.Text)
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment