记录笔记或者写博客的时候经常会直接复制mac截图插入图片,默认复制得到的是无损png图片,图片体积比较大,占空间带宽,就基于go实现了个命令行批量压缩工具。
基于图片尺寸压缩
主要是用到了github.com/nfnt/resize 库
func (j *JPG) Resizer(filePath string, dstPath string, compressFactor float64) error {
// 打开图片文件
file, err := os.Open(filePath)
if err != nil {
return err
}
defer file.Close()
// 解码图片
img, _, err := image.Decode(file)
if err != nil {
return err
}
// 计算新的宽高
width := uint(float64(img.Bounds().Dx()) * compressFactor)
height := uint(float64(img.Bounds().Dy()) * compressFactor)
// 缩放图片
resizedImg := resize.Resize(width, height, img, resize.Lanczos3)
// 创建输出文件
outputFile, err := os.Create(dstPath)
if err != nil {
return err
}
defer outputFile.Close()
// 保存压缩后的图片
err = jpeg.Encode(outputFile, resizedImg, nil)
if err != nil {
return err
}
return nil
}
基于质量的压缩
直接使用的Go image标准库
func (j *JPG) QualityLower(filePath string, dstPath string, quality int) error {
if quality < 0 {
return nil
}
if quality < 10 {
quality = quality * 10
}
if quality > 100 {
return nil
}
// 打开图片文件
file, err := os.Open(filePath)
if err != nil {
return err
}
defer file.Close()
// 解码图片
img, _, err := image.Decode(file)
if err != nil {
return err
}
// 创建输出文件
outputFile, err := os.Create(dstPath)
if err != nil {
return err
}
defer outputFile.Close()
// 设置JPEG编码参数
options := &jpeg.Options{
Quality: int(quality),
}
// 保存压缩后的图片
err = jpeg.Encode(outputFile, img, options)
if err != nil {
return err
}
return nil
}
png属于无损格式,go默认库无法进行有效压缩,就算用png.BestCompression 参数压缩效果也不理想,如果不是很在乎质量,可以转成jpg图片,再压缩
// QualityLower png 压缩
func (p *PNG) QualityLower(filePath string, dstPath string) error {
// 打开PNG图片文件
file, err := os.Open(filePath)
if err != nil {
return err
}
defer file.Close()
// 解码PNG图片
img, _, err := image.Decode(file)
if err != nil {
return err
}
// 创建输出文件
outputFile, err := os.Create(dstPath)
if err != nil {
return err
}
defer outputFile.Close()
encoder := png.Encoder{
CompressionLevel: png.BestCompression,
}
// 保存为PNG格式
err = encoder.Encode(outputFile, img)
if err != nil {
return err
}
return nil
}
png转jpg再压缩
func (i *ImageConvert) ToJPEG(filePath string, dstPath string, quality int) error {
file, err := os.Open(filePath)
if err != nil {
return err
}
defer file.Close()
img, _, err := image.Decode(file)
if err != nil {
return err
}
// 创建输出文件
outputFile, err := os.Create(dstPath)
if err != nil {
return err
}
defer outputFile.Close()
// 设置JPEG编码参数
jpegOptions := &jpeg.Options{
Quality: quality,
}
// 将PNG转为JPEG并进行压缩
err = jpeg.Encode(outputFile, img, jpegOptions)
if err != nil {
return err
}
return nil
}
完整代码在github,直接用go安装go install github.com/mengboy/img@latest使用示例:
# 将image下的png图片批量转换为jpeg图片并压缩质量到80
img convert -s /images -d /imagesjpeg -c jpeg -q 80
# 将image下的test.png转换为test.jpeg并压缩质量到80
img convert -s /images/test.png -d /images/test.jpeg -c jpeg -q 80
# 将image下的图片批量压缩质量到80
img resize -s /images -d /images8 -q 80
# 将image下的test.jpeg压缩质量到80
img resize -s /images/test.jpeg -d /images/test8.jpeg - 80
# 将image下的png图片尺寸批量缩小至原来的80%
img resize -s /images -d /images8 -f 0.8
# 将image下的test.png图片尺寸缩小至原来的80%
img resize -s /images/test.png -d /images/test8.png -f 0.8