GO使用image/draw库给图片添加水印完全解析 您所在的位置:网站首页 images/pt.png GO使用image/draw库给图片添加水印完全解析

GO使用image/draw库给图片添加水印完全解析

2023-12-21 22:12| 来源: 网络整理| 查看: 265

目录 一、前言二、`image/draw`三、`image/jpeg`和`image/png`四、思路分析五、代码实装1.读取图片2.根据图片类型使用不同类3.添加图片水印4.添加文字水印5. 水印效果6. 完整代码 六、总结1. 需要熟悉的库2.处理思路 七、评论区作业

一、前言

图片水印是很实用的功能,可以标注图片的来源,防止第三方盗图。

GO实现图片水印功能主要使用绘图库image/draw。

二、image/draw

主要的方法有

func Draw(dst Image, r image.Rectangle, src image.Image, sp image.Point, op Op) func DrawMask(dst Image, r image.Rectangle, src image.Image, sp image.Point, mask image.Image, mp image.Point, op Op) 三、image/jpeg和image/png

image/jpeg和image/png的作用是图片的读取和写入。

读取图片

func Decode(r io.Reader) (image.Image, error)

写入图片

func Encode(w io.Writer, m image.Image, o *Options) error

两个库的方法名都是一致的。

四、思路分析

和之前PHP写的水印思路没什么区别

读取原始图片读取水印图片或者获取水印文字创建新图片,写入原始图片和水印图片或者文字保存图片到文件 五、代码实装 1.读取图片

比如我的原始图片是这个猫猫图

请添加图片描述 那么作为输入,我应该获取图片,并且判断图片的文件类型,由于我会事先声明只支持jpg和png的图,那么在判断图片不属于jpg或png之后应该返回错误信息。

package main import ( "os" imgtype "codechina.csdn.net/diandianxiyu/goimgtype" ) func main() { var imgdiandianxiyu_geek string = `./bg.jpg` imgb, err := os.Open(imgdiandianxiyu_geek) if err != nil { panic(err) } defer imgb.Close() datatype, err2 := imgtype.Get(imgdiandianxiyu_geek) var imgtype string = "" if err2 != nil { imgtype = "" } else { // 根据文件类型执行响应的操作 switch datatype { case `image/jpeg`: imgtype = "jpeg" case `image/png`: imgtype = "png" } } if imgtype == "" { panic("暂不支持文件类型") } print(imgtype) } jpeg

由于go不支持原生的获取图片类型方式,所以这个引入了第三方库。

2.根据图片类型使用不同类

如果是jpeg的图片,就在对象初始化的时候用image/jpeg。 如果是png的图片,就在对象初始化的时候用image/png

var imgbinfo image.Image if imgtype == "jpeg" { imgbinfo, _ = jpeg.Decode(imgb) } else { imgbinfo, _ = png.Decode(imgb) } 3.添加图片水印

因为图片水印的图片是已知的,所以我们不需要判断图片类型了

//读取水印图片 watermark, err := os.Open("watermark.png") if err != nil { panic(err) } defer watermark.Close() imgwatermark, err := png.Decode(watermark) if err != nil { panic(err) } offset := image.Pt(imgbinfo.Bounds().Dx()-imgwatermark.Bounds().Dx()-19, imgbinfo.Bounds().Dy()-imgwatermark.Bounds().Dy()-19) b := imgbinfo.Bounds() m := image.NewNRGBA(b) //按原图生成新图

这里要注意的是,imgbinfo.Bounds().Dx()指的是原图的宽度,imgbinfo.Bounds().Dy()指的是原图的高度。

代码的意思是水印图放在右下角19像素的位置上,实际应用中可以根据需求调整。

4.添加文字水印

文字水印必须引入字体文件,如果水印中有中文的话,引入的字体文件必需支持中文。

//文字水印 fontBytes, err := ioutil.ReadFile("Arial Unicode.ttf") //读取字体文件 if err != nil { log.Println(err) } font, err := freetype.ParseFont(fontBytes) if err != nil { log.Println(err) } f := freetype.NewContext() f.SetDPI(72) //设置DPI f.SetFont(font) //设置字体 f.SetFontSize(24) //设置字号 f.SetClip(imgbinfo.Bounds()) f.SetDst(m) f.SetSrc(image.NewUniform(color.RGBA{R: 255, G: 0, B: 0, A: 255})) //设置颜色 pt := freetype.Pt(10, 50) _, err = f.DrawString("blog.csdn.net/diandianxiyu_geek 邻座的小雨同学", pt)

pt指的是坐标,我设置的是横坐标10和纵坐标的位置。

5. 水印效果

请添加图片描述 备注:右下角的白色的文字是CSDN的水印,不是代码里的。

6. 完整代码 package main import ( "image" "image/color" "image/draw" "image/jpeg" "image/png" "io/ioutil" "log" "os" "codechina.csdn.net/diandianxiyu/freetype" imgtype "codechina.csdn.net/diandianxiyu/goimgtype" ) func main() { var imgdiandianxiyu_geek string = `./bg.jpg` imgb, err := os.Open(imgdiandianxiyu_geek) if err != nil { panic(err) } defer imgb.Close() datatype, err2 := imgtype.Get(imgdiandianxiyu_geek) var imgtype string = "" if err2 != nil { imgtype = "" } else { // 根据文件类型执行响应的操作 switch datatype { case `image/jpeg`: imgtype = "jpeg" case `image/png`: imgtype = "png" } } if imgtype == "" { panic("暂不支持文件类型") } var imgbinfo image.Image if imgtype == "jpeg" { imgbinfo, _ = jpeg.Decode(imgb) } else { imgbinfo, _ = png.Decode(imgb) } //读取水印图片 watermark, err := os.Open("watermark.png") if err != nil { panic(err) } defer watermark.Close() imgwatermark, err := png.Decode(watermark) if err != nil { panic(err) } offset := image.Pt(imgbinfo.Bounds().Dx()-imgwatermark.Bounds().Dx()-19, imgbinfo.Bounds().Dy()-imgwatermark.Bounds().Dy()-19) b := imgbinfo.Bounds() m := image.NewNRGBA(b) //按原图生成新图 //文字水印 fontBytes, err := ioutil.ReadFile("Arial Unicode.ttf") //读取字体文件 if err != nil { log.Println(err) } font, err := freetype.ParseFont(fontBytes) if err != nil { log.Println(err) } f := freetype.NewContext() f.SetDPI(72) //设置DPI f.SetFont(font) //设置字体 f.SetFontSize(24) //设置字号 f.SetClip(imgbinfo.Bounds()) f.SetDst(m) f.SetSrc(image.NewUniform(color.RGBA{R: 255, G: 0, B: 0, A: 255})) //设置颜色 //新图写入原图和背景图 draw.Draw(m, b, imgbinfo, image.ZP, draw.Src) draw.Draw(m, imgwatermark.Bounds().Add(offset), imgwatermark, image.ZP, draw.Over) pt := freetype.Pt(10, 50) _, err = f.DrawString("blog.csdn.net/diandianxiyu_geek 邻座的小雨同学", pt) //输出图像 imgw, _ := os.Create("new.jpg") jpeg.Encode(imgw, m, &jpeg.Options{100}) }

本地引入库

go get codechina.csdn.net/diandianxiyu/freetype go get codechina.csdn.net/diandianxiyu/goimgtype 六、总结 1. 需要熟悉的库 image/drawimage/jpeg和image/png 2.处理思路 找到合适的库通过文档确认合适的方法完善代码健壮性 七、评论区作业

这个水印工具还有哪些可以优化的点?

欢迎给出你的思路!



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有