youbbs
youbbs
3185 5 0

Golang 模仿微信群头像九宫格

在主题前面添加类似微信群用户头像九宫格,这个想法很早就有,拖到现在才实现,楼主在右下角,最新回复用户在前。

感谢 Li BuBai 写好的 核心功能,省掉很多繁琐的工作。

func Merge(src []io.Reader, dst io.Writer) error {
	defer func() {
		if r := recover(); r != nil {
			log.Println("Merge.recover:", r)
		}
	}()
	var err error
	imagePoints := getXy(len(src))
	width := getWidth(len(src))

	//Create a background image
	background := image.NewRGBA(image.Rect(0, 0, 132, 132))

	//Set the background to gray (127, 127, 127)
	for m := 0; m < 132; m++ {
		for n := 0; n < 132; n++ {
			background.SetRGBA(m, n, color.RGBA{R: 214, G: 214, B: 214, A: 0})
		}
	}

	for i, v := range imagePoints {
		x := v.x
		y := v.y

		fOut := MemoryNewWriter(nil)

		_, _, 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 int

	if size == 1 {
		_x, _y = 6, 6
		s[0] = &Point{_x, _y}
	}
	if size == 2 {
		_x, _y = 4, 4
		s[0] = &Point{_x, 132/2 - 60/2}
		s[1] = &Point{60 + 2*_x, 132/2 - 60/2}
	}
	if size == 3 {
		_x, _y = 4, 4
		s[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, 4
		s[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, 3
		s[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, 3
		s[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, 3
		s[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, 3
		s[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, 3
		s[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
}

顺便把头像及九宫格头像保存在数据库里,减少小文件 io

标题参与用户头像九宫格在参与用户大于9个才好看,4个头像也不错。

相关问题

  • 大量头像文件(小文件4~6KB)保存在数据库的利弊?
0

See Also

Nearby


Discussion (5)

小萌娘
小萌娘 2021-04-02 11:57

wow 你都已经用上了啊 这个什么时候推送到github啊 到时学学习下 感觉挺酷的

0
youbbs
youbbs 2021-04-03 00:22

@小萌娘 #1 好多bug

0
ego008
ego008 2021-04-03 11:05

@youbbs #2 旧 bug 修好新 bug 来

0
liao123
liao123 2021-04-09 22:00

这个功能很赞👍👍

0
ego008
ego008 2021-04-09 22:03

@liao123 #4 多用户互动效果更好

0
Login Topics