// CompositeImage numSizeRatio is num + '#' size_ratio
func CompositeImage(numSizeRatio string, imageUrls []string) ([]byte, error) {
	compositeImageParameter := CompositeImageParameterMap[numSizeRatio]
	basemap := image.NewRGBA(image.Rect(0, 0, compositeImageParameter.BaseImageWidth, compositeImageParameter.BaseImageHeight))
	var wg sync.WaitGroup
	for i := 0; i < len(imageUrls); i++ {
		wg.Add(1)
		go func(i int) {
			defer func() {
				if err := recover(); err != nil {
					log.Errorf("panic stack: %s", string(debug.Stack()))
					log.Error("CompositeImage panic:", err)
				}
				wg.Done()
			}()
			imageBytes, err := util.GetRaw(imageUrls[i])
			if err != nil {
				log.Errorf("GetRaw image %d error: %v", i, err)
				return
			}
			buffer := bytes.NewBuffer(imageBytes)
			imageDecode, err := webp.Decode(buffer)
			if err != nil {
				imageDecode, _, err = image.Decode(bytes.NewBuffer(imageBytes))
				if err != nil {
					log.Errorf("Decode image %d error: %v", i, err)
					return
				}
			}
			draw.Draw(basemap, image.Rect(compositeImageParameter.Offset[i][0], compositeImageParameter.Offset[i][1], compositeImageParameter.Offset[i][2], compositeImageParameter.Offset[i][3]),
				imageDecode, imageDecode.Bounds().Min, draw.Over)
		}(i)
	}
	wg.Wait()
	outputImageBytes := bytes.NewBuffer([]byte{})
	if err := png.Encode(outputImageBytes, basemap); err != nil {
		return nil, errors.Wrap(err, "png Encode error")
	}
	return outputImageBytes.Bytes(), nil
}
I use go test -race. It doesn’t have errors.