需求:
1、将两张图片上下排列合成为一张新图片(就像平时去复印身份证,上面是正面,下面是反面);
2、新图片的宽度最大为 600 ;
3、最大高度不定义,保证图片原始宽高比即可;
问题排除:
关于图片的尺寸,可能会遇到以下几种情况:
1、两张图片宽度都大于600:直接以600为基准,进行缩放即可;
2、两张图片宽度不一致,并且小于600:以较小的图片宽度为基准,将较大图片的宽高比并进行缩放即可;
resize库中的Resize函数内部已经实现了自动计算图片宽高比的逻辑,所以,外部就不需要自己计算了。
实现:
package main
import (
"github.com/nfnt/resize"
"image"
"image/draw"
"image/jpeg"
"log"
"math"
"os"
)
const MaxWidth float64 = 600
func fixSize(img1W, img2W int) (new1W, new2W int) {
var ( //为了方便计算,将两个图片的宽转为 float64
img1Width, img2Width = float64(img1W), float64(img2W)
ratio1, ratio2 float64
)
minWidth := math.Min(img1Width, img2Width) // 取出两张图片中宽度最小的为基准
if minWidth > 600 { // 如果最小宽度大于600,那么两张图片都需要进行缩放
ratio1 = MaxWidth / img1Width // 图片1的缩放比例
ratio2 = MaxWidth / img2Width // 图片2的缩放比例
// 原宽度 * 比例 = 新宽度
return int(img1Width * ratio1), int(img2Width * ratio2)
}
// 如果最小宽度小于600,那么需要将较大的图片缩放,使得两张图片的宽度一致
if minWidth == img1Width {
ratio2 = minWidth / img2Width // 图片2的缩放比例
return img1W, int(img2Width * ratio2)
}
ratio1 = minWidth / img1Width // 图片1的缩放比例
return int(img1Width * ratio1), img2W
}
func main() {
file1, _ := os.Open("001.jpg") //打开图片1
file2, _ := os.Open("002.jpg") //打开图片2
defer file1.Close()
defer file2.Close()
// image.Decode 图片
var (
img1, img2 image.Image
err error
)
if img1, _, err = image.Decode(file1); err != nil {
log.Fatal(err)
return
}
if img2, _, err = image.Decode(file2); err != nil {
log.Fatal(err)
return
}
b1 := img1.Bounds()
b2 := img2.Bounds()
new1W, new2W := fixSize(b1.Max.X, b2.Max.X)
// 调用resize库进行图片缩放(高度填0,resize.Resize函数中会自动计算缩放图片的宽高比)
m1 := resize.Resize(uint(new1W), 0, img1, resize.Lanczos3)
m2 := resize.Resize(uint(new2W), 0, img2, resize.Lanczos3)
// 将两个图片合成一张
newWidth := m1.Bounds().Max.X //新宽度 = 随意一张图片的宽度
newHeight := m1.Bounds().Max.Y + m2.Bounds().Max.Y // 新图片的高度为两张图片高度的和
newImg := image.NewNRGBA(image.Rect(0, 0, newWidth, newHeight)) //创建一个新RGBA图像
draw.Draw(newImg, newImg.Bounds(), m1, m1.Bounds().Min, draw.Over) //画上第一张缩放后的图片
draw.Draw(newImg, newImg.Bounds(), m2, m2.Bounds().Min.Sub(image.Pt(0, m1.Bounds().Max.Y)), draw.Over) //画上第二张缩放后的图片(这里需要注意Y值的起始位置)
// 保存文件
imgfile, _ := os.Create("003.jpg")
defer imgfile.Close()
jpeg.Encode(imgfile, newImg, &jpeg.Options{100})
}