Example #1
0
// Dissolve randomly selects pixels from the blend image, depending on their
// opacity. Blend pixels with higher opacities are more likely to be displayed.
func Dissolve(a, b image.Image) image.Image {
	ba := a.Bounds()
	bb := b.Bounds()
	width := int(utils.Min(uint32(ba.Dx()), uint32(bb.Dx())))
	height := int(utils.Min(uint32(ba.Dy()), uint32(bb.Dy())))

	result := image.NewRGBA(image.Rect(0, 0, width, height))

	for y := 0; y < height; y++ {
		for x := 0; x < width; x++ {
			// base colour
			rb, gb, bb, ab := utils.RatioRGBA(a.At(x, y))
			// blend colour
			rs, gs, bs, as := utils.RatioRGBA(b.At(x, y))

			toPaint := ratioNRGBA(rb, gb, bb, ab)

			if rand.Float64() < as {
				toPaint = ratioNRGBA(rs, gs, bs, 1)
			}

			result.Set(x, y, toPaint)
		}
	}

	return result
}
Example #2
0
// Addition adds the blend colour to the base colour. (aka. Linear Dodge)
func Addition(a, b image.Image) image.Image {
	return BlendPixels(a, b, func(c, d color.Color) color.Color {
		i, j, k, l := utils.NormalisedRGBA(c)
		m, n, o, p := utils.NormalisedRGBA(d)

		r := utils.Min(i+m, 255)
		g := utils.Min(j+n, 255)
		b := utils.Min(k+o, 255)
		a := utils.Min(l+p, 255)

		return color.NRGBA{uint8(r), uint8(g), uint8(b), uint8(a)}
	})
}
Example #3
0
// BlendPixels takes the base and blend images and applies the given Blender to
// each of their pixel pairs.
func BlendPixels(a, b image.Image, f Blender) image.Image {
	ba := a.Bounds()
	bb := b.Bounds()
	width := int(utils.Min(uint32(ba.Dx()), uint32(bb.Dx())))
	height := int(utils.Min(uint32(ba.Dy()), uint32(bb.Dy())))

	result := image.NewRGBA(image.Rect(0, 0, width, height))

	for y := 0; y < height; y++ {
		for x := 0; x < width; x++ {
			// Uses methods described in "PDF Reference, Third Edition" from Adobe
			//  see: http://www.adobe.com/devnet/pdf/pdf_reference_archive.html

			// backdrop colour
			cb := a.At(x, y)
			// source colour
			cs := b.At(x, y)
			// result colour
			cr := f(cb, cs)

			rb, gb, bb, ab := utils.RatioRGBA(cb)
			rs, gs, bs, as := utils.RatioRGBA(cs)
			rr, gr, br, _ := utils.RatioRGBA(cr)

			// Color compositing formula, expanded form. (Section 7.2.5)
			red := ((1 - as) * ab * rb) + ((1 - ab) * as * rs) + (ab * as * rr)
			green := ((1 - as) * ab * gb) + ((1 - ab) * as * gs) + (ab * as * gr)
			blue := ((1 - as) * ab * bb) + ((1 - ab) * as * bs) + (ab * as * br)

			// Union function. (Section 7.2.6)
			alpha := ab + as - (ab * as)

			result.Set(x, y, color.RGBA{
				uint8(utils.Truncatef(red * 255)),
				uint8(utils.Truncatef(green * 255)),
				uint8(utils.Truncatef(blue * 255)),
				uint8(utils.Truncatef(alpha * 255)),
			})
		}
	}

	return result
}
Example #4
0
func MinimalC() utils.Composable {
	return colorAlterer(func(r, g, b uint32) uint32 {
		return utils.Min(r, g, b)
	})
}
Example #5
0
func LightnessC() utils.Composable {
	return colorAlterer(func(r, g, b uint32) uint32 {
		return (utils.Max(r, g, b) + utils.Min(r, g, b)) / 2
	})
}