Documentation
¶
Overview ¶
Package accumimage provides support for images whose colors can be accumulated and averaged. It is based on the color types defined in accumimage/accumcolor. The core data types that accumimage defines are AccumNRGBA and AccumLabA, which implement the image.Image interface as well as most of the standard set of methods provided by the image package's image types. (AccumLabA lacks PixOffset.) In addition, each Accum____.Set* method has a corresponding Accum____.Add* method, which adds color to a pixel rather than replacing the pixel's color with a given color.
Example ¶
Scale down an arbitrary image (img) to given dimensions (newBnds), averaging colors that map to the same target pixel. The result is smoother than if newImg.Set were used instead of newImg.Add.
package main
import (
"image"
"image/png"
"log"
"os"
"github.com/spakin/accumimage"
)
// readImage reads an image from a named file.
func readImage(fn string) (image.Image, error) {
r, err := os.Open(fn)
if err != nil {
return nil, err
}
img, _, err := image.Decode(r)
if err != nil {
return nil, err
}
return img, nil
}
// writeImage writes an image to a named file in PNG format.
func writeImage(fn string, img image.Image) error {
w, err := os.Create(fn)
if err != nil {
return err
}
err = png.Encode(w, img)
return err
}
func main() {
// Read an image from a file.
if len(os.Args) != 2 {
return
}
img, err := readImage(os.Args[1])
if err != nil {
log.Fatal(err)
}
// Choose (arbitrarily) to scale to 1/3 of the size in each of x and y.
bnds := img.Bounds()
wd, ht := bnds.Dx(), bnds.Dy()
newBnds := image.Rect(0, 0, wd/3, ht/3)
// Create an AccumNRGBA image.
newImg := accumimage.NewAccumNRGBA(newBnds)
nwd, nht := newBnds.Dx(), newBnds.Dy()
// Copy the image pixel-by-pixel, from (x, y) in the input image to
// (nx, ny) in the output image.
for y := bnds.Min.Y; y < bnds.Max.Y; y++ {
ny := (nht*(y-bnds.Min.Y))/ht + newBnds.Min.Y
for x := bnds.Min.X; x < bnds.Max.X; x++ {
nx := (nwd*(x-bnds.Min.X))/wd + newBnds.Min.X
c := img.At(x, y)
newImg.Add(nx, ny, c) // Accumulate multiple colors into a single pixel.
}
}
// Write the downscaled image to a file.
err = writeImage("image.png", newImg)
if err != nil {
log.Fatal(err)
}
}
Output:
Index ¶
- type AccumLabA
- func (p *AccumLabA) AccumLabAAt(x, y int) accumcolor.AccumLabA
- func (p *AccumLabA) Add(x, y int, c color.Color)
- func (p *AccumLabA) AddAccumLabA(x, y int, c accumcolor.AccumLabA)
- func (p *AccumLabA) AddRGBA64(x, y int, c color.RGBA64)
- func (p *AccumLabA) At(x, y int) color.Color
- func (p *AccumLabA) Bounds() image.Rectangle
- func (p *AccumLabA) ColorModel() color.Model
- func (p *AccumLabA) ColorfulAt(x, y int) colorful.Color
- func (p *AccumLabA) Opaque() bool
- func (p *AccumLabA) RGBA64At(x, y int) color.RGBA64
- func (p *AccumLabA) Set(x, y int, c color.Color)
- func (p *AccumLabA) SetAccumLabA(x, y int, c accumcolor.AccumLabA)
- func (p *AccumLabA) SetRGBA64(x, y int, c color.RGBA64)
- func (p *AccumLabA) SubImage(r image.Rectangle) image.Image
- type AccumNRGBA
- func (p *AccumNRGBA) AccumNRGBAAt(x, y int) accumcolor.AccumNRGBA
- func (p *AccumNRGBA) Add(x, y int, c color.Color)
- func (p *AccumNRGBA) AddAccumNRGBA(x, y int, c accumcolor.AccumNRGBA)
- func (p *AccumNRGBA) AddRGBA64(x, y int, c color.RGBA64)
- func (p *AccumNRGBA) At(x, y int) color.Color
- func (p *AccumNRGBA) Bounds() image.Rectangle
- func (p *AccumNRGBA) ColorModel() color.Model
- func (p *AccumNRGBA) NRGBAAt(x, y int) color.NRGBA
- func (p *AccumNRGBA) Opaque() bool
- func (p *AccumNRGBA) PixOffset(x, y int) int
- func (p *AccumNRGBA) RGBA64At(x, y int) color.RGBA64
- func (p *AccumNRGBA) Set(x, y int, c color.Color)
- func (p *AccumNRGBA) SetAccumNRGBA(x, y int, c accumcolor.AccumNRGBA)
- func (p *AccumNRGBA) SetRGBA64(x, y int, c color.RGBA64)
- func (p *AccumNRGBA) SubImage(r image.Rectangle) image.Image
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AccumLabA ¶ added in v1.3.0
type AccumLabA struct {
// Pix holds the image's pixels. Pix[0][0] corresponds to (Rect.Min.X,
// Rect.Min.Y).
Pix [][]accumcolor.AccumLabA
// Rect is the image's bounds.
Rect image.Rectangle
}
An AccumLabA is an in-memory image whose At method returns accumcolor.AccumLabA values.
func NewAccumLabA ¶ added in v1.3.0
NewAccumLabA returns a new AccumLabA image with the given bounds.
func (*AccumLabA) AccumLabAAt ¶ added in v1.3.0
func (p *AccumLabA) AccumLabAAt(x, y int) accumcolor.AccumLabA
AccumLabAAt returns the color of the pixel at (x, y) as an accumcolor.AccumLabA.
func (*AccumLabA) Add ¶ added in v1.3.0
Add accumulates a given color of any type to the pixel at (x, y).
func (*AccumLabA) AddAccumLabA ¶ added in v1.3.0
func (p *AccumLabA) AddAccumLabA(x, y int, c accumcolor.AccumLabA)
AddAccumLabA accumulates a given color of type accumcolor.AccumLabA to the pixel at (x, y).
func (*AccumLabA) AddRGBA64 ¶ added in v1.3.0
AddRGBA64 accumulates a given color of type color.RGBA64 to the pixel at (x, y).
func (*AccumLabA) At ¶ added in v1.3.0
At returns the color of the pixel at (x, y) as a color.Color.
func (*AccumLabA) Bounds ¶ added in v1.3.0
Bounds returns the domain for which At can return non-zero color.
func (*AccumLabA) ColorModel ¶ added in v1.3.0
ColorModel returns the AccumLabA's color model (always accumcolor.AccumLabAModel).
func (*AccumLabA) ColorfulAt ¶ added in v1.3.0
ColorfulAt returns the color of the pixel at (x, y) as a fully opaque colorful.Color (from the go-colorful package).
func (*AccumLabA) Opaque ¶ added in v1.3.0
Opaque scans the entire image and reports whether it is fully opaque.
func (*AccumLabA) RGBA64At ¶ added in v1.3.0
RGBA64At returns the color of the pixel at (x, y) as a color.RGBA64.
func (*AccumLabA) SetAccumLabA ¶ added in v1.3.0
func (p *AccumLabA) SetAccumLabA(x, y int, c accumcolor.AccumLabA)
SetAccumLabA sets the pixel at (x, y) to a given color of type accumcolor.AccumLabA.
type AccumNRGBA ¶
type AccumNRGBA struct {
// Pix holds the image's pixels, in R, G, B, A, Tally order. The pixel
// at (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*5].
Pix []uint64
// Stride is the Pix stride (in uint64s) between vertically adjacent
// pixels.
Stride int
// Rect is the image's bounds.
Rect image.Rectangle
}
An AccumNRGBA is an in-memory image whose At method returns accumcolor.NRGBA values.
func NewAccumNRGBA ¶
func NewAccumNRGBA(r image.Rectangle) *AccumNRGBA
NewAccumNRGBA returns a new AccumNRGBA image with the given bounds.
func (*AccumNRGBA) AccumNRGBAAt ¶
func (p *AccumNRGBA) AccumNRGBAAt(x, y int) accumcolor.AccumNRGBA
AccumNRGBAAt returns the color of the pixel at (x, y) as an accumcolor.AccumNRGBA.
func (*AccumNRGBA) Add ¶
func (p *AccumNRGBA) Add(x, y int, c color.Color)
Add accumulates a given color of any type to the pixel at (x, y).
Example ¶
Blend two images to produce a third image.
package main
import (
"image"
"image/png"
"log"
"os"
"github.com/spakin/accumimage"
)
// readImage reads an image from a named file.
func readImage(fn string) (image.Image, error) {
r, err := os.Open(fn)
if err != nil {
return nil, err
}
img, _, err := image.Decode(r)
if err != nil {
return nil, err
}
return img, nil
}
// writeImage writes an image to a named file in PNG format.
func writeImage(fn string, img image.Image) error {
w, err := os.Create(fn)
if err != nil {
return err
}
err = png.Encode(w, img)
return err
}
func main() {
// Read two images from files.
if len(os.Args) != 3 {
return
}
imgA, err := readImage(os.Args[1])
if err != nil {
log.Fatal(err)
}
imgB, err := readImage(os.Args[2])
if err != nil {
log.Fatal(err)
}
// Create an AccumNRGBA image imgC that's large enough to hold the
// overlap of input images imgA and imgB.
bndsA := imgA.Bounds()
bndsB := imgB.Bounds()
bndsC := bndsA.Union(bndsB)
imgC := accumimage.NewAccumNRGBA(bndsC)
// Blend image A with image C.
for y := bndsA.Min.Y; y < bndsA.Max.Y; y++ {
for x := bndsA.Min.X; x < bndsA.Max.X; x++ {
imgC.Add(x, y, imgA.At(x, y))
}
}
// Blend image B with image C.
for y := bndsB.Min.Y; y < bndsB.Max.Y; y++ {
for x := bndsB.Min.X; x < bndsB.Max.X; x++ {
imgC.Add(x, y, imgB.At(x, y))
}
}
// Write the blended image to a file.
err = writeImage("image.png", imgC)
if err != nil {
log.Fatal(err)
}
}
Output:
func (*AccumNRGBA) AddAccumNRGBA ¶
func (p *AccumNRGBA) AddAccumNRGBA(x, y int, c accumcolor.AccumNRGBA)
AddAccumNRGBA accumulates a given color of type accumcolor.AccumNRGBA to the pixel at (x, y).
func (*AccumNRGBA) AddRGBA64 ¶
func (p *AccumNRGBA) AddRGBA64(x, y int, c color.RGBA64)
AddRGBA64 accumulates a given color of type color.RGBA64 to the pixel at (x, y).
func (*AccumNRGBA) At ¶
func (p *AccumNRGBA) At(x, y int) color.Color
At returns the color of the pixel at (x, y) as a color.Color.
func (*AccumNRGBA) Bounds ¶
func (p *AccumNRGBA) Bounds() image.Rectangle
Bounds returns the domain for which At can return non-zero color.
func (*AccumNRGBA) ColorModel ¶
func (p *AccumNRGBA) ColorModel() color.Model
ColorModel returns the AccumNRGBA's color model (always accumcolor.AccumNRGBAModel).
func (*AccumNRGBA) NRGBAAt ¶
func (p *AccumNRGBA) NRGBAAt(x, y int) color.NRGBA
NRGBAAt returns the color of the pixel at (x, y) as a color.NRGBA.
func (*AccumNRGBA) Opaque ¶
func (p *AccumNRGBA) Opaque() bool
Opaque scans the entire image and reports whether it is fully opaque.
func (*AccumNRGBA) PixOffset ¶
func (p *AccumNRGBA) PixOffset(x, y int) int
PixOffset returns the index of the first element of Pix that corresponds to the pixel at (x, y).
func (*AccumNRGBA) RGBA64At ¶
func (p *AccumNRGBA) RGBA64At(x, y int) color.RGBA64
RGBA64At returns the color of the pixel at (x, y) as a color.RGBA64.
func (*AccumNRGBA) Set ¶
func (p *AccumNRGBA) Set(x, y int, c color.Color)
Set sets the pixel at (x, y) to a given color of any type.
func (*AccumNRGBA) SetAccumNRGBA ¶
func (p *AccumNRGBA) SetAccumNRGBA(x, y int, c accumcolor.AccumNRGBA)
SetAccumNRGBA sets the pixel at (x, y) to a given color of type accumcolor.AccumNRGBA.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package accumcolor provides support for colors that can be accumulated and averaged.
|
Package accumcolor provides support for colors that can be accumulated and averaged. |