github.com/qxnw/lib4go@v0.0.0-20180426074627-c80c7e84b925/images/image.go (about)

     1  package images
     2  
     3  import (
     4  	"fmt"
     5  	"image"
     6  	"image/color"
     7  	"image/draw"
     8  	"image/jpeg"
     9  	"image/png"
    10  	"io/ioutil"
    11  	"os"
    12  	"strconv"
    13  	"strings"
    14  
    15  	"golang.org/x/image/font"
    16  
    17  	"github.com/golang/freetype"
    18  	"github.com/nfnt/resize"
    19  )
    20  
    21  //Image 图片自定义处理类
    22  type Image struct {
    23  	m *image.RGBA
    24  }
    25  
    26  //NewImage 创建指定大小的画板
    27  func NewImage(w int, h int) (img *Image) {
    28  	img = &Image{}
    29  	img.m = image.NewRGBA(image.Rect(0, 0, w, h))
    30  	draw.Draw(img.m, img.m.Bounds(), image.White, image.ZP, draw.Src)
    31  	return
    32  }
    33  
    34  //NewImageFromFile 根据文件创建画板
    35  func NewImageFromFile(p string) (img *Image, err error) {
    36  	ig, err := decodeImage(p)
    37  	if err != nil {
    38  		return
    39  	}
    40  	img = &Image{}
    41  	img.m = image.NewRGBA(ig.Bounds())
    42  	draw.Draw(img.m, img.m.Bounds(), ig, image.ZP, draw.Src)
    43  	return
    44  }
    45  
    46  //DrawImage 在当前画版上绘制图片
    47  func (img *Image) DrawImage(p string, sx int, sy int, ex int, ey int) (err error) {
    48  	m, err := decodeImage(p)
    49  	if err != nil {
    50  		return
    51  	}
    52  	draw.Draw(img.m, image.Rect(sx, sy, ex, ey), m, image.Pt(0, 0), draw.Over)
    53  	return
    54  }
    55  
    56  //DrawFont 绘制字体
    57  func (img *Image) DrawFont(fontPath string, text string, col string, fontSize float64, sx int, sy int) (err error) {
    58  	data, err := ioutil.ReadFile(fontPath)
    59  	if err != nil {
    60  		return
    61  	}
    62  	f, err := freetype.ParseFont(data)
    63  	if err != nil {
    64  		return
    65  	}
    66  
    67  	c := freetype.NewContext()
    68  	c.SetDst(img.m)
    69  	c.SetClip(img.m.Bounds())
    70  	switch col {
    71  	case "000000":
    72  		c.SetSrc(image.NewUniform(color.Gray16{0}))
    73  	case "ffffff":
    74  		c.SetSrc(image.NewUniform(color.Gray16{0xffff}))
    75  	default:
    76  		r, g, b, err := colorToRGB(col)
    77  		if err != nil {
    78  			return err
    79  		}
    80  		c.SetSrc(image.NewUniform(color.RGBA{R: r, G: g, B: b, A: 1}))
    81  	}
    82  
    83  	c.SetFont(f)
    84  	c.SetFontSize(fontSize)
    85  	c.SetHinting(font.HintingNone)
    86  	_, err = c.DrawString(text, freetype.Pt(sx, sy))
    87  	return
    88  }
    89  
    90  //DrawImageWithScale 绘制图片并缩放原始图片
    91  func (img *Image) DrawImageWithScale(p string, sx int, sy int, w int, h int) (err error) {
    92  	m1, err := decodeImage(p)
    93  	if err != nil {
    94  		return
    95  	}
    96  	//缩放图片
    97  	m := resize.Resize(uint(w), uint(h), m1, resize.Lanczos3)
    98  	draw.Draw(img.m, image.Rect(sx, sy, sx+w, sy+h), m, image.Pt(0, 0), draw.Over)
    99  	return
   100  }
   101  
   102  //Save 保存图片到指定路径
   103  func (img *Image) Save(path string) error {
   104  	imgfile, _ := os.Create(path)
   105  	defer imgfile.Close()
   106  	if strings.HasSuffix(path, ".jpg") {
   107  		return jpeg.Encode(imgfile, img.m, &jpeg.Options{Quality: 70})
   108  	}
   109  	return png.Encode(imgfile, img.m)
   110  }
   111  
   112  func decodeImage(p string) (m image.Image, err error) {
   113  	f1, err := os.Open(p)
   114  	if err != nil {
   115  		return
   116  	}
   117  	if strings.HasSuffix(p, ".jpg") {
   118  		m, err = jpeg.Decode(f1)
   119  		return
   120  	} else if strings.HasSuffix(p, ".png") {
   121  		m, err = png.Decode(f1)
   122  		return
   123  	}
   124  	return nil, fmt.Errorf("图片格式不支持")
   125  
   126  }
   127  
   128  func colorToRGB(sc string) (red, green, blue uint8, err error) {
   129  	color64, err := strconv.ParseInt(sc, 16, 32) //字串到数据整型
   130  	if err != nil {
   131  		return
   132  	}
   133  	c := int(color64) //类型强转
   134  	red = uint8(c >> 16)
   135  	green = uint8((c & 0x00FF00) >> 8)
   136  	blue = uint8(c & 0x0000FF)
   137  	return
   138  }