Loading...

简单刨析,教大家自制假期倒计时图片

技术分享3个月前发布 Jone
118 0 0

昨天有个小伙子对假期倒计时那个图片比较感兴趣,想要知道怎么做的。

简单刨析,教大家自制假期倒计时图片

今天给大家介绍下原理,主要有两个方面——图片上写字假期倒计时获取。往图片模板上写字用的是image/draw这个类,获取假期倒计时用的是github.com/6tail/lunar-go/calendar这个类。

假期倒计时

这个制作的话需要自己找个图片模板,不能直接用我这个。我图片模板下面那个二维码是写死的,不是可以指定二维码生成的。

简单刨析,教大家自制假期倒计时图片

这个就是没添加文字之前的模板,接下来就是获取假期倒计时了,计算接下来距离最近的四天假期。

获取绘制数据

首先咱们先手动枚举比较重要的几个假期,包括阴历假期和阳历假期。

var (
    holidays []Holiday
)

func init() {
    holidays = append(holidays, Holiday{Name: "元旦", Month: 1, Day: 1, Lunar: false})
    holidays = append(holidays, Holiday{Name: "春节", Month: 1, Day: 1, Lunar: true})
    holidays = append(holidays, Holiday{Name: "清明节", Month: 4, Day: 4, Lunar: false})
    holidays = append(holidays, Holiday{Name: "劳动节", Month: 5, Day: 1, Lunar: false})
    holidays = append(holidays, Holiday{Name: "端午节", Month: 5, Day: 5, Lunar: true})
    holidays = append(holidays, Holiday{Name: "中秋节", Month: 8, Day: 15, Lunar: true})
    holidays = append(holidays, Holiday{Name: "国庆节", Month: 10, Day: 1, Lunar: false})
}

接下来就简单了,循环来距离当天最近的四个假期时间即可。

/ NextFourHolidays 计算下四个假期时间
func (*CalendarService) NextFourHolidays() (holidayResList []HolidayRes) {
    year := time.Now().Year()
    month := time.Now().Month()
    day := time.Now().Day()
    for _, holiday := range holidays {
        var holidaySolar *calendar.Solar
        if holiday.Lunar {
            holidaySolar = calendar.NewLunarFromYmd(year, holiday.Month, holiday.Day).GetSolar()
        } else {
            holidaySolar = calendar.NewSolarFromYmd(year, holiday.Month, holiday.Day)
        }
        nowSolar := calendar.NewSolarFromYmd(year, int(month), day)
        if holidaySolar.IsAfter(nowSolar) {
            holidayResList = append(holidayResList, HolidayRes{Name: holiday.Name, Day: holidaySolar.Subtract(nowSolar)})
        }
    }
    if len(holidayResList) < 4 {
        for _, holiday := range holidays {
            var holidaySolar *calendar.Solar
            if holiday.Lunar {
                holidaySolar = calendar.NewLunarFromYmd(year+1, holiday.Month, holiday.Day).GetSolar()
            } else {
                holidaySolar = calendar.NewSolarFromYmd(year+1, holiday.Month, holiday.Day)
            }
            nowSolar := calendar.NewSolarFromYmd(year, int(month), day)
            if holidaySolar.IsAfter(nowSolar) {
                holidayResList = append(holidayResList, HolidayRes{Name: holiday.Name, Day: holidaySolar.Subtract(nowSolar)})
            }
            if len(holidayResList) >= 4 {
                return
            }
        }
    }
    return
}

上述逻辑还是挺简单的,因为我们总共需要获取四个假期,如果今年剩余假期不到四个的话,就需要计算下一年的假期,反正最后总共有四个就行了。

这样我们右边的假期倒计时数据就取出来了,接下来就是左边的数据了。左边数据根据你自己喜好随便弄点啥都可以,正巧github.com/6tail/lunar-go/calendar这个类可以计算每日宜忌,顺便我就加上了。

    data += "宜:"
    for i := dayYi.Front(); i != nil; i = i.Next() {
        if i.Next() == nil {
            data += strings.TrimSpace(i.Value.(string))
        } else {
            data += strings.TrimSpace(i.Value.(string)) + " "
        }
    }
    data = "忌:"
    dayJi := calendar.NewLunarFromDate(time.Now()).GetDayJiBySect(2)
    for i := dayJi.Front(); i != nil; i = i.Next() {
        if i.Next() == nil {
            data += strings.TrimSpace(i.Value.(string))
        } else {
            data += strings.TrimSpace(i.Value.(string)) + " "
        }
    }

通过calendar.NewLunarFromDate这个函数即可计算每日宜忌。

对了,左边最下面还有个每日一言,这个我是通过https://v1.hitokoto.cn/这个接口获取到的。

其他数据都是程序自己计算出来的,唯有这个一言是调用的别人API,很没有安全感啊,不知道啥时候就不能用了。

这样模板两个框里面的数据我们都去到了,接下来就是把数据绘制到图片模板上。

绘制图片

绘制这部分就比较恶心了,github.com/golang/freetype提供了DrawString方法,不过这个方法需要自己找到绘画的像素点。这个我在用的时候没找到啥好方式,一点点手动试找到合适绘画点的(/= _ =)/~┴┴

content := freetype.NewContext()
content.SetClip(img.Bounds())
content.SetDst(img)
content.SetSrc(image.Black) // 设置字体颜色
content.SetDPI(300)         // 设置字体分辨率
content.SetFontSize(10)     // 设置字体大小
fontKai, err := loadFont("./img/HarmonyOS_Sans_SC_Regular.ttf")
content.SetFont(fontKai)
content.DrawString(weekend, freetype.Pt(1320, 230))

上面这几个就是绘制文字主要的几个方法了,绘制之前需要加载字体库,这里我用的鸿蒙字体。

等全部字体都绘制到上面后,把图片保存到本地即可。

func saveFile(pic *image.RGBA) {
    dstFile, err := os.Create("./img/" + strconv.Itoa(time.Now().Year()) + strconv.Itoa(int(time.Now().Month())) + strconv.Itoa(time.Now().Day()) + ".png")
    if err != nil {
        global.GVA_LOG.Error("保存图片失败", zap.Error(err))
    }
    defer dstFile.Close()
    png.Encode(dstFile, pic)
}

进阶方式

上面就是我的实现方式了,整体比较繁琐且普遍率不是很高,需要自己懂些代码然后自己修改。

前段时间看到可以通过htmlpng形式来实现,一直想重新试试,可惜还没有机会。

感兴趣的小伙伴们可以试试这种方式,等html模板完成的话普遍率肯定比我这种方式高,到时候让我copy一下(๑•́ ₃ •̀๑)

简单刨析,教大家自制假期倒计时图片

没想到这个图片也是自动生成的吧(ਛ_≻ਛ),这个就简单了,可以自己随便diy替换。想要的话我可以发出来,得等下周了,在另一个电脑上。

闲聊

昨天iPhone 16不支持微信都能上热搜,明眼看都知道是不可能的。

微信那么多用户,苹果不可能放弃的,就是最后哪方放点利益的问题。

© 版权声明

相关文章

暂无评论

暂无评论...