zoukankan      html  css  js  c++  java
  • Golang压缩Jpeg图片和PNG图片

    • 博主一直在维护一个导出PDF的服务,但是这个服务导出的PDF文件是真的巨大,动辄就上百MB。这里面主要是图片占据了大多数体积,所以考虑在导出前压缩一下图片。
    • Jpeg的图片压缩是很好做的,因为jpeg这个协议本身就支持调整图片质量的。在golang中,我们只需要使用标准库的image/jpeg,将图片从二进制数据解码后,降低质量再编码为二进制数据即可实现压缩。而且质量和压缩比例相对而言还不错。
    func compressImageResource(data []byte) []byte {
    	img, _, err := image.Decode(bytes.NewReader(data))
    	if err != nil {
    		return data
    	}
    	buf := bytes.Buffer{}
    	err = jpeg.Encode(&buf, img, &jpeg.Options{Quality: 40})
    	if err != nil {
    		return data
    	}
    	if buf.Len() > len(data) {
    		return data
    	}
    	return buf.Bytes()
    }
    
    • 比较麻烦的是压缩PNG图片,在网上找了很多相关的库,感觉都没什么即可以保持质量,又可以尽可能压缩的办法。
    //下面这两个库都比较偏重于转换图片大小,在保持宽高不变的情况下,压缩比例很一般
    https://github.com/discord/lilliput                        //这个库是一家海外公司基于C语言的一个开源图片处理库,但是封装的很好,不需要安装额外依赖
    https://github.com/disintegration/imaging
    
    //下面这个库可以对PNG图片进行较大的压缩,可惜压缩比例过大时会严重失真
    https://github.com/foobaz/lossypng/
    
    
    • 后来,借鉴一篇博客的做法,还是先把PNG图片转换为Jpeg图片,然后再将jpeg图片的质量降低。相对上边这些库,压缩比例和质量都比较令人满意
    func compressImageResource(data []byte) []byte {
    	imgSrc, _, err := image.Decode(bytes.NewReader(data))
    	if err != nil {
    		return data
    	}
            newImg := image.NewRGBA(imgSrc.Bounds())
    	draw.Draw(newImg, newImg.Bounds(), &image.Uniform{C: color.White}, image.Point{}, draw.Src)
    	draw.Draw(newImg, newImg.Bounds(), imgSrc, imgSrc.Bounds().Min, draw.Over)
    
    	buf := bytes.Buffer{}
    	err = jpeg.Encode(&buf, newImg, &jpeg.Options{Quality: 40})
    	if err != nil {
    		return data
    	}
    	if buf.Len() > len(data) {
    		return data
    	}
    	return buf.Bytes()
    }
    
    
    • 最后给大家分享一个超级好用PDF处理的golang 库: https://github.com/unidoc/unipdf。一开始使用这个库将生成后的PDF压缩的,可以将一个200M的PDF(里面都是图片)直接压缩到7M左右。可惜的是这个库商用需要购买商业版权,所以最后只能采取了导出前压缩图片的做法。
    • 这个库没有授权的情况下会在处理后的PDF中加上水印,这个想去掉也简单,fork下来改一下代码就好了。虽然我这里因为是商业的场景不能这么用,但是我还是尝试了下,仓库在这:https://github.com/lianggx6/unipdf。然后再在go.mod文件中将依赖替换即可。大家如果有个人开发实践需要的可以直接这样拿来用,商用务必购买版权。
    replace (
    	github.com/unidoc/unipdf/v3 => github.com/lianggx6/unipdf v0.0.0-20200409043947-1c871b2c4951
    )
    
  • 相关阅读:
    docker 镜像相关
    docker相关网站
    docker初识 一
    loadrunner Windows资源指标
    Codeforces Round #368 (Div. 2) Brain's Photos
    CodeForce 589J Cleaner Robot
    CodeForce 677I Lottery
    CodeForce 677D Boulevard
    CodeForce 589B Layer Cake
    Map的遍历
  • 原文地址:https://www.cnblogs.com/lianggx6/p/12684885.html
Copyright © 2011-2022 走看看