golang实现给图片加水印

 更新时间:2023年12月31日 09:15:02   作者:lmy_loveF  
这篇文章主要为大家详细介绍了Vue3如何利用golang实现给图片加水印,文中的示例代码讲解详细,具有一定的借鉴价值,需要的可以参考一下

预览效果

需求:

1,员工签到图片加水印

2,水印文字需要有半透明的底色,避免水印看不清

3,图片宽设置在600,小于600或者大于600都需要等比例修改图片的高度,保持水印在图片中的大小和位置

4,处理后图片和原图大小不要相差太多

调用:

	
    fileName := "display_20231229134926805_9512.jpg"
	waterMark := WaterMarkInfo{
		UserInfo: "1123456789-仲夏夜的梦  2023-12-28 17:23:54",
		SignAddress: "[119.092868,34.887314] 中国广东省深圳市龙岗区坂田街道华为基地广东省深圳市南山区广东省深圳市南山区广东省深圳市南山区广东省深圳市南山区广东省深圳市南山区",
	}
	addSigninWaterMark(fileName, waterMark)

图片加水印方法:

// WaterMarkInfo 水印信息
type WaterMarkInfo struct {
	UserInfo string //用户信息
	SignAddress string //签到地址
}
 
// 增加打卡水印
func addSigninWaterMark(fileName string, waterMarkInfo WaterMarkInfo) error {
	//接口异常捕获
	defer func() {
		if err := recover(); err != nil {
			sbjlog.ExcLog("100", "addSigninWaterMark-图片增加水印异常:err=%v", err)
		}
	}()
	//需要加水印的图片
	imgfile, err := os.Open(tempImgDir + fileName)
	if err != nil {
		sbjlog.Debug("addSigninWaterMark os.Open ERROR:%v \r\n", err)
		return err
	}
	defer imgfile.Close()
	jpgimg, err := jpeg.Decode(imgfile)
	if err != nil {
		sbjlog.Debug("addSigninWaterMark jpeg.Decode ERROR:%v \r\n", err)
		return err
	}
	//对图片进行大小变更,图片的宽必须是600,水印文字长度是按照600来设置的
	imgWidth := uint(600)
	imgHeight := uint(800)
	if uint(jpgimg.Bounds().Dx()) != imgWidth {
		imgHeight = uint(imgWidth) * uint(jpgimg.Bounds().Dy()) / uint(jpgimg.Bounds().Dx())
		jpgimg = resize.Resize(600, imgHeight, jpgimg, resize.Bilinear)
	}
	//新建空白图层
	img := image.NewRGBA64(jpgimg.Bounds())
	pic2FramePadding := 20
	waterMarkHeight := 80
	waterMarkWidth := 600
 
	//新建空白白色图层
	transparentImg := image.NewRGBA64(image.Rect(0, 0, waterMarkWidth-pic2FramePadding/2, waterMarkHeight))
	//设置空白白色图层的大小
	draw.Draw(transparentImg,
		image.Rect(pic2FramePadding/2, pic2FramePadding/2, transparentImg.Bounds().Dx(), transparentImg.Bounds().Dy()),
		image.White,
		image.Point{},
		draw.Over)
	//把原来的图片画到空白图层上
	draw.Draw(img, jpgimg.Bounds(), jpgimg, jpgimg.Bounds().Min, draw.Over)
 
	//设置白色图层透明度,color.Alpha值在0-255之间,越靠近0越来透明
	mask := image.NewUniform(color.Alpha{180})
	//把空白图层画到空白图层上
	draw.DrawMask(img, img.Bounds().Add(image.Pt(0, jpgimg.Bounds().Dy()-waterMarkHeight-pic2FramePadding/2)), transparentImg, image.ZP, mask, image.Point{}, draw.Over)
	//给空白图层加水印
	err = addWaterMarkToImage(img, waterMarkInfo)
	if err != nil {
		return err
	}
 
	//保存到新文件中
	newfile, err := os.Create(tempImgDir + fileName)
	//在尽量不损失图片质量的情况下,保证绘制后图片和原图片一样大:jpeg.Options{94}
	err = jpeg.Encode(newfile, img, &jpeg.Options{94})
	if err != nil {
		fmt.Println(err)
	}
 
	return nil
}

图片加文字:

func addWaterMarkToImage(newTemplateImage *image.RGBA64, waterMarkInfo WaterMarkInfo) error {
	// 在写入之前有一些准备工作
	content := freetype.NewContext()
	fontTtf, err := loadFont("runtime/fonts/simsun.ttc")
	if err != nil {
		sbjlog.Debug("addWaterMarkToImage loadFont ERROR:%v \r\n", err)
		return err
	}
 
	content.SetClip(newTemplateImage.Bounds())
	content.SetDst(newTemplateImage)
	content.SetSrc(image.Black) // 设置字体颜色
	content.SetDPI(72)          // 设置字体分辨率
 
	content.SetFontSize(14)  // 设置字体大小
	content.SetFont(fontTtf) // 设置字体样式,就是我们上面加载的字体
 
	// 	正式写入文字
	// 参数1:要写入的文字
	// 参数2:文字坐标
	//dx := newTemplateImage.Bounds().Dx()
	dy := newTemplateImage.Bounds().Dy()
	topSignAddress := waterMarkInfo.SignAddress
	endSignAddress := ""
	if len(waterMarkInfo.SignAddress) > 100 {
		topSignAddress = xstring.SubString(waterMarkInfo.SignAddress, 100)
		endSignAddress = waterMarkInfo.SignAddress[len(topSignAddress):]
	}
	pic2FramePadding := 20
	markHeiht := dy - pic2FramePadding*3
	content.DrawString(waterMarkInfo.UserInfo, freetype.Pt(pic2FramePadding, markHeiht))
	markHeiht = markHeiht + 20
	content.DrawString(topSignAddress, freetype.Pt(pic2FramePadding, markHeiht))
	markHeiht = markHeiht + 20
	content.DrawString(endSignAddress, freetype.Pt(pic2FramePadding, markHeiht))
	return nil
}

加载字体:

// 根据路径加载字体文件
// path 字体的路径
func loadFont(path string) (font *truetype.Font, err error) {
	var fontBytes []byte
	fontBytes, err = ioutil.ReadFile(path) // 读取字体文件
	if err != nil {
		err = fmt.Errorf("加载字体文件出错:%s", err.Error())
		return
	}
	font, err = freetype.ParseFont(fontBytes) // 解析字体文件
	if err != nil {
		err = fmt.Errorf("解析字体文件出错,%s", err.Error())
		return
	}
	return
}

到此这篇关于golang实现给图片加水印的文章就介绍到这了,更多相关golang图片加水印内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vscode上搭建go开发环境详细完整过程

    vscode上搭建go开发环境详细完整过程

    这篇文章主要给大家介绍了关于vscode上搭建go开发环境的详细完整过程,Go语言或将成为新的主力开发语言,Go是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言,所以我们有必要学习并掌握它,需要的朋友可以参考下
    2023-10-10
  • golang RPC包原理和使用详细介绍

    golang RPC包原理和使用详细介绍

    golang的rpc支持三个级别的RPC:TCP、HTTP、JSONRPC。但Go的RPC包是独一无二的RPC,它和传统的RPC系统不同,它只支持Go开发的服务器与客户端之间的交互,因为在内部,它们采用了Gob来编码
    2022-09-09
  • 简化Go开发提高生产力的强大工具及使用详解

    简化Go开发提高生产力的强大工具及使用详解

    作为 Go 开发人员,应该都知道维持简洁高效开发工作流程的重要性,为了提高工作效率和代码质量,简化开发流程并自动执行重复性任务至关重要,在本文中,我们将探讨一些强大的工具和技术,它们将简化 Go 开发过程,助力您的编码之旅
    2023-10-10
  • Goland IDEA项目多开设置方式

    Goland IDEA项目多开设置方式

    这篇文章主要介绍了Goland IDEA项目多开设置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • 解析Golang中引用类型是否进行引用传递

    解析Golang中引用类型是否进行引用传递

    这篇文章主要为大家介绍了Golang中引用类型是否进行引用传递剖析详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • Golang实现Md5校验的代码示例

    Golang实现Md5校验的代码示例

    最近项目中有个需求,就是地图文件下发后,接收方需要文件的md5值,和接收到的文件做比对,以免文件不完整,引起bug,于是测试了下本地文件和远程文件的md5计算,所以本文给大家介绍了Golang实现Md5校验,需要的朋友可以参考下
    2024-07-07
  • Go标准库http server优雅启动深入理解

    Go标准库http server优雅启动深入理解

    这篇文章主要介绍了Go标准库http server优雅启动深入理解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2024-01-01
  • 使用Go添加HTTPS的实现代码示例

    使用Go添加HTTPS的实现代码示例

    这篇文章主要介绍了使用Go添加HTTPS的实现代码示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-10-10
  • Go实现map并发安全的3种方式总结

    Go实现map并发安全的3种方式总结

    Go的原生map不是并发安全的,在多协程读写同一个map的时候,安全性无法得到保障,这篇文章主要给大家总结介绍了关于Go实现map并发安全的3种方式,需要的朋友可以参考下
    2023-10-10
  • go语言实现二叉树的序例化与反序列化

    go语言实现二叉树的序例化与反序列化

    这篇文章主要介绍了go语言实现二叉树的序例化与反序列化,文章围绕主题展开详细内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-05-05

最新评论