github.com/status-im/status-go@v1.1.0/images/status_indicator.go (about) 1 package images 2 3 import ( 4 "bytes" 5 "image" 6 "image/color" 7 "image/png" 8 "math" 9 10 "github.com/fogleman/gg" 11 ) 12 13 func AddStatusIndicatorToImage(inputImage []byte, innerColor color.Color, indicatorSize, indicatorBorder, indicatorCenterToEdge float64) ([]byte, error) { 14 // decode the input image 15 img, _, err := image.Decode(bytes.NewReader(inputImage)) 16 if err != nil { 17 return nil, err 18 } 19 20 // get the dimensions of the image 21 width := img.Bounds().Max.X 22 height := img.Bounds().Max.Y 23 24 indicatorOuterRadius := (indicatorSize / 2) + indicatorBorder 25 26 // calculate the center point 27 x := float64(width) - indicatorCenterToEdge 28 y := float64(height) - indicatorCenterToEdge 29 30 // create a new gg.Context instance 31 dc := gg.NewContext(width, height) 32 dc.DrawImage(img, 0, 0) 33 34 // Loop through each pixel in the hole and set it to transparent 35 dc.SetColor(color.Transparent) 36 for i := x - indicatorOuterRadius; i <= x+indicatorOuterRadius; i++ { 37 for j := y - indicatorOuterRadius; j <= y+indicatorOuterRadius; j++ { 38 if math.Pow(i-x, 2)+math.Pow(j-y, 2) <= math.Pow(indicatorOuterRadius, 2) { 39 dc.SetPixel(int(i), int(j)) 40 } 41 } 42 } 43 44 // draw inner circle 45 dc.DrawCircle(x, y, indicatorOuterRadius-indicatorBorder) 46 dc.SetColor(innerColor) 47 dc.Fill() 48 49 // encode the modified image as PNG and return as []byte 50 var outputImage bytes.Buffer 51 err = png.Encode(&outputImage, dc.Image()) 52 if err != nil { 53 return nil, err 54 } 55 return outputImage.Bytes(), nil 56 }