Golang图片压缩实现方法与优化技巧
Golang图片压缩实现方法与优化技巧 大家好,我有一张 image.jpeg 图片,大小是 2.5 MB 或更大。我想压缩这张图片,以便能在网络应用中使用。我甚至不知道该如何着手。我查阅了一些图像处理库,但可能研究得不够深入,只看到了裁剪、模糊处理等选项。请提供一个代码示例或为我指明正确的方向,这样我就能进行更深入的研究。谢谢。
// 示例代码:使用Go进行图片压缩
package main
import (
"image/jpeg"
"os"
)
func main() {
// 打开原始图片文件
file, err := os.Open("image.jpeg")
if err != nil {
panic(err)
}
defer file.Close()
// 解码JPEG图片
img, err := jpeg.Decode(file)
if err != nil {
panic(err)
}
// 创建输出文件
out, err := os.Create("compressed_image.jpeg")
if err != nil {
panic(err)
}
defer out.Close()
// 设置压缩质量并编码输出
// 质量参数范围是1-100,数值越低压缩率越高
opts := &jpeg.Options{Quality: 75}
err = jpeg.Encode(out, img, opts)
if err != nil {
panic(err)
}
}
更多关于Golang图片压缩实现方法与优化技巧的实战教程也可以访问 https://www.itying.com/category-94-b0.html
3 回复
使用标准库的image/jpeg包调整质量参数是最直接的压缩方法。以下是优化后的代码示例,包含错误处理和更精确的质量控制:
package main
import (
"image"
"image/jpeg"
"io"
"os"
)
func compressJPEG(inputPath, outputPath string, quality int) error {
// 打开原始图片
inputFile, err := os.Open(inputPath)
if err != nil {
return err
}
defer inputFile.Close()
// 解码JPEG图片
img, err := jpeg.Decode(inputFile)
if err != nil {
return err
}
// 创建输出文件
outputFile, err := os.Create(outputPath)
if err != nil {
return err
}
defer outputFile.Close()
// 设置压缩质量
opts := &jpeg.Options{Quality: quality}
return jpeg.Encode(outputFile, img, opts)
}
// 高级压缩:先调整尺寸再压缩
func compressAndResize(inputPath, outputPath string, quality int, maxWidth int) error {
inputFile, err := os.Open(inputPath)
if err != nil {
return err
}
defer inputFile.Close()
img, _, err := image.Decode(inputFile)
if err != nil {
return err
}
// 获取原始尺寸
bounds := img.Bounds()
origWidth := bounds.Dx()
origHeight := bounds.Dy()
// 计算新尺寸
newWidth := origWidth
newHeight := origHeight
if origWidth > maxWidth {
ratio := float64(maxWidth) / float64(origWidth)
newWidth = maxWidth
newHeight = int(float64(origHeight) * ratio)
}
// 创建新图像并调整尺寸
resizedImg := image.NewRGBA(image.Rect(0, 0, newWidth, newHeight))
for y := 0; y < newHeight; y++ {
for x := 0; x < newWidth; x++ {
srcX := x * origWidth / newWidth
srcY := y * origHeight / newHeight
resizedImg.Set(x, y, img.At(srcX, srcY))
}
}
// 保存压缩后的图片
outputFile, err := os.Create(outputPath)
if err != nil {
return err
}
defer outputFile.Close()
opts := &jpeg.Options{Quality: quality}
return jpeg.Encode(outputFile, resizedImg, opts)
}
func main() {
// 基础压缩示例
err := compressJPEG("image.jpeg", "compressed_basic.jpeg", 75)
if err != nil {
panic(err)
}
// 调整尺寸+压缩示例
err = compressAndResize("image.jpeg", "compressed_resized.jpeg", 80, 1024)
if err != nil {
panic(err)
}
}
对于更高级的优化,可以使用第三方库如github.com/disintegration/imaging:
package main
import (
"github.com/disintegration/imaging"
"image/jpeg"
"os"
)
func compressWithImaging(inputPath, outputPath string, quality int, width int) error {
// 打开并解码图片
img, err := imaging.Open(inputPath)
if err != nil {
return err
}
// 调整尺寸
if width > 0 {
img = imaging.Resize(img, width, 0, imaging.Lanczos)
}
// 保存压缩图片
outputFile, err := os.Create(outputPath)
if err != nil {
return err
}
defer outputFile.Close()
opts := &jpeg.Options{Quality: quality}
return jpeg.Encode(outputFile, img, opts)
}
func main() {
// 使用imaging库进行高质量压缩
err := compressWithImaging("image.jpeg", "compressed_advanced.jpeg", 85, 1200)
if err != nil {
panic(err)
}
}
关键优化技巧:
- 质量参数设置在75-85之间通常能在文件大小和视觉质量间取得平衡
- 对于网络使用,将宽度限制在1200-1600像素
- 使用渐进式JPEG编码(如果需要,可通过第三方库实现)
- 批量处理时考虑并行压缩:
func batchCompress(files []string, quality int, outputDir string) {
sem := make(chan struct{}, 4) // 限制并发数
for _, file := range files {
sem <- struct{}{}
go func(f string) {
defer func() { <-sem }()
outputPath := outputDir + "/compressed_" + f
compressJPEG(f, outputPath, quality)
}(file)
}
for i := 0; i < cap(sem); i++ {
sem <- struct{}{}
}
}


