From 7ce2543be63caed3a3f16c4565de65563a2c9494 Mon Sep 17 00:00:00 2001 From: Peter Date: Sat, 14 Jan 2023 23:36:44 +0300 Subject: [PATCH 1/2] Fix horizontal and vertical flipping --- processing/flip-horizontal.go | 6 +++++- processing/flip-vertical.go | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/processing/flip-horizontal.go b/processing/flip-horizontal.go index 6464129..7222897 100644 --- a/processing/flip-horizontal.go +++ b/processing/flip-horizontal.go @@ -9,7 +9,11 @@ import ( func FlipHorizontal(source [][]color.Color) [][]color.Color { width, height := len(source), len(source[0]) destination := utilities.CreateGrid(width, height) - for x := 0; x < width/2; x += 1 { + correction := 0 + if width%2 != 0 { + correction = 1 + } + for x := 0; x < width/2+correction; x += 1 { for y := 0; y < height; y += 1 { z := width - x - 1 destination[x][y], destination[z][y] = source[z][y], source[x][y] diff --git a/processing/flip-vertical.go b/processing/flip-vertical.go index 7dde204..932ef91 100644 --- a/processing/flip-vertical.go +++ b/processing/flip-vertical.go @@ -9,8 +9,12 @@ import ( func FlipVertical(source [][]color.Color) [][]color.Color { width, height := len(source), len(source[0]) destination := utilities.CreateGrid(width, height) + correction := 0 + if height%2 != 0 { + correction = 1 + } for x := 0; x < width; x += 1 { - for y := 0; y < height/2; y += 1 { + for y := 0; y < height/2+correction; y += 1 { z := height - y - 1 destination[x][y], destination[x][z] = source[x][z], source[x][y] } From 1771718682836061524f949ebb7828a92273a066 Mon Sep 17 00:00:00 2001 From: Peter Date: Sat, 14 Jan 2023 23:46:56 +0300 Subject: [PATCH 2/2] Add hue rotation filter --- README.md | 6 +++++ index.go | 17 ++++++++++++++ processing/hue-rotate.go | 49 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 processing/hue-rotate.go diff --git a/README.md b/README.md index e1580b0..2660cd9 100644 --- a/README.md +++ b/README.md @@ -179,6 +179,12 @@ func controller(context *fiber.Ctx) error { ) ``` +- **Hue rotation**: rotate image hue to change the colors. Requires an angle to be provided. Angle represents degree of a hue rotation, can be any `int` number: + + ```golang + rotated, format, processingError := brille.HueRotate(file, 278) + ``` + - **Laplasian filter**: a static edge detection filter that uses a 3x3 kernel. It can be used to outline edges on an image: ```golang diff --git a/index.go b/index.go index b692792..3388b03 100644 --- a/index.go +++ b/index.go @@ -203,6 +203,23 @@ func Grayscale(file io.Reader, grayscaleType string) (io.Reader, string, error) return encoded, format, nil } +// angle: any int value +func HueRotate(file io.Reader, angle int) (io.Reader, string, error) { + if file == nil { + return nil, "", errors.New(constants.ERROR_NO_FILE_PROVIDED) + } + source, format, preparationError := utilities.PrepareSource(file) + if preparationError != nil { + return nil, "", preparationError + } + rotated := processing.HueRotate(source, angle) + encoded, encodingError := utilities.PrepareResult(rotated, format) + if encodingError != nil { + return nil, "", encodingError + } + return encoded, format, nil +} + func LaplasianFilter(file io.Reader) (io.Reader, string, error) { if file == nil { return nil, "", errors.New(constants.ERROR_NO_FILE_PROVIDED) diff --git a/processing/hue-rotate.go b/processing/hue-rotate.go new file mode 100644 index 0000000..490ae24 --- /dev/null +++ b/processing/hue-rotate.go @@ -0,0 +1,49 @@ +package processing + +import ( + "image/color" + "math" + + "github.com/julyskies/brille/utilities" +) + +const DEG float64 = math.Pi / 180 + +func HueRotate(source [][]color.Color, angle int) [][]color.Color { + width, height := len(source), len(source[0]) + destination := utilities.CreateGrid(width, height) + cos := math.Cos(float64(angle) * DEG) + sin := math.Sin(float64(angle) * DEG) + matrix := [3]float64{ + cos + (1-cos)/3, + (1-cos)/3 - math.Sqrt(float64(1)/3)*sin, + (1-cos)/3 + math.Sqrt(float64(1)/3)*sin, + } + for x := 0; x < width; x += 1 { + for y := 0; y < height; y += 1 { + r, g, b, alpha := utilities.RGBA(source[x][y]) + rr := utilities.MaxMin( + float64(r)*matrix[0]+float64(g)*matrix[1]+float64(b)*matrix[2], + 255, + 0, + ) + rg := utilities.MaxMin( + float64(r)*matrix[2]+float64(g)*matrix[0]+float64(b)*matrix[1], + 255, + 0, + ) + rb := utilities.MaxMin( + float64(r)*matrix[1]+float64(g)*matrix[2]+float64(b)*matrix[0], + 255, + 0, + ) + destination[x][y] = color.RGBA{ + uint8(rr), + uint8(rg), + uint8(rb), + alpha, + } + } + } + return destination +}