You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Go语言实现类似placeholder.com的动态尺寸图片及尺寸文本绘制

在Go生成的占位图片上动态绘制尺寸文本

你已经搞定了基础的灰色背景生成,接下来要解决的就是动态适配图片尺寸的文本绘制——这也是placeholder.com那种效果的核心:文本大小、位置都能跟着图片宽高自动调整,不会出现文字太大溢出或者太小看不清的情况。

我给你整理了一套完整的实现方案,直接就能用:

核心思路

  1. 选择适配性强的字体(可以用系统基础字体,也能嵌入开源字体避免外部依赖)
  2. 根据图片宽高的最小边计算合适的文本字号,保证文本能完整显示
  3. 精准计算文本的居中绘制位置,避免偏移
  4. 用Go的image/draw和golang.org/x/image/font系列包完成文本渲染

完整代码示例

package main

import (
	"fmt"
	"image"
	"image/color"
	"image/draw"
	"image/png"
	"os"

	"golang.org/x/image/font"
	"golang.org/x/image/font/basicfont"
	"golang.org/x/image/math/fixed"
)

func main() {
	width := 350
	height := 150

	// 创建灰色背景图:修正Alpha通道为255(完全不透明)
	img := image.NewRGBA(image.Rect(0, 0, width, height))
	bgColor := color.RGBA{204, 204, 204, 255}
	draw.Draw(img, img.Bounds(), &image.Uniform{bgColor}, image.Point{}, draw.Src)

	// 生成要绘制的尺寸文本
	text := fmt.Sprintf("%d×%d", width, height)

	// 动态计算字号:取图片最小边的1/8作为基准,可按需调整比例
	fontSizeRatio := 8.0
	fontSize := float64(min(width, height)) / fontSizeRatio
	face := basicfont.Face7x13 // 先使用基础字体,后续可替换为自定义字体

	// 计算文本实际占用的尺寸
	d := &font.Drawer{
		Dst:  img,
		Src:  &image.Uniform{color.RGBA{0, 0, 0, 255}}, // 黑色文本
		Face: face,
	}
	d.Dot = fixed.P(0, 0)
	textBounds, _ := d.BoundString(text)
	textWidth := int(textBounds.Max.X - textBounds.Min.X)
	textHeight := int(textBounds.Max.Y - textBounds.Min.Y)

	// 计算居中绘制坐标:X轴水平居中,Y轴基于字体基线调整实现垂直居中
	x := (width - textWidth) / 2
	y := (height + textHeight) / 2

	// 设置绘制位置并渲染文本
	d.Dot = fixed.P(x, y)
	d.DrawString(text)

	// 保存图片到本地
	f, err := os.Create("placeholder.png")
	if err != nil {
		panic(err)
	}
	defer f.Close()
	png.Encode(f, img)
}

// 辅助函数:取两个整数的最小值
func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

关键细节说明

  • Alpha通道修正:你之前代码里的color.RGBA{204,204,204,1}几乎是透明状态,改成255才能显示正常的灰色背景
  • 动态字号逻辑:用图片最小边的比例计算字号,不管是宽幅图还是竖幅图,文本都能适配不溢出
  • 垂直居中技巧:字体的绘制基线在Y轴位置,所以Y坐标不能直接用height/2,而是(height + textHeight)/2,这样文本才能真正垂直居中
  • 自定义字体替换:如果觉得基础字体不够美观,可以换成TTF字体,示例代码如下:
    // 加载自定义TTF字体示例(需要引入opentype包)
    import "golang.org/x/image/font/opentype"
    
    fontBytes, err := os.ReadFile("Roboto-Regular.ttf")
    if err != nil {
        panic(err)
    }
    f, err := opentype.Parse(fontBytes)
    if err != nil {
        panic(err)
    }
    face, err := opentype.NewFace(f, &opentype.FaceOptions{
        Size:    fontSize,
        DPI:     72,
        Hinting: font.HintingFull,
    })
    if err != nil {
        panic(err)
    }
    defer face.Close()
    

这样生成的图片就和placeholder.com的效果完全一致了,文本会自动适配图片尺寸,精准居中显示~

内容的提问来源于stack exchange,提问作者Jared Chu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:55:00