package picture_service
import (
"errors"
"github.com/nfnt/resize"
"image"
"image/draw"
"image/jpeg"
"image/png"
"log"
"net/http"
"os"
)
type PictureService struct{}
func NewPictureService() *PictureService {
return &PictureService{}
}
func (service *PictureService) PictureMerge(sign string, pic string, newImagePath string, left int, up int, picWidth int, picHeight int, signWidth int, signHeight int) (err error) {
signFile, err := os.Open(sign)
if err != nil {
return
}
defer signFile.Close()
sImage, _, err := image.Decode(signFile)
if err != nil {
return
}
signImage := resize.Resize(uint(signWidth), uint(signHeight), sImage, resize.Lanczos3)
picFile, err := os.Open(pic)
if err != nil {
return
}
defer picFile.Close()
picBytes, err := os.ReadFile(pic)
if err != nil {
return
}
contentType := http.DetectContentType(picBytes)
var picImage image.Image
if contentType == "image/jpeg" || contentType == "image/jpg" {
picImage, err = jpeg.Decode(picFile)
if err != nil {
return
}
} else if contentType == "image/png" {
picImage, err = png.Decode(picFile)
if err != nil {
return
}
} else {
return errors.New("未知图片类型")
}
// 重置底图大小
resizePicImage := resize.Resize(uint(picWidth), uint(picHeight), picImage, resize.Lanczos3)
// 新建画布,边界与底图一致
templateImage := image.NewRGBA(resizePicImage.Bounds())
// 将底图覆盖画布上,坐标起点为0,0
draw.Draw(templateImage, resizePicImage.Bounds(), resizePicImage, resizePicImage.Bounds().Min, draw.Over)
if err != nil {
log.Panicln(err.Error())
return
}
// 签章图片的高、宽的 1/2 就是,签章图片中心到右下角距离。文字信息的中心:向左距离(left),向上距离(up)
// left -宽 = l,up - 高 = h
// 向左移动 l,向上移动 h,就可以让印章图的中心点和文字的中心点总是重合,这样印章就是总是在文字上面
imaCenterLeft := signImage.Bounds().Dx() / 2
imaCenterUp := signImage.Bounds().Dy() / 2
l := left - imaCenterLeft
h := up - imaCenterUp
// 向左移动X减少,向上移动Y减少
offset := image.Pt(templateImage.Bounds().Dx()-signImage.Bounds().Dx()-l, templateImage.Bounds().Dy()-signImage.Bounds().Dy()-h)
draw.Draw(
templateImage,
signImage.Bounds().Add(offset),
signImage,
// 0,0 为起点
image.Point{},
draw.Over)
err = service.savePng(templateImage, newImagePath)
return
}
func (service *PictureService) savePng(pic *image.RGBA, path string) (err error) {
dstFile, err := os.Create(path)
if err != nil {
return
}
defer dstFile.Close()
err = png.Encode(dstFile, pic)
return
}
标签:return,nil,err,合成,Bounds,golang,signImage,image,图片
From: https://www.cnblogs.com/jing1024/p/18405044