Skip to content

Commit

Permalink
Merge pull request #81 from BluePsyduck/export-blend
Browse files Browse the repository at this point in the history
Make blend() exported to allow for custom blending implementations.
  • Loading branch information
anthonynsimon authored Apr 22, 2020
2 parents e55edda + 12e9426 commit c58fb61
Showing 1 changed file with 18 additions and 18 deletions.
36 changes: 18 additions & 18 deletions blend/blend.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
// Normal combines the foreground and background images by placing the foreground over the
// background using alpha compositing. The resulting image is then returned.
func Normal(bg image.Image, fg image.Image) *image.RGBA {
dst := blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
dst := Blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
return alphaComp(c0, c1)
})

Expand All @@ -24,7 +24,7 @@ func Normal(bg image.Image, fg image.Image) *image.RGBA {
// Add combines the foreground and background images by adding their values and
// returns the resulting image.
func Add(bg image.Image, fg image.Image) *image.RGBA {
dst := blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
dst := Blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
r := c0.R + c1.R
g := c0.G + c1.G
b := c0.B + c1.B
Expand All @@ -39,7 +39,7 @@ func Add(bg image.Image, fg image.Image) *image.RGBA {
// Multiply combines the foreground and background images by multiplying their
// normalized values and returns the resulting image.
func Multiply(bg image.Image, fg image.Image) *image.RGBA {
dst := blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
dst := Blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
r := c0.R * c1.R
g := c0.G * c1.G
b := c0.B * c1.B
Expand All @@ -54,7 +54,7 @@ func Multiply(bg image.Image, fg image.Image) *image.RGBA {
// Overlay combines the foreground and background images by using Multiply when channel values < 0.5
// or using Screen otherwise and returns the resulting image.
func Overlay(bg image.Image, fg image.Image) *image.RGBA {
dst := blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
dst := Blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
var r, g, b float64
if c0.R > 0.5 {
r = 1 - (1-2*(c0.R-0.5))*(1-c1.R)
Expand Down Expand Up @@ -82,7 +82,7 @@ func Overlay(bg image.Image, fg image.Image) *image.RGBA {
// SoftLight combines the foreground and background images by using Pegtop's Soft Light formula and
// returns the resulting image.
func SoftLight(bg image.Image, fg image.Image) *image.RGBA {
dst := blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
dst := Blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
r := (1-2*c1.R)*c0.R*c0.R + 2*c0.R*c1.R
g := (1-2*c1.G)*c0.G*c0.G + 2*c0.G*c1.G
b := (1-2*c1.B)*c0.B*c0.B + 2*c0.B*c1.B
Expand All @@ -96,7 +96,7 @@ func SoftLight(bg image.Image, fg image.Image) *image.RGBA {
// Screen combines the foreground and background images by inverting, multiplying and inverting the output.
// The result is a brighter image which is then returned.
func Screen(bg image.Image, fg image.Image) *image.RGBA {
dst := blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
dst := Blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
r := 1 - (1-c0.R)*(1-c1.R)
g := 1 - (1-c0.G)*(1-c1.G)
b := 1 - (1-c0.B)*(1-c1.B)
Expand All @@ -111,7 +111,7 @@ func Screen(bg image.Image, fg image.Image) *image.RGBA {
// Difference calculates the absolute difference between the foreground and background images and
// returns the resulting image.
func Difference(bg image.Image, fg image.Image) *image.RGBA {
dst := blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
dst := Blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
r := math.Abs(c0.R - c1.R)
g := math.Abs(c0.G - c1.G)
b := math.Abs(c0.B - c1.B)
Expand All @@ -126,7 +126,7 @@ func Difference(bg image.Image, fg image.Image) *image.RGBA {
// Divide combines the foreground and background images by diving the values from the background
// by the foreground and returns the resulting image.
func Divide(bg image.Image, fg image.Image) *image.RGBA {
dst := blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
dst := Blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
var r, g, b float64
if c1.R == 0 {
r = 1
Expand Down Expand Up @@ -154,7 +154,7 @@ func Divide(bg image.Image, fg image.Image) *image.RGBA {
// ColorBurn combines the foreground and background images by dividing the inverted
// background by the foreground image and then inverting the result which is then returned.
func ColorBurn(bg image.Image, fg image.Image) *image.RGBA {
dst := blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
dst := Blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
var r, g, b float64
if c1.R == 0 {
r = 0
Expand Down Expand Up @@ -182,7 +182,7 @@ func ColorBurn(bg image.Image, fg image.Image) *image.RGBA {
// Exclusion combines the foreground and background images applying the Exclusion blend mode and
// returns the resulting image.
func Exclusion(bg image.Image, fg image.Image) *image.RGBA {
dst := blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
dst := Blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
r := 0.5 - 2*(c0.R-0.5)*(c1.R-0.5)
g := 0.5 - 2*(c0.G-0.5)*(c1.G-0.5)
b := 0.5 - 2*(c0.B-0.5)*(c1.B-0.5)
Expand All @@ -198,7 +198,7 @@ func Exclusion(bg image.Image, fg image.Image) *image.RGBA {
// ColorDodge combines the foreground and background images by dividing background by the
// inverted foreground image and returns the result.
func ColorDodge(bg image.Image, fg image.Image) *image.RGBA {
dst := blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
dst := Blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
var r, g, b float64
if c1.R == 1 {
r = 1
Expand Down Expand Up @@ -226,7 +226,7 @@ func ColorDodge(bg image.Image, fg image.Image) *image.RGBA {
// LinearBurn combines the foreground and background images by adding them and
// then subtracting 255 (1.0 in normalized scale). The resulting image is then returned.
func LinearBurn(bg image.Image, fg image.Image) *image.RGBA {
dst := blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
dst := Blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
r := c0.R + c1.R - 1
g := c0.G + c1.G - 1
b := c0.B + c1.B - 1
Expand All @@ -241,7 +241,7 @@ func LinearBurn(bg image.Image, fg image.Image) *image.RGBA {
// LinearLight combines the foreground and background images by a mix of a Linear Dodge and
// Linear Burn operation. The resulting image is then returned.
func LinearLight(bg image.Image, fg image.Image) *image.RGBA {
dst := blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
dst := Blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
var r, g, b float64
if c1.R > 0.5 {
r = c0.R + 2*c1.R - 0.5
Expand Down Expand Up @@ -269,7 +269,7 @@ func LinearLight(bg image.Image, fg image.Image) *image.RGBA {
// Subtract combines the foreground and background images by Subtracting the background from the
// foreground. The result is then returned.
func Subtract(bg image.Image, fg image.Image) *image.RGBA {
dst := blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
dst := Blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
r := c1.R - c0.R
g := c1.G - c0.G
b := c1.B - c0.B
Expand All @@ -286,7 +286,7 @@ func Subtract(bg image.Image, fg image.Image) *image.RGBA {
func Opacity(bg image.Image, fg image.Image, percent float64) *image.RGBA {
percent = f64.Clamp(percent, 0, 1.0)

dst := blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
dst := Blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
r := c1.R*percent + (1-percent)*c0.R
g := c1.G*percent + (1-percent)*c0.G
b := c1.B*percent + (1-percent)*c0.B
Expand All @@ -301,7 +301,7 @@ func Opacity(bg image.Image, fg image.Image, percent float64) *image.RGBA {
// Darken combines the foreground and background images by picking the darkest value per channel
// for each pixel. The result is then returned.
func Darken(bg image.Image, fg image.Image) *image.RGBA {
dst := blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
dst := Blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
r := math.Min(c0.R, c1.R)
g := math.Min(c0.G, c1.G)
b := math.Min(c0.B, c1.B)
Expand All @@ -316,7 +316,7 @@ func Darken(bg image.Image, fg image.Image) *image.RGBA {
// Lighten combines the foreground and background images by picking the brightest value per channel
// for each pixel. The result is then returned.
func Lighten(bg image.Image, fg image.Image) *image.RGBA {
dst := blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
dst := Blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
r := math.Max(c0.R, c1.R)
g := math.Max(c0.G, c1.G)
b := math.Max(c0.B, c1.B)
Expand All @@ -331,7 +331,7 @@ func Lighten(bg image.Image, fg image.Image) *image.RGBA {
// Blend two images together by applying the provided function for each pixel.
// If images differ in size, the minimum width and height will be picked from each one
// when creating the resulting image.
func blend(bg image.Image, fg image.Image, fn func(fcolor.RGBAF64, fcolor.RGBAF64) fcolor.RGBAF64) *image.RGBA {
func Blend(bg image.Image, fg image.Image, fn func(fcolor.RGBAF64, fcolor.RGBAF64) fcolor.RGBAF64) *image.RGBA {
bgBounds := bg.Bounds()
fgBounds := fg.Bounds()

Expand Down

0 comments on commit c58fb61

Please sign in to comment.