描述
随意上传一张图片,将图片的分辨率等比率压缩至 108*108 的格式,若图片不是正方形,则多余部分使用黑色填充。
大体思路
- 首先将图片进行解码。
- 将图片分辨率等比例压缩至 108*108 。
- 创建一个黑色的 108*108 的图片,在黑色图片上把压缩过的图片画在正中间。
- 最后再创建新的图片/编码。
完整代码
package main
import (
"bufio"
"bytes"
"fmt"
"github.com/nfnt/resize"
"image"
"image/draw"
"image/jpeg"
"image/png"
"io/ioutil"
"log"
"net/http"
"os"
"strings"
)
func main() {
file, err := os.Open("/Users/guowenfeng/Desktop/test2.jpeg")
if err != nil {
log.Fatal(err)
}
// 因为有人为修改后缀的可能性,所以这里去探查一下图片的真正格式,然后根据格式来确定使用 png 还是 jpeg 进行解码。
buffer, err := ioutil.ReadAll(bufio.NewReader(file))
contentType := http.DetectContentType(buffer)
var img image.Image
if contentType == "png" {
img, err = png.Decode(bytes.NewReader(buffer))
} else {
img, err = jpeg.Decode(bytes.NewReader(buffer))
}
if err != nil {
fmt.Println("decode err")
log.Fatal(err)
}
file.Close()
width := img.Bounds().Dx()
height := img.Bounds().Dy()
widthNew := 108
heightNew := 108
// 将图片等比例压缩至 108*108 的格式。
var m image.Image
if width/height >= widthNew/heightNew {
m = resize.Resize(uint(widthNew), uint(height)*uint(widthNew)/uint(width), img, resize.Lanczos3)
} else {
m = resize.Resize(uint(width*heightNew/height), uint(heightNew), img, resize.Lanczos3)
}
// 在黑色图片上画上压缩后的图片
newImag := image.NewNRGBA(image.Rect(0, 0, 108, 108))
if m.Bounds().Dx() > m.Bounds().Dy() {
draw.Draw(newImag, image.Rectangle{
Min: image.Point{Y: (108 - m.Bounds().Dy()) / 2},
Max: image.Point{108, 108},
}, m, m.Bounds().Min, draw.Src)
} else {
draw.Draw(newImag, image.Rectangle{
Min: image.Point{X: (108 - m.Bounds().Dx()) / 2},
Max: image.Point{108, 108},
}, m, m.Bounds().Min, draw.Src)
}
out, err := os.Create("/Users/guowenfeng/Desktop/test_resized.jpeg")
if err != nil {
log.Println("create err " + err.Error())
log.Fatal(err)
}
defer out.Close()
//write new image to file
err = jpeg.Encode(out, newImag, nil)
//err = png.Encode(out, newImag) // png encode 会把黑边去掉,不能用
if err != nil {
log.Fatal(err)
}
}