summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/disintegration/imaging/adjust.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/disintegration/imaging/adjust.go')
-rw-r--r--vendor/github.com/disintegration/imaging/adjust.go256
1 files changed, 139 insertions, 117 deletions
diff --git a/vendor/github.com/disintegration/imaging/adjust.go b/vendor/github.com/disintegration/imaging/adjust.go
index daee893cc..fb3a9ce3c 100644
--- a/vendor/github.com/disintegration/imaging/adjust.go
+++ b/vendor/github.com/disintegration/imaging/adjust.go
@@ -6,50 +6,95 @@ import (
"math"
)
-// AdjustFunc applies the fn function to each pixel of the img image and returns the adjusted image.
+// Grayscale produces a grayscale version of the image.
+func Grayscale(img image.Image) *image.NRGBA {
+ src := newScanner(img)
+ dst := image.NewNRGBA(image.Rect(0, 0, src.w, src.h))
+ parallel(0, src.h, func(ys <-chan int) {
+ for y := range ys {
+ i := y * dst.Stride
+ src.scan(0, y, src.w, y+1, dst.Pix[i:i+src.w*4])
+ for x := 0; x < src.w; x++ {
+ r := dst.Pix[i+0]
+ g := dst.Pix[i+1]
+ b := dst.Pix[i+2]
+ f := 0.299*float64(r) + 0.587*float64(g) + 0.114*float64(b)
+ y := uint8(f + 0.5)
+ dst.Pix[i+0] = y
+ dst.Pix[i+1] = y
+ dst.Pix[i+2] = y
+ i += 4
+ }
+ }
+ })
+ return dst
+}
+
+// Invert produces an inverted (negated) version of the image.
+func Invert(img image.Image) *image.NRGBA {
+ src := newScanner(img)
+ dst := image.NewNRGBA(image.Rect(0, 0, src.w, src.h))
+ parallel(0, src.h, func(ys <-chan int) {
+ for y := range ys {
+ i := y * dst.Stride
+ src.scan(0, y, src.w, y+1, dst.Pix[i:i+src.w*4])
+ for x := 0; x < src.w; x++ {
+ dst.Pix[i+0] = 255 - dst.Pix[i+0]
+ dst.Pix[i+1] = 255 - dst.Pix[i+1]
+ dst.Pix[i+2] = 255 - dst.Pix[i+2]
+ i += 4
+ }
+ }
+ })
+ return dst
+}
+
+// AdjustContrast changes the contrast of the image using the percentage parameter and returns the adjusted image.
+// The percentage must be in range (-100, 100). The percentage = 0 gives the original image.
+// The percentage = -100 gives solid gray image.
//
-// Example:
+// Examples:
//
-// dstImage = imaging.AdjustFunc(
-// srcImage,
-// func(c color.NRGBA) color.NRGBA {
-// // shift the red channel by 16
-// r := int(c.R) + 16
-// if r > 255 {
-// r = 255
-// }
-// return color.NRGBA{uint8(r), c.G, c.B, c.A}
-// }
-// )
+// dstImage = imaging.AdjustContrast(srcImage, -10) // decrease image contrast by 10%
+// dstImage = imaging.AdjustContrast(srcImage, 20) // increase image contrast by 20%
//
-func AdjustFunc(img image.Image, fn func(c color.NRGBA) color.NRGBA) *image.NRGBA {
- src := toNRGBA(img)
- width := src.Bounds().Max.X
- height := src.Bounds().Max.Y
- dst := image.NewNRGBA(image.Rect(0, 0, width, height))
-
- parallel(height, func(partStart, partEnd int) {
- for y := partStart; y < partEnd; y++ {
- for x := 0; x < width; x++ {
- i := y*src.Stride + x*4
- j := y*dst.Stride + x*4
-
- r := src.Pix[i+0]
- g := src.Pix[i+1]
- b := src.Pix[i+2]
- a := src.Pix[i+3]
-
- c := fn(color.NRGBA{r, g, b, a})
+func AdjustContrast(img image.Image, percentage float64) *image.NRGBA {
+ percentage = math.Min(math.Max(percentage, -100.0), 100.0)
+ lut := make([]uint8, 256)
- dst.Pix[j+0] = c.R
- dst.Pix[j+1] = c.G
- dst.Pix[j+2] = c.B
- dst.Pix[j+3] = c.A
- }
+ v := (100.0 + percentage) / 100.0
+ for i := 0; i < 256; i++ {
+ if 0 <= v && v <= 1 {
+ lut[i] = clamp((0.5 + (float64(i)/255.0-0.5)*v) * 255.0)
+ } else if 1 < v && v < 2 {
+ lut[i] = clamp((0.5 + (float64(i)/255.0-0.5)*(1/(2.0-v))) * 255.0)
+ } else {
+ lut[i] = uint8(float64(i)/255.0+0.5) * 255
}
- })
+ }
- return dst
+ return adjustLUT(img, lut)
+}
+
+// AdjustBrightness changes the brightness of the image using the percentage parameter and returns the adjusted image.
+// The percentage must be in range (-100, 100). The percentage = 0 gives the original image.
+// The percentage = -100 gives solid black image. The percentage = 100 gives solid white image.
+//
+// Examples:
+//
+// dstImage = imaging.AdjustBrightness(srcImage, -15) // decrease image brightness by 15%
+// dstImage = imaging.AdjustBrightness(srcImage, 10) // increase image brightness by 10%
+//
+func AdjustBrightness(img image.Image, percentage float64) *image.NRGBA {
+ percentage = math.Min(math.Max(percentage, -100.0), 100.0)
+ lut := make([]uint8, 256)
+
+ shift := 255.0 * percentage / 100.0
+ for i := 0; i < 256; i++ {
+ lut[i] = clamp(float64(i) + shift)
+ }
+
+ return adjustLUT(img, lut)
}
// AdjustGamma performs a gamma correction on the image and returns the adjusted image.
@@ -68,15 +113,7 @@ func AdjustGamma(img image.Image, gamma float64) *image.NRGBA {
lut[i] = clamp(math.Pow(float64(i)/255.0, e) * 255.0)
}
- fn := func(c color.NRGBA) color.NRGBA {
- return color.NRGBA{lut[c.R], lut[c.G], lut[c.B], c.A}
- }
-
- return AdjustFunc(img, fn)
-}
-
-func sigmoid(a, b, x float64) float64 {
- return 1 / (1 + math.Exp(b*(a-x)))
+ return adjustLUT(img, lut)
}
// AdjustSigmoid changes the contrast of the image using a sigmoidal function and returns the adjusted image.
@@ -118,83 +155,68 @@ func AdjustSigmoid(img image.Image, midpoint, factor float64) *image.NRGBA {
}
}
- fn := func(c color.NRGBA) color.NRGBA {
- return color.NRGBA{lut[c.R], lut[c.G], lut[c.B], c.A}
- }
-
- return AdjustFunc(img, fn)
+ return adjustLUT(img, lut)
}
-// AdjustContrast changes the contrast of the image using the percentage parameter and returns the adjusted image.
-// The percentage must be in range (-100, 100). The percentage = 0 gives the original image.
-// The percentage = -100 gives solid grey image.
-//
-// Examples:
-//
-// dstImage = imaging.AdjustContrast(srcImage, -10) // decrease image contrast by 10%
-// dstImage = imaging.AdjustContrast(srcImage, 20) // increase image contrast by 20%
-//
-func AdjustContrast(img image.Image, percentage float64) *image.NRGBA {
- percentage = math.Min(math.Max(percentage, -100.0), 100.0)
- lut := make([]uint8, 256)
+func sigmoid(a, b, x float64) float64 {
+ return 1 / (1 + math.Exp(b*(a-x)))
+}
- v := (100.0 + percentage) / 100.0
- for i := 0; i < 256; i++ {
- if 0 <= v && v <= 1 {
- lut[i] = clamp((0.5 + (float64(i)/255.0-0.5)*v) * 255.0)
- } else if 1 < v && v < 2 {
- lut[i] = clamp((0.5 + (float64(i)/255.0-0.5)*(1/(2.0-v))) * 255.0)
- } else {
- lut[i] = uint8(float64(i)/255.0+0.5) * 255
+// adjustLUT applies the given lookup table to the colors of the image.
+func adjustLUT(img image.Image, lut []uint8) *image.NRGBA {
+ src := newScanner(img)
+ dst := image.NewNRGBA(image.Rect(0, 0, src.w, src.h))
+ parallel(0, src.h, func(ys <-chan int) {
+ for y := range ys {
+ i := y * dst.Stride
+ src.scan(0, y, src.w, y+1, dst.Pix[i:i+src.w*4])
+ for x := 0; x < src.w; x++ {
+ dst.Pix[i+0] = lut[dst.Pix[i+0]]
+ dst.Pix[i+1] = lut[dst.Pix[i+1]]
+ dst.Pix[i+2] = lut[dst.Pix[i+2]]
+ i += 4
+ }
}
- }
-
- fn := func(c color.NRGBA) color.NRGBA {
- return color.NRGBA{lut[c.R], lut[c.G], lut[c.B], c.A}
- }
-
- return AdjustFunc(img, fn)
+ })
+ return dst
}
-// AdjustBrightness changes the brightness of the image using the percentage parameter and returns the adjusted image.
-// The percentage must be in range (-100, 100). The percentage = 0 gives the original image.
-// The percentage = -100 gives solid black image. The percentage = 100 gives solid white image.
+// AdjustFunc applies the fn function to each pixel of the img image and returns the adjusted image.
//
-// Examples:
+// Example:
//
-// dstImage = imaging.AdjustBrightness(srcImage, -15) // decrease image brightness by 15%
-// dstImage = imaging.AdjustBrightness(srcImage, 10) // increase image brightness by 10%
+// dstImage = imaging.AdjustFunc(
+// srcImage,
+// func(c color.NRGBA) color.NRGBA {
+// // shift the red channel by 16
+// r := int(c.R) + 16
+// if r > 255 {
+// r = 255
+// }
+// return color.NRGBA{uint8(r), c.G, c.B, c.A}
+// }
+// )
//
-func AdjustBrightness(img image.Image, percentage float64) *image.NRGBA {
- percentage = math.Min(math.Max(percentage, -100.0), 100.0)
- lut := make([]uint8, 256)
-
- shift := 255.0 * percentage / 100.0
- for i := 0; i < 256; i++ {
- lut[i] = clamp(float64(i) + shift)
- }
-
- fn := func(c color.NRGBA) color.NRGBA {
- return color.NRGBA{lut[c.R], lut[c.G], lut[c.B], c.A}
- }
-
- return AdjustFunc(img, fn)
-}
-
-// Grayscale produces grayscale version of the image.
-func Grayscale(img image.Image) *image.NRGBA {
- fn := func(c color.NRGBA) color.NRGBA {
- f := 0.299*float64(c.R) + 0.587*float64(c.G) + 0.114*float64(c.B)
- y := uint8(f + 0.5)
- return color.NRGBA{y, y, y, c.A}
- }
- return AdjustFunc(img, fn)
-}
-
-// Invert produces inverted (negated) version of the image.
-func Invert(img image.Image) *image.NRGBA {
- fn := func(c color.NRGBA) color.NRGBA {
- return color.NRGBA{255 - c.R, 255 - c.G, 255 - c.B, c.A}
- }
- return AdjustFunc(img, fn)
+func AdjustFunc(img image.Image, fn func(c color.NRGBA) color.NRGBA) *image.NRGBA {
+ src := newScanner(img)
+ dst := image.NewNRGBA(image.Rect(0, 0, src.w, src.h))
+ parallel(0, src.h, func(ys <-chan int) {
+ for y := range ys {
+ i := y * dst.Stride
+ src.scan(0, y, src.w, y+1, dst.Pix[i:i+src.w*4])
+ for x := 0; x < src.w; x++ {
+ r := dst.Pix[i+0]
+ g := dst.Pix[i+1]
+ b := dst.Pix[i+2]
+ a := dst.Pix[i+3]
+ c := fn(color.NRGBA{r, g, b, a})
+ dst.Pix[i+0] = c.R
+ dst.Pix[i+1] = c.G
+ dst.Pix[i+2] = c.B
+ dst.Pix[i+3] = c.A
+ i += 4
+ }
+ }
+ })
+ return dst
}