首页 > 其他分享 >Golang实现图片与视频的缩略图生成

Golang实现图片与视频的缩略图生成

时间:2023-07-01 21:02:04浏览次数:41  
标签:视频 img err sz image 缩略图 Golang thumbnail

图片与视频的缩略图是一个十分常见的需求,比如即时消息。这里摘取了Golang项目中的相关代码,分享图片与视频相关处理的开发经验。


图片缩略图

缩略图的尺寸分为两种规则:

1)边长模式,生成正方形缩略图;

2)宽高模式,又分三种:指定宽高、指定宽(高等比缩放)、指定高(宽等比缩放)。

如果原图为png或gif,缩略图则采用png格式;否则,都采用jpeg格式。

func createPhotoThumbnail(src string, thumbnail string, side int, width int, height int) (err error) {
	// open image
	srcFile, err := os.Open(src)
	if err != nil {
		return fmt.Errorf("opening image failed")
	}
	defer srcFile.Close()
	img, format, err := image.Decode(srcFile)
	if err != nil {
		return fmt.Errorf("decode image failed %v", err)
	}

	// process image
	var thumbnailImg image.Image
	if side > 0 {	// 指定边长
		var canvas image.Image
        s := side
		sz := img.Bounds().Size()
        // 等比缩小
		if sz.X > sz.Y {
			canvas = resize.Thumbnail(uint(sz.X), uint(s), img, resize.Lanczos2)
		} else {
			canvas = resize.Thumbnail(uint(s), uint(sz.Y), img, resize.Lanczos2)
		}
		sz = canvas.Bounds().Size()
		var l, t, r, b int
		if sz.X > s {
			l = (sz.X - s) / 2
			r = l + s
		} else {
			l = 0
			r = sz.X
		}
		if sz.Y > s {
			t = (sz.Y - s) / 2
			b = t + s
		} else {
			t = 0
			b = sz.Y
		}
        // 裁剪
		thumbnailImg = canvas.(*image.YCbCr).SubImage(image.Rect(l, t, r, b)).(*image.YCbCr)
	} else {	// 指定宽和高
        w := width
        h := height
		if w > 0 && h > 0 {
		} else if w > 0 {
			h = img.Bounds().Dy()
		} else {
			w = img.Bounds().Dx()
		}
		thumbnailImg = resize.Thumbnail(uint(w), uint(h), img, resize.Lanczos2)
	}

	// save thumbnail
	err = os.MkdirAll(filepath.Dir(thumbnail), os.ModePerm)
	if err != nil {
		return
	}
	thumbnailFile, err := os.Create(thumbnail)
	if err != nil {
		return
	}
	defer thumbnailFile.Close()
	if format == "png" || format == "gif" {
		err = png.Encode(thumbnailFile, thumbnailImg)
	} else {
		err = jpeg.Encode(thumbnailFile, thumbnailImg, &jpeg.Options{Quality: 80})
	}
	return
}

视频缩略图

生成视频的缩略图,需要先用ffmpeg命令行程序从视频中截取2秒之后的单帧图片,这里以Linux为例。然后,用上面的图片缩略图生成函数再生成指定尺寸的缩略图。

func createVideoThumbnail(src string, thumbnail string, side int, width int, height int) (err error) {
	ctx, cancel := context.WithTimeout(context.Background(), time.Duration(25)*time.Second)
	defer cancel()
	dir := filepath.Dir(thumbnail)
	os.MkdirAll(dir, os.ModePerm)
	tmp := thumbnail + ".tmp"
	c := exec.CommandContext(ctx, "./ffmpeg",
		"-loglevel", "error",
		"-y",
		"-ss", "2",
		"-accurate_seek", "-i", src,
		"-vframes", "1",
		"-f", "image2",
		tmp)
	var stderr bytes.Buffer
	c.Stderr = &stderr
	err = c.Run()
	errStr := ""
	if err != nil {
		errStr = fmt.Sprintf("ffmpeg cmderr(%v) ", err)
	}
	if stderr.Len() != 0 {
		errStr += fmt.Sprintf("ffmpeg stderr(%v) ", stderr.String())
	}
	if ctx.Err() != nil {
		errStr += fmt.Sprintf("ffmpeg ctxerr(%v)", ctx.Err())
	}
	if errStr != "" {
		err = errors.New(errStr)
		return
	}
	err = createPhotoThumbnail(tmp, thumbnail, side, width, height)
	os.Remove(tmp)
	return
}

标签:视频,img,err,sz,image,缩略图,Golang,thumbnail
From: https://blog.51cto.com/u_16166196/6601375

相关文章

  • golang查询数据报错:closing bad idle connection: unexpected read from socket
    原因应用程序在使用驱动的有效空闲连接时候,发现数据库的连接已经失效(因为连接超过wait_timeout时间),用一个失效的连接查数据,所以报错。解决办法将sql驱动SetConnMaxLifetime和SetConnMaxIdleTime设置时间,并且小于数据库的wait_timeout时间(单位秒)。调小wait_timeout。分析......
  • uni.app上传视频vue2 es6
    上传视频可以使用uni.app里面的api letself=this; uni.chooseVideo({ count:1, sourceType:['camera','album'], success:function(res){ console.log(res) self.showVideo=true self.addVideo=false self.src=......
  • 国标GB28181协议客户端开发(三)查询和实时视频画面
    国标GB28181协议客户端开发(三)查询和实时视频画面本文是《国标GB28181协议设备端开发》系列的第三篇,探讨了信息查询和实时视频在GB28181协议中的应用。首先,介绍了设备目录查询、设备信息查询和设备状态查询三个重要的信息查询功能,并详细解释了它们在协议中的信令交互流程。随后,深......
  • 如何使用libavfilter库给输入文件input.yuv添加视频滤镜?
    一.视频滤镜初始化本次代码实现的是给输入视频文件添加水平翻转滤镜,在视频滤镜初始化部分我们可以分为以下几步进行:1.创建滤镜图结构视频滤镜功能最核心的结构为滤镜图结构,即AVFilterGraph结构,我们调用avfilter_graph_alloc()函数就可以创建一个滤镜图结构。......
  • 【视频】R语言LDA线性判别、QDA二次判别分析分类葡萄酒品质数据
    全文链接:https://tecdat.cn/?p=33031原文出处:拓端数据部落公众号分析师:DongleiNiu判别分析(Discriminantanalysis)是一种统计分析方法,旨在通过将一组对象(例如观察数据)分类到已知类别的组中,来发现不同组之间的差异。什么是判别分析判别分析有两种主要形式:线性判别分析(LDA)和......
  • Debug Golang源码中的单元测试
    goland配置如上,既可以debuggolang源码中的单元测试。......
  • EasyCVR播放设备录像出现部分视频不能播放的原因排查与解决
    EasyCVR视频融合平台基于云边端协同架构,具有强大的数据接入、处理及分发能力。平台支持多协议接入,包括:国标GB28181、RTMP、RTSP/Onvif、海康Ehome、海康SDK、大华SDK、宇视SDK等,对外可分发多格式视频流,包括RTSP、RTMP、FLV、HLS、WebRTC等。有用户反馈,通过SDK接入的设备,当天的设......
  • EasyDSS视频直播点播平台视频回看列表显示为ID的排查与优化
    视频直播点播EasyDSS平台具备灵活的视频能力,包括直播、点播、转码、管理、录像、检索、时移回看等,平台支持音视频采集、视频推拉流、播放H.265编码视频、存储、分发等能力服务,可应用在无人机推流、在线直播、虚拟直播、远程培训等场景中。有用户反馈,在EasyDSS视频回看列表中,“名称......
  • EasyCVR播放设备录像出现部分视频不能播放的原因排查与解决
    EasyCVR视频融合平台基于云边端协同架构,具有强大的数据接入、处理及分发能力。平台支持多协议接入,包括:国标GB28181、RTMP、RTSP/Onvif、海康Ehome、海康SDK、大华SDK、宇视SDK等,对外可分发多格式视频流,包括RTSP、RTMP、FLV、HLS、WebRTC等。有用户反馈,通过SDK接入的设备,当天的设备......
  • 看这个视频,4万人学会云上部署 Stable Diffusion
    目前大火的AIGC领域中,除了ChatGPT,StableDiffusion在文生图领域大放异彩,深刻影响着绘画、视频制作等相关领域。《动手吧,开发者》本期活动邀请B站知识区UP主、“林粒粒”手把手教大家用函数计算FC部署StableDiffusion,教程简单易上手,在B站已有4w多用户观看学习。......