BOYYANG/1/blog/WLOP-digital-art-artwork-illustration-fantasy-art-lion-2302910-wallhere

golang 图片压缩

作者: boyyang
分类: 后端开发
发布: 2024-07-13 03:01:25
更新: 2025-03-23 12:10:09
浏览: 404

       之前个人博客中的所有图片我都是直接原图存储的,大多数图片都是4k,图片文件比较大,导致本来就慢的网站更加慢了。所以决定还是牺牲一点图片质量压缩一下图片。

       图片压缩可以分为前端压缩,后端压缩,前端通过canvas更改图片质量可以达到图片压缩的效果,前端的优势在于上传的时候图片就是压缩后的图片,那么上传速度有显著提升。后端压缩上传的是原图,所以上传速度还是没有任何变化。

        但是可能前端压缩和后端压缩用的库不同,压缩的算法不同,那么压缩图片的结果也不通。所以最后我还是决定使用后端图片压缩。

       安装压缩库

go get github.com/nfnt/resize

       下面是go后端图片压缩代码

package helper

import (
	"bytes"
	"github.com/nfnt/resize"
	"image"
	_ "image/gif"
	"image/jpeg"
	_ "image/jpeg"
	"image/png"
	_ "image/png"
	"mime/multipart"
)

type CompressedImage struct {
	Buf    *bytes.Buffer
	Width  int
	Height int
	Hash   string
	Size   int64
}

func ResizeImage(fileHeader *multipart.FileHeader) (compressionImage *CompressedImage, err error) {
	imgFile, err := fileHeader.Open()
	if err != nil {
		return nil, err
	}
	defer func(img multipart.File) {
		_ = img.Close()
	}(imgFile)

	img, imgType, err := image.Decode(imgFile)
	if err != nil {
		return nil, err
	}
	bounds := img.Bounds()
	cimg := resize.Resize(uint(bounds.Dx()), uint(bounds.Dy()), img, resize.Lanczos3)
	buffer := new(bytes.Buffer)
	hash, err := MakeImageFileHash(cimg, imgType)
	if err != nil {
		return nil, err
	}

	switch imgType {
	case "png":
		if err = png.Encode(buffer, cimg); err != nil {
			return nil, err
		}
	case "jpeg", "jpg":
		if err = jpeg.Encode(buffer, cimg, nil); err != nil {
			return nil, err
		}
	}

	reader := bytes.NewReader(buffer.Bytes())

	return &CompressedImage{
		Hash:   hash,
		Buf:    buffer,
		Width:  bounds.Dx(),
		Height: bounds.Dy(),
		Size:   int64(reader.Size()),
	}, nil
}

       计算文件hash

func MakeImageFileHash(img image.Image, imgType string) (hash string, err error) {
	buf := new(bytes.Buffer)

	switch imgType {
	case "png":
		if err = png.Encode(buf, img); err != nil {
			return "", err
		}
	case "jpeg", "jpg":
		if err = jpeg.Encode(buf, img, nil); err != nil {
			return "", err
		}
	}

	h := make([]byte, buf.Len())
	if _, err = buf.Read(h); err != nil {
		return "", err
	}

	return fmt.Sprintf("%x", md5.Sum(h)), nil
}

总结:

       通过图片压缩后质量感觉没啥大变化,封面图原图5.6M,压缩后图片759.5kb。所以感觉压缩率还不错。

#go
#后端
#图片压缩