登录 注册

 golang如何实现给图片转方向,并保存

2025-09-29  回复(0) 

在 Golang 中实现图片的旋转和保存,通常会用到 imageimage/jpeg (或 image/png) 等标准库,以及一个强大的第三方库 github.com/disintegration/imaging,它提供了更便捷的图片处理功能,包括旋转。

下面将介绍两种实现方式:

1. 使用 imageimage/jpeg (或 image/png) 标准库(相对基础)
2. 使用 github.com/disintegration/imaging 库(推荐,更简单方便)


方法一:使用 imageimage/jpeg (或 image/png) 标准库


这种方法相对基础,需要手动处理像素的重新映射。

步骤:

1. 解码图片: 使用 image.Decode 来解码图片文件。
2. 创建新的图片: 根据旋转后的尺寸创建一个新的 image.RGBA 图像。
3. 像素映射: 遍历原始图片的像素,计算出它们在新图片中的对应位置,然后复制像素。
4. 编码并保存: 使用 jpeg.Encode (或 png.Encode) 将处理后的图片保存到文件。

代码示例(旋转 90 度顺时针):

go
package main

import (
"fmt"
"image"
"image/color"
"image/jpeg"
_ "image/jpeg" // 注册 JPEG 解码器
"os"
)

// rotate90DegreesClockwise 旋转图片 90 度顺时针
func rotate90DegreesClockwise(src image.Image) image.Image {
originalBounds := src.Bounds()
originalWidth, originalHeight := originalBounds.Dx(), originalBounds.Dy()

// 旋转后,宽和高互换
rotatedWidth := originalHeight
rotatedHeight := originalWidth

// 创建新的 RGBA 图像,用于存储旋转后的图片
rotatedImage := image.NewRGBA(image.Rect(0, 0, rotatedWidth, rotatedHeight))

// 遍历原始图片的像素,计算在新图片中的位置
for y := 0; y < originalHeight; y++ {
for x := 0; x < originalWidth; x++ {
// 原始坐标 (x, y)
// 旋转后的坐标 (newX, newY)
// 对于 90 度顺时针旋转:
// newX = originalHeight - 1 - y
// newY = x
newX := rotatedWidth - 1 - y
newY := x
rotatedImage.Set(newX, newY, src.At(x, y))
}
}
return rotatedImage
}

func main() {
// 1. 打开原始图片文件
file, err := os.Open("input.jpg") // 替换为你的图片文件路径
if err != nil {
fmt.Println("Error opening image:", err)
return
}
defer file.Close()

// 2. 解码图片
img, _, err := image.Decode(file)
if err != nil {
fmt.Println("Error decoding image:", err)
return
}

// 3. 旋转图片 (这里以旋转 90 度顺时针为例)
rotatedImg := rotate90DegreesClockwise(img)

// 4. 创建新的图片文件用于保存
outputFile, err := os.Create("output_rotated.jpg") // 替换为你想保存的文件路径
if err != nil {
fmt.Println("Error creating output file:", err)
return
}
defer outputFile.Close()

// 5. 编码并保存图片
// JPEG 编码质量,0-100,100 为最高质量
err = jpeg.Encode(outputFile, rotatedImg, &jpeg.Options{Quality: 90})
if err != nil {
fmt.Println("Error encoding image:", err)
return
}

fmt.Println("Image rotated and saved successfully!")
}


说明:

* image.Decode 会自动识别图片格式(JPEG, PNG 等),前提是你导入了相应的解码器(例如 _ "image/jpeg")。
* image.NewRGBA 创建了一个新的 RGBA 图像,RGBA 格式支持透明度,并且方便像素操作。
* 旋转逻辑是核心。对于 90 度顺时针旋转,原始坐标 (x, y) 映射到新坐标 (rotatedWidth - 1 - y, x)
* jpeg.Encode 用于将 image.Image 接口类型编码成 JPEG 格式并写入 io.Writer(这里是 os.File)。

其他旋转角度:

* 180 度: newX = originalWidth - 1 - x, newY = originalHeight - 1 - y
* 270 度顺时针 (或 90 度逆时针): newX = y, newY = originalHeight - 1 - x
* 水平翻转: newX = originalWidth - 1 - x, newY = y
* 垂直翻转: newX = x, newY = originalHeight - 1 - y


方法二:使用 github.com/disintegration/imaging 库 (推荐)


这个库大大简化了图片处理的操作。

安装库:

bash
go get github.com/disintegration/imaging


代码示例(旋转 90 度顺时针):

go
package main

import (
"fmt"
"image"
"log"
"os"

"github.com/disintegration/imaging"
)

func main() {
// 1. 打开原始图片文件
file, err := os.Open("input.jpg") // 替换为你的图片文件路径
if err != nil {
log.Fatalf("Error opening image: %v", err)
}
defer file.Close()

// 2. 解码图片
src, _, err := image.Decode(file)
if err != nil {
log.Fatalf("Error decoding image: %v", err)
}

// 3. 旋转图片 (使用 imaging 库)
// imaging.Rotate90 旋转 90 度顺时针
// imaging.Rotate180 旋转 180 度
// imaging.Rotate270 旋转 270 度顺时针
// imaging.FlipHorizontal 水平翻转
// imaging.FlipVertical 垂直翻转
rotatedImg := imaging.Rotate90(src) // 旋转 90 度顺时针

// 4. 创建新的图片文件用于保存
outputFile, err := os.Create("output_rotated_imaging.jpg") // 替换为你想保存的文件路径
if err != nil {
log.Fatalf("Error creating output file: %v", err)
}
defer outputFile.Close()

// 5. 编码并保存图片 (imaging 库提供了方便的 Encode 函数)
err = imaging.Encode(outputFile, rotatedImg, imaging.JPEG, &imaging.EncodeOptions{Quality: 90})
if err != nil {
log.Fatalf("Error encoding image: %v", err)
}

fmt.Println("Image rotated and saved successfully using imaging library!")
}


说明:

* imaging.Decode 也可以用来解码图片,但这里为了演示,我们仍然使用标准的 image.Decode
* imaging.Rotate90(src) 直接返回旋转后的 image.Image。这个库支持多种旋转和翻转操作,非常方便。
* imaging.Encode 是一个通用的编码函数,可以指定编码格式(imaging.JPEG, imaging.PNG 等)和选项。


如何选择:


* 学习目的或只需要简单的旋转: 方法一(标准库)可以帮助你理解图片像素操作的底层逻辑。
* 实际项目开发,追求效率和便捷: 强烈推荐 方法二(github.com/disintegration/imaging),它大大减少了代码量,且功能更全面。

注意事项:

* 错误处理: 在实际应用中,请务必对所有文件操作和图片处理操作进行细致的错误检查。
* 图片格式: 确保你导入了正确的图片格式解码器(image/jpeg, image/png 等)。
* 文件路径: 将示例代码中的 input.jpgoutput_rotated.jpg 替换为你实际的文件路径。
* 内存: 处理大型图片时,可能会消耗较多内存。

选择哪种方法取决于你的具体需求,但 github.com/disintegration/imaging 库无疑是更现代、更便捷的选择。

#回复 AI问答 上传/拍照 我的