diff --git a/.github/README.md b/.github/README.md index 2aa8fba..8df418a 100644 --- a/.github/README.md +++ b/.github/README.md @@ -116,6 +116,10 @@ func controller(context *fiber.Ctx) error { Full Fiber example is available at https://github.com/peterdee/filtering-backend +### Performance + +Brille uses `sync.WaitGroup` for performance optimization starting with version **v2.0.4**. Image processing can be done in several threads (by default Brille uses `runtime.NumCPU()` value). + ### Available filters - **Binary**: converts an image to 1-bit black and white. Requires a threshold value (`uint8`, 0 to 255): diff --git a/filters/emboss.go b/filters/emboss.go index 29ae9d6..a55f6b7 100644 --- a/filters/emboss.go +++ b/filters/emboss.go @@ -25,11 +25,11 @@ func Emboss(file io.Reader) (io.Reader, string, error) { if convertationError != nil { return nil, "", convertationError } - width, height := img.Rect.Max.X, img.Rect.Max.Y pixLen := len(img.Pix) - result := make([]uint8, pixLen) threads := utilities.GetThreads() pixPerThread := utilities.GetPixPerThread(pixLen, threads) + result := make([]uint8, pixLen) + width, height := img.Rect.Max.X, img.Rect.Max.Y var wg sync.WaitGroup processing := func(thread int) { defer wg.Done() diff --git a/filters/gaussian-blur.go b/filters/gaussian-blur.go index 5d4335c..a8f9544 100644 --- a/filters/gaussian-blur.go +++ b/filters/gaussian-blur.go @@ -41,12 +41,11 @@ func GaussianBlur(file io.Reader, sigma float64) (io.Reader, string, error) { sigma = utilities.Clamp(sigma, 99, 0) kernel := createKernel(sigma) pixLen := len(img.Pix) - width, height := img.Rect.Max.X, img.Rect.Max.Y - temp := make([]uint8, pixLen) threads := utilities.GetThreads() pixPerThread := utilities.GetPixPerThread(pixLen, threads) + temp := make([]uint8, pixLen) + width, height := img.Rect.Max.X, img.Rect.Max.Y var wg sync.WaitGroup - processing := func(start int, direction string) { defer wg.Done() end := utilities.ClampMax(start+pixPerThread, pixLen) @@ -88,20 +87,15 @@ func GaussianBlur(file io.Reader, sigma float64) (io.Reader, string, error) { } } } - - // horizontal for t := 0; t < threads; t += 1 { wg.Add(1) go processing(pixPerThread*t, "horizontal") } wg.Wait() - - // vertical for t := 0; t < threads; t += 1 { wg.Add(1) go processing(pixPerThread*t, "vertical") } wg.Wait() - return utilities.EncodeResult(img, format) } diff --git a/filters/kuwahara.go b/filters/kuwahara.go index 0aa0026..b6725ff 100644 --- a/filters/kuwahara.go +++ b/filters/kuwahara.go @@ -12,12 +12,12 @@ func Kuwahara(file io.Reader, radius uint) (io.Reader, string, error) { if convertationError != nil { return nil, "", convertationError } - width, height := img.Rect.Max.X, img.Rect.Max.Y radiusInt := int(radius) pixLen := len(img.Pix) threads := utilities.GetThreads() pixPerThread := utilities.GetPixPerThread(pixLen, threads) result := make([]uint8, pixLen) + width, height := img.Rect.Max.X, img.Rect.Max.Y var wg sync.WaitGroup processing := func(thread int) { defer wg.Done() diff --git a/filters/laplacian.go b/filters/laplacian.go index a29f8be..ab43563 100644 --- a/filters/laplacian.go +++ b/filters/laplacian.go @@ -18,11 +18,11 @@ func Laplacian(file io.Reader) (io.Reader, string, error) { if convertationError != nil { return nil, "", convertationError } - width, height := img.Rect.Max.X, img.Rect.Max.Y pixLen := len(img.Pix) threads := utilities.GetThreads() pixPerThread := utilities.GetPixPerThread(pixLen, threads) result := make([]uint8, pixLen) + width, height := img.Rect.Max.X, img.Rect.Max.Y var wg sync.WaitGroup processing := func(thread int) { defer wg.Done() diff --git a/filters/sharpen.go b/filters/sharpen.go index 9871f48..ffdf655 100644 --- a/filters/sharpen.go +++ b/filters/sharpen.go @@ -22,8 +22,8 @@ func Sharpen(file io.Reader, amount uint) (io.Reader, string, error) { pixLen := len(img.Pix) threads := utilities.GetThreads() pixPerThread := utilities.GetPixPerThread(pixLen, threads) - width, height := img.Rect.Max.X, img.Rect.Max.Y result := make([]uint8, pixLen) + width, height := img.Rect.Max.X, img.Rect.Max.Y var wg sync.WaitGroup processing := func(thread int) { defer wg.Done() diff --git a/filters/sobel.go b/filters/sobel.go index 4d9968f..123a659 100644 --- a/filters/sobel.go +++ b/filters/sobel.go @@ -28,8 +28,8 @@ func Sobel(file io.Reader) (io.Reader, string, error) { pixLen := len(img.Pix) threads := utilities.GetThreads() pixPerThread := utilities.GetPixPerThread(pixLen, threads) - width, height := img.Rect.Max.X, img.Rect.Max.Y result := make([]uint8, pixLen) + width, height := img.Rect.Max.X, img.Rect.Max.Y var wg sync.WaitGroup processing := func(thread int) { defer wg.Done()