yuwingo
2/12/2019 - 7:24 AM

使用go合成图片,文字

使用go合成图片,文字

//https://studygolang.com/articles/4403
//https://blog.golang.org/go-imagedraw-package
package main

import (
	"os"
	"image/png"
	"image"
	"image/color"
	"log"
	"io/ioutil"
	"github.com/golang/freetype"
	"fmt"
	"image/draw"
)

func main() {
	createCImage()
}

func createImage() {
	imgfile, err := os.Open("test_2.png")
	if err != nil {
		fmt.Printf("err %v", err)
	}
	defer imgfile.Close()

	img, _, err := image.Decode(imgfile)
	if err != nil {
		fmt.Printf("err %v", err)
	}
	//fmt.Printf("image:%v, name:%v", img, name)
	imgRgba := image.NewNRGBA(img.Bounds())

	draw.Draw(imgRgba, imgRgba.Bounds(), img, image.ZP, draw.Src)

	////设置每个点的 RGBA (Red,Green,Blue,Alpha(设置透明度))
	//for y := 0; y < dy; y++ {
	//	for x := 0; x < dx; x++ {
	//		//设置一块 白色(255,255,255)不透明的背景
	//		img.Set(x, y, color.RGBA{255, 255, 255, 255})
	//	}
	//}
	//读取字体数据
	fontBytes, err := ioutil.ReadFile("test_font.ttf")
	if err != nil {
		log.Println(err)
	}
	//载入字体数据
	font, err := freetype.ParseFont(fontBytes)
	if err != nil {
		log.Println("load front fail", err)
	}
	f := freetype.NewContext()
	//设置分辨率
	f.SetDPI(72)
	//设置字体
	f.SetFont(font)
	//设置尺寸
	f.SetFontSize(100)
	f.SetClip(imgRgba.Bounds())
	//设置输出的图片
	f.SetDst(imgRgba)
	//设置字体颜色(红色)
	f.SetSrc(image.NewUniform(color.RGBA{255, 0, 0, 255}))

	//设置字体的位置
	pt := freetype.Pt(10, 40+int(f.PointToFixed(26))>>8)

	_, err = f.DrawString("hello,世界", pt)
	if err != nil {
		log.Fatal(err)
	}

	imgW, _ := os.Create("test_output.png")

	//以png 格式写入文件
	err = png.Encode(imgW, imgRgba)
	if err != nil {
		log.Fatal(err)
	}
}

func createCImage() {
	imgfile, err := os.Open("test_2.png")
	if err != nil {
		fmt.Printf("err %v", err)
	}
	defer imgfile.Close()

	img, _, err := image.Decode(imgfile)
	if err != nil {
		fmt.Printf("err %v", err)
	}
	//fmt.Printf("image:%v, name:%v", img, name)
	imgRgba := image.NewNRGBA(img.Bounds())


	imgFileHead, _ := os.Open("test_1.png")
	defer imgFileHead.Close()

	imgHead, _, err := image.Decode(imgFileHead)
	if err != nil {
		fmt.Printf("err %v", err, imgHead)
	}
	//fmt.Printf("image:%v, name:%v", img, name)
	//imgRgbaHead := image.NewNRGBA(imgHead.Bounds())


	draw.Draw(imgRgba, imgRgba.Bounds(), img, image.ZP, draw.Src)

	draw.DrawMask(imgRgba, imgRgba.Bounds(), imgHead, image.ZP, &CircleMask{image.Pt(95, 95), 95}, image.ZP, draw.Over)

	imgW, _ := os.Create("test_output.png")

	//以png 格式写入文件
	err = png.Encode(imgW, imgRgba)
	if err != nil {
		log.Fatal(err)
	}
}

type CircleMask struct {
	P image.Point
	R int
}

func (c *CircleMask) ColorModel() color.Model {
	return color.AlphaModel
}

func (c *CircleMask) Bounds() image.Rectangle {
	return image.Rect(c.P.X-c.R, c.P.Y-c.R, c.P.X+c.R, c.P.Y+c.R)
}

func (c *CircleMask) At(x, y int) color.Color {
	xx, yy, rr := float64(x-c.P.X)+0.5, float64(y-c.P.Y)+0.5, float64(c.R)
	if xx*xx+yy*yy < rr*rr {
		return color.Alpha{255}
	}
	return color.Alpha{0}
}