Create linear color gradient in go
Go doesn’t have any builtin gradient functions to paint/fill the background of a raster, however it has all the required primitives one needs to create a very basic linear gradient.
Here is a basic code which defines a 256 x 256 image, then calculates the value of each pixel in the raster based on a linear interpolation formula.
import (
"image"
"image/color"
"image/png"
"log"
"os"
"os/exec"
)
var(
colorB = [3]float64{248, 54, 0}
colorA = [3]float64{254, 140, 0}
)
var(
width = 256
height = 256
max = float64(width)
)
func linearGradient(x, y float64) (uint8, uint8, uint8) {
d := x/max
r := colorA[0] + d * (colorB[0] - colorA[0])
g := colorA[1] + d * (colorB[1] - colorA[1])
b := colorA[2] + d * (colorB[2] - colorA[2])
return uint8(r), uint8(g), uint8(b)
}
func main() {
var w, h int = width, height
dst := image.NewRGBA(image.Rect(0, 0, w, h)) //*NRGBA (image.Image interface)
for x := 0; x < w; x++ {
for y := 0; y < h; y++ {
r, g, b := linearGradient(float64(x), float64(y))
c := color.RGBA{
r,
g,
b,
255,
}
dst.Set(x, y, c)
}
}
img, \_ := os.Create("new.png")
defer img.Close()
png.Encode(img, dst) //Encode writes the Image m to w in PNG format.
Show(img.Name())
}
// show a specified file by Preview.app for OS X(darwin)
func Show(name string) {
command := "open"
arg1 := "-a"
arg2 := "/Applications/Preview.app"
cmd := exec.Command(command, arg1, arg2, name)
err := cmd.Run()
if err != nil {
log.Fatal(err)
}
}
Here is how the generated image looks like
Function linearGradient is where all the magic happens, this method takes in x and y pixel locations and then calculates the appropriate gradient value based on the maximum width (256) to produce a horizontal gradient, now if one was to change the the d := x/max to d := y/max, this now becomes a top down-gradient instead of left-right (our image is 256x256 hence max of both width and height is 256) like so
or swap colors arrays to get a differrent affect. ### Circular Gradient
To get something like a circular gradient replace linearGradient function with circularRadient
var dx, dy float64 = cenX - x, cenY - y
d:= math.Sqrt(dx*dx+dy*dy)
p := d/255
r := colorA[0] + p*(colorB[0]-colorA[0])
g := colorA[1] + p*(colorB[1]-colorA[1])
b := colorA[2] + p*(colorB[2]-colorA[2])
return uint8(r), uint8(g), uint8(b)
}
This should result in an image like below
or if you want to confine it to the circle try this
var dx, dy float64 = cenX - x, cenY - y
d:= math.Sqrt(dx*dx+dy*dy)
p := d/255
if d < 128 {
r := colorA[0] + p*(colorB[0]-colorA[0])
g := colorA[1] + p*(colorB[1]-colorA[1])
b := colorA[2] + p*(colorB[2]-colorA[2])
return uint8(r), uint8(g), uint8(b)
}
return 0,0,0
}
Hope this helps.