summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/disintegration/imaging/effects.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/disintegration/imaging/effects.go')
-rw-r--r--vendor/github.com/disintegration/imaging/effects.go187
1 files changed, 187 insertions, 0 deletions
diff --git a/vendor/github.com/disintegration/imaging/effects.go b/vendor/github.com/disintegration/imaging/effects.go
new file mode 100644
index 000000000..fe92e10a2
--- /dev/null
+++ b/vendor/github.com/disintegration/imaging/effects.go
@@ -0,0 +1,187 @@
+package imaging
+
+import (
+ "image"
+ "math"
+)
+
+func gaussianBlurKernel(x, sigma float64) float64 {
+ return math.Exp(-(x*x)/(2*sigma*sigma)) / (sigma * math.Sqrt(2*math.Pi))
+}
+
+// Blur produces a blurred version of the image using a Gaussian function.
+// Sigma parameter must be positive and indicates how much the image will be blurred.
+//
+// Usage example:
+//
+// dstImage := imaging.Blur(srcImage, 3.5)
+//
+func Blur(img image.Image, sigma float64) *image.NRGBA {
+ if sigma <= 0 {
+ // sigma parameter must be positive!
+ return Clone(img)
+ }
+
+ src := toNRGBA(img)
+ radius := int(math.Ceil(sigma * 3.0))
+ kernel := make([]float64, radius+1)
+
+ for i := 0; i <= radius; i++ {
+ kernel[i] = gaussianBlurKernel(float64(i), sigma)
+ }
+
+ var dst *image.NRGBA
+ dst = blurHorizontal(src, kernel)
+ dst = blurVertical(dst, kernel)
+
+ return dst
+}
+
+func blurHorizontal(src *image.NRGBA, kernel []float64) *image.NRGBA {
+ radius := len(kernel) - 1
+ width := src.Bounds().Max.X
+ height := src.Bounds().Max.Y
+
+ dst := image.NewNRGBA(image.Rect(0, 0, width, height))
+
+ parallel(width, func(partStart, partEnd int) {
+ for x := partStart; x < partEnd; x++ {
+ start := x - radius
+ if start < 0 {
+ start = 0
+ }
+
+ end := x + radius
+ if end > width-1 {
+ end = width - 1
+ }
+
+ weightSum := 0.0
+ for ix := start; ix <= end; ix++ {
+ weightSum += kernel[absint(x-ix)]
+ }
+
+ for y := 0; y < height; y++ {
+
+ r, g, b, a := 0.0, 0.0, 0.0, 0.0
+ for ix := start; ix <= end; ix++ {
+ weight := kernel[absint(x-ix)]
+ i := y*src.Stride + ix*4
+ r += float64(src.Pix[i+0]) * weight
+ g += float64(src.Pix[i+1]) * weight
+ b += float64(src.Pix[i+2]) * weight
+ a += float64(src.Pix[i+3]) * weight
+ }
+
+ r = math.Min(math.Max(r/weightSum, 0.0), 255.0)
+ g = math.Min(math.Max(g/weightSum, 0.0), 255.0)
+ b = math.Min(math.Max(b/weightSum, 0.0), 255.0)
+ a = math.Min(math.Max(a/weightSum, 0.0), 255.0)
+
+ j := y*dst.Stride + x*4
+ dst.Pix[j+0] = uint8(r + 0.5)
+ dst.Pix[j+1] = uint8(g + 0.5)
+ dst.Pix[j+2] = uint8(b + 0.5)
+ dst.Pix[j+3] = uint8(a + 0.5)
+
+ }
+ }
+ })
+
+ return dst
+}
+
+func blurVertical(src *image.NRGBA, kernel []float64) *image.NRGBA {
+ radius := len(kernel) - 1
+ 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++ {
+ start := y - radius
+ if start < 0 {
+ start = 0
+ }
+
+ end := y + radius
+ if end > height-1 {
+ end = height - 1
+ }
+
+ weightSum := 0.0
+ for iy := start; iy <= end; iy++ {
+ weightSum += kernel[absint(y-iy)]
+ }
+
+ for x := 0; x < width; x++ {
+
+ r, g, b, a := 0.0, 0.0, 0.0, 0.0
+ for iy := start; iy <= end; iy++ {
+ weight := kernel[absint(y-iy)]
+ i := iy*src.Stride + x*4
+ r += float64(src.Pix[i+0]) * weight
+ g += float64(src.Pix[i+1]) * weight
+ b += float64(src.Pix[i+2]) * weight
+ a += float64(src.Pix[i+3]) * weight
+ }
+
+ r = math.Min(math.Max(r/weightSum, 0.0), 255.0)
+ g = math.Min(math.Max(g/weightSum, 0.0), 255.0)
+ b = math.Min(math.Max(b/weightSum, 0.0), 255.0)
+ a = math.Min(math.Max(a/weightSum, 0.0), 255.0)
+
+ j := y*dst.Stride + x*4
+ dst.Pix[j+0] = uint8(r + 0.5)
+ dst.Pix[j+1] = uint8(g + 0.5)
+ dst.Pix[j+2] = uint8(b + 0.5)
+ dst.Pix[j+3] = uint8(a + 0.5)
+
+ }
+ }
+ })
+
+ return dst
+}
+
+// Sharpen produces a sharpened version of the image.
+// Sigma parameter must be positive and indicates how much the image will be sharpened.
+//
+// Usage example:
+//
+// dstImage := imaging.Sharpen(srcImage, 3.5)
+//
+func Sharpen(img image.Image, sigma float64) *image.NRGBA {
+ if sigma <= 0 {
+ // sigma parameter must be positive!
+ return Clone(img)
+ }
+
+ src := toNRGBA(img)
+ blurred := Blur(img, sigma)
+
+ 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
+ for j := 0; j < 4; j++ {
+ k := i + j
+ val := int(src.Pix[k]) + (int(src.Pix[k]) - int(blurred.Pix[k]))
+ if val < 0 {
+ val = 0
+ } else if val > 255 {
+ val = 255
+ }
+ dst.Pix[k] = uint8(val)
+ }
+ }
+ }
+ })
+
+ return dst
+}