1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > golang 九宫格头像生成

golang 九宫格头像生成

时间:2021-09-01 16:17:26

相关推荐

golang 九宫格头像生成

原文地址:/cqvoip/p/8078843.html

原文作者:李不白

特别感谢原文博主 李不白。 原文上有个函数代码没有贴上来。联系上李不白之后补全给我了。所以特别感谢他的不吝赐教。

贴上原文代码

//Merge6Grid 6宫格//rule NO1:至少3张图 最多6张图// NO2:第一张大小 60*60 其他大小 28*28 间隔4px 合成图大小102*102// NO3:排列顺序 从左至右 从上到小 再 从右到左// ++|// ++|// --|func Merge6Grid(src []io.Reader, dst io.Writer) error {defer func() {if r := recover(); r != nil {log.Println("Merge.recover:", r)}}()if len(src) < 3 || len(src) > 6 {panic("the pic num is between 3 and 6")}var err errorimagePoints := getXy6Grid(len(src))//创建背景大图background := image.NewRGBA(image.Rect(0, 0, 100, 100))//设置背景为灰色for m := 0; m < 100; m++ {for n := 0; n < 100; n++ {//rgba := GetRGBA(0xC8CED4)background.SetRGBA(m, n, color.RGBA{127, 127, 127, 0})}}//背景图矩形圆角newBg, err := CreateRoundRectWithRGBA(background, 10)if err != nil {return err}//开始合成var width intfor i, v := range imagePoints {x := v.xy := v.yif i == 0 {width = 60} else {width = 28}fOut := memory.NewWriter()//先缩略err = Scale(src[i], fOut, width, width, 100)if err != nil {return err}//矩形圆角rgba, err := CreateRoundRectWithoutColor(fOut, 6)if err != nil {return err}draw.Draw(newBg, newBg.Bounds(), rgba, rgba.Bounds().Min.Sub(image.Pt(x, y)), draw.Src)}return png.Encode(dst, newBg)//return jpeg.Encode(dst, newBg, nil)}//CreateRoundRect 创建圆角矩形 r为输入图像 r为圆角半径 color为圆角颜色func CreateRoundRect(rd io.Reader, r int, c *color.RGBA) (*image.RGBA, error) {src, _, err := image.Decode(rd)if err != nil {return nil, err}b := src.Bounds()x := b.Dx()y := b.Dy()dst := image.NewRGBA(b)draw.Draw(dst, b, src, src.Bounds().Min, draw.Src)p1 := image.Point{r, r}p2 := image.Point{x - r, r}p3 := image.Point{r, y - r}p4 := image.Point{x - r, y - r}for m := 0; m < x; m++ {for n := 0; n < y; n++ {if (p1.X-m)*(p1.X-m)+(p1.Y-n)*(p1.Y-n) > r*r && m <= p1.X && n <= p1.Y {dst.Set(m, n, c)} else if (p2.X-m)*(p2.X-m)+(p2.Y-n)*(p2.Y-n) > r*r && m > p2.X && n <= p2.Y {dst.Set(m, n, c)} else if (p3.X-m)*(p3.X-m)+(p3.Y-n)*(p3.Y-n) > r*r && m <= p3.X && n > p3.Y {dst.Set(m, n, c)} else if (p4.X-m)*(p4.X-m)+(p4.Y-n)*(p4.Y-n) > r*r && m > p4.X && n > p4.Y {dst.Set(m, n, c)}}}return dst, nil}func CreateRoundRectWithoutColor(rd io.Reader, r int) (*image.RGBA, error) {src, _, err := image.Decode(rd)if err != nil {return nil, err}b := src.Bounds()x := b.Dx()y := b.Dy()dst := image.NewRGBA(b)p1 := image.Point{r, r}p2 := image.Point{x - r, r}p3 := image.Point{r, y - r}p4 := image.Point{x - r, y - r}for m := 0; m < x; m++ {for n := 0; n < y; n++ {if (p1.X-m)*(p1.X-m)+(p1.Y-n)*(p1.Y-n) > r*r && m <= p1.X && n <= p1.Y {} else if (p2.X-m)*(p2.X-m)+(p2.Y-n)*(p2.Y-n) > r*r && m > p2.X && n <= p2.Y {} else if (p3.X-m)*(p3.X-m)+(p3.Y-n)*(p3.Y-n) > r*r && m <= p3.X && n > p3.Y {} else if (p4.X-m)*(p4.X-m)+(p4.Y-n)*(p4.Y-n) > r*r && m > p4.X && n > p4.Y {} else {dst.Set(m, n, src.At(m, n))}}}return dst, nil}func CreateRoundRectWithRGBA(src *image.RGBA, r int) (*image.RGBA, error) {b := src.Bounds()x := b.Dx()y := b.Dy()dst := image.NewRGBA(b)p1 := image.Point{r, r}p2 := image.Point{x - r, r}p3 := image.Point{r, y - r}p4 := image.Point{x - r, y - r}for m := 0; m < x; m++ {for n := 0; n < y; n++ {if (p1.X-m)*(p1.X-m)+(p1.Y-n)*(p1.Y-n) > r*r && m <= p1.X && n <= p1.Y {} else if (p2.X-m)*(p2.X-m)+(p2.Y-n)*(p2.Y-n) > r*r && m > p2.X && n <= p2.Y {} else if (p3.X-m)*(p3.X-m)+(p3.Y-n)*(p3.Y-n) > r*r && m <= p3.X && n > p3.Y {} else if (p4.X-m)*(p4.X-m)+(p4.Y-n)*(p4.Y-n) > r*r && m > p4.X && n > p4.Y {} else {dst.Set(m, n, src.At(m, n))}}}return dst, nil}//0xC8CED4func GetRGBA(c int) *color.RGBA {var cl color.RGBAcl.R = uint8((c >> 16) & 0xFF)cl.G = uint8((c >> 8) & 0xFF)cl.B = uint8(c & 0xFF)return &cl}func getXy6Grid(size int) []*Point {s := make([]*Point, size)_x, _y := 4, 4s[0] = &Point{_x, _y}s[1] = &Point{60 + 2*_x, _y}s[2] = &Point{60 + 2*_x, 28 + 2*_y}if size >= 4 {s[3] = &Point{60 + 2*_x, 28*2 + 3*_y}}if size >= 5 {s[4] = &Point{28 + 2*_x, 60 + 2*_y}}if size >= 6 {s[5] = &Point{_x, 60 + 2*_y}}return s}以下是仿微信群头像//Merge 九宫格头像合成 固定新图大小132*132px 间隙3px//至少一张图片func Merge(src []io.Reader, dst io.Writer) error {defer func() {if r := recover(); r != nil {log.Println("Merge.recover:", r)}}()var err errorimagePoints := getXy(len(src))width := getWidth(len(src))//创建背景图background := image.NewRGBA(image.Rect(0, 0, 132, 132))//设置背景为灰色for m := 0; m < 132; m++ {for n := 0; n < 132; n++ {background.SetRGBA(m, n, color.RGBA{127, 127, 127, 0})}}for i, v := range imagePoints {x := v.xy := v.yfOut := memory.NewWriter()err = Scale(src[i], fOut, width, width, 100)if err != nil {return err}//file2draw, err := jpeg.Decode(fOut)file2draw, _, err := image.Decode(fOut)if err != nil {return err}draw.Draw(background, background.Bounds(), file2draw, file2draw.Bounds().Min.Sub(image.Pt(x, y)), draw.Src)}return jpeg.Encode(dst, background, nil)}type Point struct {x, y int}func getXy(size int) []*Point {s := make([]*Point, size)var _x, _y intif size == 1 {_x, _y = 6, 6s[0] = &Point{_x, _y}}if size == 2 {_x, _y = 4, 4s[0] = &Point{_x, 132/2 - 60/2}s[1] = &Point{60 + 2*_x, 132/2 - 60/2}}if size == 3 {_x, _y = 4, 4s[0] = &Point{132/2 - 60/2, _y}s[1] = &Point{_x, 60 + 2*_y}s[2] = &Point{60 + 2*_y, 60 + 2*_y}}if size == 4 {_x, _y = 4, 4s[0] = &Point{_x, _y}s[1] = &Point{_x*2 + 60, _y}s[2] = &Point{_x, 60 + 2*_y}s[3] = &Point{60 + 2*_y, 60 + 2*_y}}if size == 5 {_x, _y = 3, 3s[0] = &Point{(132 - 40*2 - _x) / 2, (132 - 40*2 - _y) / 2}s[1] = &Point{((132-40*2-_x)/2 + 40 + _x), (132 - 40*2 - _y) / 2}s[2] = &Point{_x, ((132-40*2-_x)/2 + 40 + _y)}s[3] = &Point{(_x*2 + 40), ((132-40*2-_x)/2 + 40 + _y)}s[4] = &Point{(_x*3 + 40*2), ((132-40*2-_x)/2 + 40 + _y)}}if size == 6 {_x, _y = 3, 3s[0] = &Point{_x, ((132 - 40*2 - _x) / 2)}s[1] = &Point{(_x*2 + 40), ((132 - 40*2 - _x) / 2)}s[2] = &Point{(_x*3 + 40*2), ((132 - 40*2 - _x) / 2)}s[3] = &Point{_x, ((132-40*2-_x)/2 + 40 + _y)}s[4] = &Point{(_x*2 + 40), ((132-40*2-_x)/2 + 40 + _y)}s[5] = &Point{(_x*3 + 40*2), ((132-40*2-_x)/2 + 40 + _y)}}if size == 7 {_x, _y = 3, 3s[0] = &Point{(132 - 40) / 2, _y}s[1] = &Point{_x, (_y*2 + 40)}s[2] = &Point{(_x*2 + 40), (_y*2 + 40)}s[3] = &Point{(_x*3 + 40*2), (_y*2 + 40)}s[4] = &Point{_x, (_y*3 + 40*2)}s[5] = &Point{(_x*2 + 40), (_y*3 + 40*2)}s[6] = &Point{(_x*3 + 40*2), (_y*3 + 40*2)}}if size == 8 {_x, _y = 3, 3s[0] = &Point{(132 - 80 - _x) / 2, _y}s[1] = &Point{((132-80-_x)/2 + _x + 40), _y}s[2] = &Point{_x, (_y*2 + 40)}s[3] = &Point{(_x*2 + 40), (_y*2 + 40)}s[4] = &Point{(_x*3 + 40*2), (_y*2 + 40)}s[5] = &Point{_x, (_y*3 + 40*2)}s[6] = &Point{(_x*2 + 40), (_y*3 + 40*2)}s[7] = &Point{(_x*3 + 40*2), (_y*3 + 40*2)}}if size == 9 {_x, _y = 3, 3s[0] = &Point{_x, _y}s[1] = &Point{_x*2 + 40, _y}s[2] = &Point{_x*3 + 40*2, _y}s[3] = &Point{_x, (_y*2 + 40)}s[4] = &Point{(_x*2 + 40), (_y*2 + 40)}s[5] = &Point{(_x*3 + 40*2), (_y*2 + 40)}s[6] = &Point{_x, (_y*3 + 40*2)}s[7] = &Point{(_x*2 + 40), (_y*3 + 40*2)}s[8] = &Point{(_x*3 + 40*2), (_y*3 + 40*2)}}return s}func getWidth(size int) int {var width intif size == 1 {width = 120}if size > 1 && size <= 4 {width = 60}if size >= 5 {width = 40}return width}//补上缺失的代码//* Clip 图片裁剪//* 入参:图片输入、输出、缩略图宽、缩略图高、Rectangle{Pt(x0, y0), Pt(x1, y1)},精度//* 规则:如果精度为0则精度保持不变//*//* 返回:error// */func Clip(in io.Reader, out io.Writer, wi, hi, x0, y0, x1, y1, quality int) (err error) {err = errors.New("unknow error")defer func() {if r := recover(); r != nil {log.Println(r)}}()var origin image.Imagevar fm stringorigin, fm, err = image.Decode(in)if err != nil {log.Println(err)return err}if wi == 0 || hi == 0 {wi = origin.Bounds().Max.Xhi = origin.Bounds().Max.Y}var canvas image.Imageif wi != origin.Bounds().Max.X {//先缩略canvas = resize.Thumbnail(uint(wi), uint(hi), origin, resize.Lanczos3)} else {canvas = origin}switch fm {case "jpeg":img := canvas.(*image.YCbCr)subImg := img.SubImage(image.Rect(x0, y0, x1, y1)).(*image.YCbCr)return jpeg.Encode(out, subImg, &jpeg.Options{quality})case "png":switch canvas.(type) {case *image.NRGBA:img := canvas.(*image.NRGBA)subImg := img.SubImage(image.Rect(x0, y0, x1, y1)).(*image.NRGBA)return png.Encode(out, subImg)case *image.RGBA:img := canvas.(*image.RGBA)subImg := img.SubImage(image.Rect(x0, y0, x1, y1)).(*image.RGBA)return png.Encode(out, subImg)}case "gif":img := canvas.(*image.Paletted)subImg := img.SubImage(image.Rect(x0, y0, x1, y1)).(*image.Paletted)return gif.Encode(out, subImg, &gif.Options{})//case "bmp"://img := canvas.(*image.RGBA)//subImg := img.SubImage(image.Rect(x0, y0, x1, y1)).(*image.RGBA)//return bmp.Encode(out, subImg)default:return errors.New("ERROR FORMAT")}return nil}/** Scale 缩略图生成* 入参:图片输入、输出,缩略图宽、高,精度* 规则: 如果width 或 hight其中有一个为0,则大小不变 如果精度为0则精度保持不变* 返回:缩略图真实宽、高、error*/func Scale(in io.Reader, out io.Writer, width, height, quality int) (int, int, error) {defer func() {if r := recover(); r != nil {log.Println(r)}}()var (w, h int)origin, fm, err := image.Decode(in)if err != nil {log.Println(err)return 0, 0, err}if width == 0 || height == 0 {width = origin.Bounds().Max.Xheight = origin.Bounds().Max.Y}if quality == 0 {quality = 100}canvas := resize.Thumbnail(uint(width), uint(height), origin, resize.Lanczos3)//return jpeg.Encode(out, canvas, &jpeg.Options{quality})w = canvas.Bounds().Dx()h = canvas.Bounds().Dy()switch fm {case "jpeg":return w, h, jpeg.Encode(out, canvas, &jpeg.Options{quality})case "png":return w, h, png.Encode(out, canvas)case "gif":return w, h, gif.Encode(out, canvas, &gif.Options{})//case "bmp": //被我注释掉的是x/image/bmp//return w, h, bmp.Encode(out, canvas)default:return w, h, errors.New("ERROR FORMAT")}return w, h, nil}// Format2JPEG 将图片转换为JPEG格式func Format2JPEG(in io.Reader, out io.Writer) error {defer func() {if r := recover(); r != nil {log.Println(r)}}()origin, _, err := image.Decode(in)if err != nil {return err}return jpeg.Encode(out, origin, nil)}// Format2PNG 将图片转换为PNG格式func Format2PNG(in io.Reader, out io.Writer) error {defer func() {if r := recover(); r != nil {log.Println(r)}}()origin, _, err := image.Decode(in)if err != nil {return err}return png.Encode(out, origin)}// Format2GIF将图片转换为GIF格式func Format2GIF(in io.Reader, out io.Writer) error {defer func() {if r := recover(); r != nil {log.Println(r)}}()origin, _, err := image.Decode(in)if err != nil {return err}return gif.Encode(out, origin, nil)}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。