-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Szilagyi Ervin
committed
Jun 25, 2018
1 parent
b258fd3
commit 221a9b8
Showing
6 changed files
with
149 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
package generate | ||
|
||
import ( | ||
"image" | ||
"image/color" | ||
"math" | ||
) | ||
|
||
// Direction constant - direction of the gradient from first color to the second color. | ||
type Direction int | ||
|
||
const ( | ||
// H - horizontal direction | ||
H Direction = iota | ||
// V - vertical direction | ||
V | ||
) | ||
|
||
func normalize(value float64, min float64, max float64) float64 { | ||
lower := -6.0 | ||
upper := 6.0 | ||
norm := (value - min) / (max - min) | ||
return norm*(upper-lower) + lower | ||
} | ||
|
||
// LinearGradient generates a gradient image using a linear function. | ||
func LinearGradient(size image.Point, startColor color.RGBA, endColor color.RGBA, direction Direction) *image.RGBA { | ||
gradFunc := func(colorChannel uint8, percent float64) uint8 { | ||
return uint8(math.Floor(float64(colorChannel) * percent)) | ||
} | ||
res := image.NewRGBA(image.Rect(0, 0, size.X, size.Y)) | ||
switch direction { | ||
case V: | ||
step := 1.0 / float64(size.Y) | ||
percent := 0.0 | ||
for y := 0; y < size.Y; y++ { | ||
c := color.RGBA{ | ||
R: gradFunc(startColor.R, 1.0-percent) + gradFunc(endColor.R, percent), | ||
G: gradFunc(startColor.G, 1.0-percent) + gradFunc(endColor.G, percent), | ||
B: gradFunc(startColor.B, 1.0-percent) + gradFunc(endColor.B, percent), | ||
A: 255, | ||
} | ||
percent += step | ||
for x := 0; x < size.X; x++ { | ||
res.SetRGBA(x, y, c) | ||
} | ||
} | ||
case H: | ||
step := 1.0 / float64(size.X) | ||
percent := 0.0 | ||
for x := 0; x < size.X; x++ { | ||
c := color.RGBA{ | ||
R: gradFunc(startColor.R, -percent) + gradFunc(endColor.R, percent), | ||
G: gradFunc(startColor.G, -percent) + gradFunc(endColor.G, percent), | ||
B: gradFunc(startColor.B, -percent) + gradFunc(endColor.B, percent), | ||
A: 255, | ||
} | ||
percent += step | ||
for y := 0; y < size.Y; y++ { | ||
res.SetRGBA(x, y, c) | ||
} | ||
} | ||
} | ||
return res | ||
} | ||
|
||
// SigmoidalGradient generates a gradient image using the sigmoid ( f(x) = 1 / (1 + exp(-x)) ) function. | ||
func SigmoidalGradient(size image.Point, startColor color.RGBA, endColor color.RGBA, direction Direction) *image.RGBA { | ||
sigmoid := func(val float64) float64 { | ||
return 1.0 / (1.0 + math.Exp(-val)) | ||
} | ||
res := image.NewRGBA(image.Rect(0, 0, size.X, size.Y)) | ||
switch direction { | ||
case V: | ||
for y := 0; y < size.Y; y++ { | ||
percent := sigmoid(normalize(float64(y), 0, float64(size.Y))) | ||
c := color.RGBA{ | ||
R: uint8((1.0-percent)*float64(startColor.R)) + uint8(percent*float64(endColor.R)), | ||
G: uint8((1.0-percent)*float64(startColor.G)) + uint8(percent*float64(endColor.G)), | ||
B: uint8((1.0-percent)*float64(startColor.B)) + uint8(percent*float64(endColor.B)), | ||
A: 255, | ||
} | ||
for x := 0; x < size.X; x++ { | ||
res.SetRGBA(x, y, c) | ||
} | ||
} | ||
case H: | ||
for x := 0; x < size.X; x++ { | ||
percent := sigmoid(normalize(float64(x), 0, float64(size.X))) | ||
c := color.RGBA{ | ||
R: uint8((1.0-percent)*float64(startColor.R)) + uint8(percent*float64(endColor.R)), | ||
G: uint8((1.0-percent)*float64(startColor.G)) + uint8(percent*float64(endColor.G)), | ||
B: uint8((1.0-percent)*float64(startColor.B)) + uint8(percent*float64(endColor.B)), | ||
A: 255, | ||
} | ||
for y := 0; y < size.Y; y++ { | ||
res.SetRGBA(x, y, c) | ||
} | ||
} | ||
} | ||
return res | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package generate | ||
|
||
import ( | ||
"github.com/Ernyoke/Imger/imgio" | ||
"image" | ||
"image/color" | ||
"testing" | ||
) | ||
|
||
// -----------------------------Acceptance tests------------------------------------ | ||
func setupTestCaseRGBA(t *testing.T) *image.RGBA { | ||
path := "../res/girl.jpg" | ||
img, err := imgio.ImreadRGBA(path) | ||
if err != nil { | ||
t.Errorf("Could not read image from path: %s", path) | ||
} | ||
return img | ||
} | ||
|
||
func tearDownTestCase(t *testing.T, img image.Image, path string) { | ||
err := imgio.Imwrite(img, path) | ||
if err != nil { | ||
t.Errorf("Could not write image to path: %s", path) | ||
} | ||
} | ||
|
||
func Test_Acceptance_LinearGradientHorizontal(t *testing.T) { | ||
res := LinearGradient(image.Point{X: 500, Y: 200}, color.RGBA{R: 0, G: 0, B: 0, A: 255}, color.RGBA{R: 255, G: 255, B: 255, A: 255}, H) | ||
tearDownTestCase(t, res, "../res/generate/linearGradientHorizontal.jpg") | ||
} | ||
|
||
func Test_Acceptance_LinearGradientVertical(t *testing.T) { | ||
res := LinearGradient(image.Point{X: 500, Y: 200}, color.RGBA{R: 0, G: 0, B: 0, A: 255}, color.RGBA{R: 255, G: 255, B: 255, A: 255}, V) | ||
tearDownTestCase(t, res, "../res/generate/linearGradientVertical.jpg") | ||
} | ||
|
||
func Test_Acceptance_SigmoidalHorizontal(t *testing.T) { | ||
res := SigmoidalGradient(image.Point{X: 500, Y: 200}, color.RGBA{R: 0, G: 0, B: 0, A: 255}, color.RGBA{R: 255, G: 255, B: 255, A: 255}, H) | ||
tearDownTestCase(t, res, "../res/generate/sigmoidalGradientHorizontal.jpg") | ||
} | ||
|
||
func Test_Acceptance_SigmoidalGradientVertical(t *testing.T) { | ||
res := SigmoidalGradient(image.Point{X: 500, Y: 200}, color.RGBA{R: 0, G: 0, B: 0, A: 255}, color.RGBA{R: 255, G: 255, B: 255, A: 255}, V) | ||
tearDownTestCase(t, res, "../res/generate/sigmoidalGradientVertical.jpg") | ||
} | ||
|
||
// --------------------------------------------------------------------------------- |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.