Skip to content

Instantly share code, notes, and snippets.

@ErikKalkoken
Created February 3, 2025 03:45
Show Gist options
  • Save ErikKalkoken/b40339bc45016ff3d8c8e5e1dcb72b07 to your computer and use it in GitHub Desktop.
Save ErikKalkoken/b40339bc45016ff3d8c8e5e1dcb72b07 to your computer and use it in GitHub Desktop.
Convert a JPEG image into an "avatar style" circle image
package main
import (
"bufio"
"image"
"image/color"
"image/draw"
_ "image/jpeg"
"image/png"
"os"
)
type circle struct {
p image.Point
r int
}
func (c *circle) ColorModel() color.Model {
return color.AlphaModel
}
func (c *circle) Bounds() image.Rectangle {
return image.Rect(c.p.X-c.r, c.p.Y-c.r, c.p.X+c.r, c.p.Y+c.r)
}
func (c *circle) At(x, y int) color.Color {
xx, yy, rr := float64(x-c.p.X)+0.5, float64(y-c.p.Y)+0.5, float64(c.r)
if xx*xx+yy*yy < rr*rr {
return color.Alpha{255}
}
return color.Alpha{0}
}
// applyCircleMask creates a new image from a round shape within the original
func applyCircleMask(source image.Image, origin image.Point, r int) image.Image {
c := &circle{origin, r}
result := image.NewRGBA(c.Bounds())
draw.DrawMask(result, source.Bounds(), source, image.Point{}, c, image.Point{}, draw.Over)
return result
}
func main() {
// load source
inFile, err := os.Open("erik.jpeg")
if err != nil {
panic(err)
}
defer inFile.Close()
reader := bufio.NewReader(inFile)
m, _, err := image.Decode(reader)
if err != nil {
panic(err)
}
// convert
b := m.Bounds()
w := (b.Max.X - b.Min.X) / 2
h := (b.Max.Y - b.Min.Y) / 2
r := min(w, h)
m2 := applyCircleMask(m, image.Point{X: w, Y: h}, r)
// write to dest
outFile, err := os.Create("out.png")
if err != nil {
panic(err)
}
defer outFile.Close()
if err := png.Encode(outFile, m2); err != nil {
panic(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment