package main
import (
"errors"
"flag"
"image"
"image/color"
"image/draw"
"image/jpeg"
"image/png"
"os"
"path/filepath"
"strings"
)
var (
imageFile = flag.String("image_path", "/Users/cpenny/go/src/local/picture_draw_pp/image.png", "path")
destImageFile = flag.String("dest_image_path", "new_file.jpg", "path")
)
type ImagePt struct {
Value string `json:"value"`
X int `json:"x"`
Y int `json:"y"`
Percentage float64 `json:"percentage"`
}
func main() {
// 读取图片信息
var err error
var imageNr *image.NRGBA
imageNr, err = readImage()
if err != nil {
panic(err)
}
// 写入图片信息
ipt := ImagePt{
Value: "temp.png",
X: 0,
Y: 0,
Percentage: 0.6,
}
imageNr, err = writeImage(imageNr, ipt)
if err != nil {
panic(err)
}
// 压缩图片
// 保存图片
err = genImage(imageNr)
if err != nil {
panic(err)
}
}
func readImage() (imageNR *image.NRGBA, err error) {
//原始图片是sam.jpg
var imgI image.Image
imgI, err = getImage("temp.png")
if err != nil {
return imageNR, err
}
b := imgI.Bounds()
m := image.NewNRGBA(b)
draw.Draw(m, b, imgI, image.ZP, draw.Src)
return m, nil
}
// 插入图片
func writeImage(imageR *image.NRGBA, ipt ImagePt) (nr *image.NRGBA, err error) {
var watermark image.Image
watermark, err = getImage(ipt.Value)
if err != nil {
return nr, err
}
//把水印写到右下角,并向0坐标各偏移10个像素
offset := image.Pt(ipt.X, ipt.Y)
waterRgba := ImageTypeToRGBA64(&watermark)
waterRgba = OpacityAdjust(waterRgba, ipt.Percentage)
draw.Draw(imageR, watermark.Bounds().Add(offset), waterRgba, image.ZP, 60)
return imageR, err
}
//Image转换为image.RGBA64
func ImageTypeToRGBA64(m *image.Image) *image.RGBA64 {
bounds := (*m).Bounds()
dx := bounds.Dx()
dy := bounds.Dy()
newRgba := image.NewRGBA64(bounds)
for i := 0; i < dx; i++ {
for j := 0; j < dy; j++ {
colorRgb := (*m).At(i, j)
r, g, b, a := colorRgb.RGBA()
nR := uint16(r)
nG := uint16(g)
nB := uint16(b)
alpha := uint16(a)
newRgba.SetRGBA64(i, j, color.RGBA64{R: nR, G: nG, B: nB, A: alpha})
}
}
return newRgba
}
//将输入图像m的透明度变为原来的倍数。若原来为完成全不透明,则percentage = 0.5将变为半透明
func OpacityAdjust(m *image.RGBA64, percentage float64) *image.RGBA64 {
bounds := m.Bounds()
dx := bounds.Dx()
dy := bounds.Dy()
newRgba := image.NewRGBA64(bounds)
for i := 0; i < dx; i++ {
for j := 0; j < dy; j++ {
colorRgb := m.At(i, j)
r, g, b, a := colorRgb.RGBA()
opacity := uint16(float64(a) * percentage)
//颜色模型转换,至关重要!
v := newRgba.ColorModel().Convert(color.NRGBA64{R: uint16(r), G: uint16(g), B: uint16(b), A: opacity})
//Alpha = 0: Full transparent
rr, gg, bb, aa := v.RGBA()
newRgba.SetRGBA64(i, j, color.RGBA64{R: uint16(rr), G: uint16(gg), B: uint16(bb), A: uint16(aa)})
}
}
return newRgba
}
// 生成图片
func genImage(imageR *image.NRGBA) (err error) {
var imgF *os.File
imgF, err = os.Create(*destImageFile)
if err != nil {
return err
}
res := getImageSuffix(*destImageFile)
if res != "" {
if res == "jpg" {
err = jpeg.Encode(imgF, imageR, &jpeg.Options{100})
if err != nil {
return err
}
} else if res == "png" {
err = png.Encode(imgF, imageR)
if err != nil {
return err
}
}
}
return nil
}
// 获取图片
func getImage(iPath string) (img image.Image, err error) {
var imgF *os.File
imgF, err = os.Open(iPath)
if err != nil {
return img, err
}
res := getImageSuffix(iPath)
if res != "" {
if res == "png" {
img, err = png.Decode(imgF)
if err != nil {
return img, err
}
} else if res == "jpg" {
img, err = jpeg.Decode(imgF)
if err != nil {
return img, err
}
} else {
return img, errors.New("无法解析该图片")
}
}
return img, err
}
// 获取图片后缀
func getImageSuffix(iPath string) (res string) {
suffix := filepath.Ext(iPath)
suffix = strings.ToLower(suffix)
if suffix == ".jpg" || suffix == ".jpeg" {
res = "jpg"
} else if suffix == ".png" {
res = "png"
} else {
res = ""
}
return res
}
参考链接:https://www.cnblogs.com/wangjunqiao/p/10985397.html