当前位置:网站首页>Golang多图生成gif
Golang多图生成gif
2022-07-01 02:57:00 【Asimov__】
package image
import (
"fmt"
"github.com/golang/freetype"
"golang.org/x/image/font"
"image"
"image/color"
"image/color/palette"
"image/draw"
"image/gif"
"image/png"
"io/ioutil"
"log"
"os"
"sync"
"testing"
"time"
)
func isInPalette(p color.Palette, c color.Color) int {
ret := -1
for i, v := range p {
if v == c {
return i
}
}
return ret
}
// 获取每张图片的调色板
func getPalette(m image.Image) color.Palette {
p := color.Palette{color.RGBA{0x00, 0x00, 0x00, 0x00}}
p9 := color.Palette(palette.Plan9)
b := m.Bounds()
black := false
for y := b.Min.Y; y < b.Max.Y; y++ {
for x := b.Min.X; x < b.Max.X; x++ {
// At返回像素At (x, y)的颜色。
c := m.At(x, y)
// Convert返回欧氏R,G,B空间中最接近c的调色板颜色。
cc := p9.Convert(c)
if cc == p9[0] {
black = true
}
if isInPalette(p, cc) == -1 {
p = append(p, cc)
}
}
}
if len(p) < 256 && black == true {
p[0] = color.RGBA{0x00, 0x00, 0x00, 0x00} // transparent
p = append(p, p9[0])
}
return p
}
// pool
type WaitGroup struct {
workChan chan int
wg sync.WaitGroup
}
func NewPool(coreNum int) *WaitGroup {
ch := make(chan int, coreNum)
return &WaitGroup{
workChan: ch,
wg: sync.WaitGroup{},
}
}
func (ap *WaitGroup) Add(num int) {
for i := 0; i < num; i++ {
ap.workChan <- i
ap.wg.Add(1)
}
}
func (ap *WaitGroup) Done() {
LOOP:
for {
select {
case <-ap.workChan:
break LOOP
}
}
ap.wg.Done()
}
func (ap *WaitGroup) Wait() {
ap.wg.Wait()
}
// 写入
func writeLabel(img image.Image, label string, x, y int, fontColor color.Color, size float64, fontPath string) (image.Image, error) {
bound := img.Bounds()
// 创建一个新的图片
rgba := image.NewRGBA(image.Rect(0, 0, bound.Dx(), bound.Dy()))
// 读取字体
fontBytes, err := ioutil.ReadFile(fontPath)
if err != nil {
return rgba, err
}
myFont, err := freetype.ParseFont(fontBytes)
if err != nil {
return rgba, err
}
draw.Draw(rgba, rgba.Bounds(), img, bound.Min, draw.Src)
c := freetype.NewContext()
c.SetDPI(72)
c.SetFont(myFont)
c.SetFontSize(size)
c.SetClip(rgba.Bounds())
c.SetDst(rgba)
uni := image.NewUniform(fontColor)
c.SetSrc(uni)
c.SetHinting(font.HintingNone)
// 在指定的位置显示
pt := freetype.Pt(x, y+int(c.PointToFixed(size)>>6))
if _, err := c.DrawString(label, pt); err != nil {
return rgba, err
}
return rgba, nil
}
func TestGif(t *testing.T) {
var disposals []byte
var images []*image.Paletted
var delays []int
work := NewPool(100)
for i := 1; i < 501; i++ {
work.Add(1)
go func(i interface{}, wg *WaitGroup) {
defer wg.Done()
var src string
src = fmt.Sprintf("./PNGS/图层 %d.png", i)
file, err := os.Open(src)
if err != nil {
fmt.Println(err)
}
defer func() { _ = file.Close() }()
g, err := png.Decode(file)
// 写入文字
writeimage, err := writeLabel(g, "NO.9988", 56, 56, color.RGBA{234, 178, 16, 255}, 60, "./PingFang Heavy.ttf")
if err != nil {
fmt.Println(err)
}
cp := getPalette(writeimage)
// cp := append(palette.WebSafe, color.Transparent)
// 透明图片需要设置
disposals = append(disposals, gif.DisposalBackground)
// 返回一个给定宽度,高度和面板。
p := image.NewPaletted(image.Rect(0, 0, 1200, 1200), cp)
draw.Draw(p, p.Bounds(), writeimage, image.ZP, draw.Src)
images = append(images, p)
delays = append(delays, 4)
//time.Sleep(time.Second * 1)
}(i, work)
}
log.Println("waiting...")
work.Wait()
log.Println("done")
g := &gif.GIF{
Image: images,
Delay: delays,
//LoopCount为0表示永远循环
LoopCount: 0,
//处理是连续的处理方法,每帧一个
Disposal: disposals,
}
f, err := os.Create("test1.gif")
if err != nil {
fmt.Println(err)
}
defer func() { _ = f.Close() }()
gif.EncodeAll(f, g)
}
边栏推荐
- 安装VCenter6.7【VCSA6.7(vCenter Server Appliance 6.7) 】
- 【小程序项目开发-- 京东商城】uni-app之分类导航区域
- Druid monitoring statistics source
- Mnasnet learning notes
- If a parent class defines a parameterless constructor, is it necessary to call super ()?
- In the industrial Internet, "small" programs have "big" effects
- 性能测试常见面试题
- Sampling Area Lights
- MySQL knowledge points
- Contrastive learning of Class-agnostic Activation Map for Weakly Supervised Object Localization and
猜你喜欢

Huawei operator level router configuration example | BGP VPLS and LDP VPLS interworking example

Redis 教程

Sampling Area Lights

【机器学习】向量化计算 -- 机器学习路上必经路
![[small program project development -- Jingdong Mall] the home page commodity floor of uni app](/img/80/20bed20a6ab91e82ad6800b11f2caa.png)
[small program project development -- Jingdong Mall] the home page commodity floor of uni app

Mysql知识点

# 使用 KubeKey 搭建 Kubernetes/KubeSphere 环境的'心路(累)历程'

So easy deploy program to server

【小程序项目开发 -- 京东商城】uni-app 商品分类页面(上)

Lenovo x86 server restart management controller (xclarity controller) or TSM method
随机推荐
安装VCenter6.7【VCSA6.7(vCenter Server Appliance 6.7) 】
[small program project development -- Jingdong Mall] the home page commodity floor of uni app
Multithreaded printing
A shooting training method based on the digital measurement of Joule energy and posture of sphygmomanometer air bag with standard air pressure
Mouse over effect I
servlet【初识】
STM32——一线协议之DS18B20温度采样
js 找出两个数组中的重复元素
Dart training and sphygmomanometer inflation pump power control DPC
Gartner research: in China, the adoption of hybrid cloud has become the mainstream trend
[linear DP] longest common subsequence
Od modify DLL and exe pop-up contents [OllyDbg]
In the industrial Internet, "small" programs have "big" effects
How to determine the progress bar loaded in the loading interface when opening the game
Mouse over effect 9
调试定位导航遇到的问题总结
最新接口自动化面试题
单片机 MCU 固件打包脚本软件
Redis 教程
Densenet network paper learning notes