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 回复

它确实做到了,我成功将文件大小减半,而且没遇到太多麻烦。非常感谢你的帮助。

最终我使用了这个库“github.com/disintegration/imaging”。不过还是感谢你为我指明了正确的方向。

更多关于Golang图片压缩实现方法与优化技巧的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这样可以吗?

GitHub

nfnt/resize

头像

纯 Go 语言图像缩放。通过在 GitHub 上创建帐户来为 nfnt/resize 的开发做出贡献。

使用标准库的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)
    }
}

关键优化技巧:

  1. 质量参数设置在75-85之间通常能在文件大小和视觉质量间取得平衡
  2. 对于网络使用,将宽度限制在1200-1600像素
  3. 使用渐进式JPEG编码(如果需要,可通过第三方库实现)
  4. 批量处理时考虑并行压缩:
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{}{}
    }
}
回到顶部