dither

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 26, 2023 License: MPL-2.0 Imports: 7 Imported by: 1

README

dither (modified for Gopy)

This is a modified version of dither Go library, made specifically to ease up process of writting bindings with Gopy.

Note If you are looking for Python bindings of dither library, check out dither-go repository.

Limitations:

  • PixelMapper type and assosiated with this type functions are privated, as they aren't currently supported by Gopy
    (related PR: https://github.com/go-python/gopy/pull/282)
  • You can't reuse generated PixelMapper assosiated functions, because of above limitation
  • Any function that returnes more that one return value, is either privated or ignored during binding generation

Changed structures:

  • pixelmappers.go:
    • PixelMapper type privated
    • RandomNoiseGrayscale, RandomNoiseRGB, Bayer and PixelMapperFromMatrix functions privated
  • dither.go:
    • Mapper field in Ditherer struct privated
    • New SetBayer, SetOrdered, SetRandomGrayscale, SetRandomRGB and ClearMapper helper functions

TODO:

  • Make a struct for *Config and Offset functions allowing to return multiple values using only one return value

License

This repository is licensed under the same terms as the original library, which is licensed under the Mozilla Public License Version 2.0.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Atkinson = ErrorDiffusionMatrix{
	{0, 0, 1.0 / 8, 1.0 / 8},
	{1.0 / 8, 1.0 / 8, 1.0 / 8, 0},
	{0, 1.0 / 8, 0, 0},
}
View Source
var Burkes = ErrorDiffusionMatrix{
	{0, 0, 0, 8.0 / 32, 4.0 / 32},
	{2.0 / 32, 4.0 / 32, 8.0 / 32, 4.0 / 32, 2.0 / 32},
}
View Source
var ClusteredDot4x4 = OrderedDitherMatrix{
	Matrix: [][]uint{
		{12, 5, 6, 13},
		{4, 0, 1, 7},
		{11, 3, 2, 8},
		{15, 10, 9, 14},
	},
	Max: 16,
}

ClusteredDot4x4 comes from http://caca.zoy.org/study/part2.html

It is not diagonal, so the dots form a grid.

View Source
var ClusteredDot6x6 = OrderedDitherMatrix{
	Matrix: [][]uint{

		{34, 29, 17, 21, 30, 35},
		{28, 14, 9, 16, 20, 31},
		{13, 8, 4, 5, 15, 19},
		{12, 3, 0, 1, 10, 18},
		{27, 7, 2, 6, 23, 24},
		{33, 26, 11, 22, 25, 32},
	},
	Max: 36,
}

ClusteredDot6x6 comes from Figure 5.9 of the book Digital Halftoning by Robert Ulichney. It can represent "37 levels of gray". It is not diagonal.

View Source
var ClusteredDot6x6_2 = OrderedDitherMatrix{
	Matrix: [][]uint{
		{34, 25, 21, 17, 29, 33},
		{30, 13, 9, 5, 12, 24},
		{18, 6, 1, 0, 8, 20},
		{22, 10, 2, 3, 4, 16},
		{26, 14, 7, 11, 15, 28},
		{35, 31, 19, 23, 27, 32},
	},
	Max: 36,
}

ClusteredDot6x6_2 comes from https://archive.is/71e9G. On the webpage it is called "central white point" while ClusteredDot6x6 is called "clustered dots".

It is nearly identical to ClusteredDot6x6.

View Source
var ClusteredDot6x6_3 = OrderedDitherMatrix{
	Matrix: [][]uint{
		{30, 22, 16, 21, 33, 35},
		{24, 11, 7, 9, 26, 28},
		{13, 5, 0, 2, 14, 19},
		{15, 3, 1, 4, 12, 18},
		{27, 8, 6, 10, 25, 29},
		{32, 20, 17, 23, 31, 34},
	},
	Max: 36,
}

ClusteredDot6x6_3 comes from https://archive.is/71e9G. On the webpage it is called "balanced centered point".

It is nearly identical to ClusteredDot6x6.

View Source
var ClusteredDot8x8 = OrderedDitherMatrix{
	Matrix: [][]uint{

		{3, 9, 17, 27, 25, 15, 7, 1},
		{11, 29, 38, 46, 44, 36, 23, 5},
		{19, 40, 52, 58, 56, 50, 34, 13},
		{31, 48, 60, 63, 62, 54, 42, 21},
		{30, 47, 59, 63, 61, 53, 41, 20},
		{18, 39, 51, 57, 55, 49, 33, 12},
		{10, 28, 37, 45, 43, 35, 22, 4},
		{2, 8, 16, 26, 24, 14, 6, 0},
	},
	Max: 64,
}

ClusteredDot8x8 comes from Figure 1.5 of the book Modern Digital Halftoning, Second Edition, by Daniel L. Lau and Gonzalo R. Arce. It is like ClusteredDotDiagonal8x8, but is not diagonal. It can represent "65 gray-levels".

View Source
var ClusteredDotDiagonal16x16 = OrderedDitherMatrix{
	Matrix: [][]uint{

		{63, 58, 50, 40, 41, 51, 59, 60, 64, 69, 77, 87, 86, 76, 68, 67},
		{57, 33, 27, 18, 19, 28, 34, 52, 70, 94, 100, 109, 108, 99, 93, 75},
		{49, 26, 13, 11, 12, 15, 29, 44, 78, 101, 114, 116, 115, 112, 98, 83},
		{39, 17, 4, 3, 2, 9, 20, 42, 87, 110, 123, 124, 125, 118, 107, 85},
		{38, 16, 5, 0, 1, 10, 21, 43, 89, 111, 122, 127, 126, 117, 106, 84},
		{48, 25, 8, 6, 7, 14, 30, 45, 79, 102, 119, 121, 120, 113, 97, 82},
		{56, 32, 24, 23, 22, 31, 35, 53, 71, 95, 103, 104, 105, 96, 92, 74},
		{62, 55, 47, 37, 36, 46, 54, 61, 65, 72, 80, 90, 91, 81, 73, 66},
		{64, 69, 77, 87, 86, 76, 68, 67, 63, 58, 50, 40, 41, 51, 59, 60},
		{70, 94, 100, 109, 108, 99, 93, 75, 57, 33, 27, 18, 19, 28, 34, 52},
		{78, 101, 114, 116, 115, 112, 98, 83, 49, 26, 13, 11, 12, 15, 29, 44},
		{87, 110, 123, 124, 125, 118, 107, 85, 39, 17, 4, 3, 2, 9, 20, 42},
		{89, 111, 122, 127, 126, 117, 106, 84, 38, 16, 5, 0, 1, 10, 21, 43},
		{79, 102, 119, 121, 120, 113, 97, 82, 48, 25, 8, 6, 7, 14, 30, 45},
		{71, 95, 103, 104, 105, 96, 92, 74, 56, 32, 24, 23, 22, 31, 35, 53},
		{65, 72, 80, 90, 91, 81, 73, 66, 62, 55, 47, 37, 36, 46, 54, 61},
	},
	Max: 128,
}

ClusteredDotDiagonal16x16 comes from Figure 5.4 of the book Digital Halftoning by Robert Ulichney. In the book it's called "M = 8". It can represent "129 levels of gray". Its dimensions are 16x16, but as a diagonal matrix it is 17x17. It is called "Diagonal" because the resulting dot pattern is at a 45 degree angle.

View Source
var ClusteredDotDiagonal6x6 = OrderedDitherMatrix{
	Matrix: [][]uint{

		{8, 6, 7, 9, 11, 10},
		{5, 0, 1, 12, 17, 16},
		{4, 3, 2, 13, 14, 15},
		{9, 11, 10, 8, 6, 8},
		{12, 17, 16, 5, 0, 1},
		{13, 14, 15, 4, 3, 2},
	},
	Max: 18,
}

ClusteredDotDiagonal6x6 comes from Figure 5.4 of the book Digital Halftoning by Robert Ulichney. In the book it's called "M = 3". It can represent "19 levels of gray". Its dimensions are 6x6, but as a diagonal matrix it is 7x7. It is called "Diagonal" because the resulting dot pattern is at a 45 degree angle.

View Source
var ClusteredDotDiagonal8x8 = OrderedDitherMatrix{
	Matrix: [][]uint{
		{24, 10, 12, 26, 35, 47, 49, 37},
		{8, 0, 2, 14, 45, 59, 61, 51},
		{22, 6, 4, 16, 43, 57, 63, 53},
		{30, 20, 18, 28, 33, 41, 55, 39},
		{34, 46, 48, 36, 25, 11, 13, 27},
		{44, 58, 60, 50, 9, 1, 3, 15},
		{42, 56, 62, 52, 23, 7, 5, 17},
		{32, 40, 54, 38, 31, 21, 19, 29},
	},
	Max: 64,
}

ClusteredDotDiagonal8x8 comes from http://caca.zoy.org/study/part2.html

They say it "mimics the halftoning techniques used by newspapers". It is called "Diagonal" because the resulting dot pattern is at a 45 degree angle.

View Source
var ClusteredDotDiagonal8x8_2 = OrderedDitherMatrix{
	Matrix: [][]uint{

		{13, 11, 12, 15, 18, 20, 19, 16},
		{4, 3, 2, 9, 27, 28, 29, 22},
		{5, 0, 1, 10, 26, 31, 30, 21},
		{8, 6, 7, 14, 23, 25, 24, 17},
		{18, 20, 19, 16, 13, 11, 12, 15},
		{27, 28, 29, 22, 4, 3, 2, 9},
		{26, 31, 30, 21, 5, 0, 1, 10},
		{23, 25, 24, 17, 8, 6, 7, 14},
	},
	Max: 32,
}

ClusteredDotDiagonal8x8_2 comes from Figure 5.4 of the book Digital Halftoning by Robert Ulichney. In the book it's called "M = 4". It can represent "33 levels of gray". Its dimensionsare 8x8, but as a diagonal matrix it is 9x9. It is called "Diagonal" because the resulting dot pattern is at a 45 degree angle.

It is almost identical to ClusteredDotDiagonal8x8, but worse because it can represent fewer gray levels. There is not much point in using it.

View Source
var ClusteredDotDiagonal8x8_3 = OrderedDitherMatrix{
	Matrix: [][]uint{

		{13, 9, 5, 12, 18, 22, 26, 19},
		{6, 1, 0, 8, 25, 30, 31, 23},
		{10, 2, 3, 4, 21, 29, 28, 27},
		{14, 7, 11, 15, 17, 24, 20, 16},
		{18, 22, 26, 19, 13, 9, 5, 12},
		{25, 30, 31, 23, 6, 1, 0, 8},
		{21, 29, 28, 27, 10, 2, 3, 4},
		{17, 24, 20, 16, 14, 7, 11, 15},
	},
	Max: 32,
}

ClusteredDotDiagonal8x8_3 comes from https://archive.is/71e9G. On the webpage it is called "diagonal ordered matrix with balanced centered points".

It is almost identical to ClusteredDotDiagonal8x8, but worse because it can represent fewer gray levels. There is not much point in using it.

It is called "Diagonal" because the resulting dot pattern is at a 45 degree angle.

View Source
var ClusteredDotHorizontalLine = OrderedDitherMatrix{
	Matrix: [][]uint{

		{35, 33, 31, 30, 32, 34},
		{23, 21, 19, 18, 20, 22},
		{11, 9, 7, 6, 8, 10},
		{5, 3, 1, 0, 2, 4},
		{17, 15, 13, 12, 14, 16},
		{29, 27, 25, 24, 26, 28},
	},
	Max: 36,
}

ClusteredDotHorizontalLine comes from Figure 5.13 of the book Digital Halftoning by Robert Ulichney. It can represent "37 levels of gray". Its dimensions are 6x6.

It "clusters pixels about horizontal lines".

View Source
var ClusteredDotSpiral5x5 = OrderedDitherMatrix{
	Matrix: [][]uint{

		{20, 21, 22, 23, 24},
		{19, 6, 7, 8, 9},
		{18, 5, 0, 1, 10},
		{17, 4, 3, 2, 11},
		{16, 15, 14, 13, 12},
	},
	Max: 25,
}

ClusteredDotSpiral5x5 comes from Figure 5.13 of the book Digital Halftoning by Robert Ulichney. It can represent "26 levels of gray". Its dimensions are 5x5.

Instead of alternating dark and light dots like the other clustered-dot matrices, the dark parts grow to fill the area.

View Source
var ClusteredDotVerticalLine = OrderedDitherMatrix{
	Matrix: [][]uint{
		{35, 23, 11, 5, 17, 29},
		{33, 21, 9, 3, 15, 27},
		{31, 19, 7, 1, 13, 25},
		{30, 18, 6, 0, 12, 24},
		{32, 20, 8, 2, 14, 26},
		{34, 22, 10, 4, 16, 28},
	},
	Max: 36,
}

ClusteredDotVerticalLine is my rotated version of ClusteredDotHorizontalLine.

View Source
var FalseFloydSteinberg = ErrorDiffusionMatrix{
	{0, 3.0 / 8},
	{3.0 / 8, 2.0 / 8},
}
View Source
var FloydSteinberg = ErrorDiffusionMatrix{
	{0, 0, 7.0 / 16},
	{3.0 / 16, 5.0 / 16, 1.0 / 16},
}
View Source
var Horizontal3x5 = OrderedDitherMatrix{
	Matrix: [][]uint{
		{9, 10, 11},
		{3, 4, 5},
		{0, 1, 2},
		{6, 7, 8},
		{12, 13, 14},
	},
	Max: 15,
}

Horizontal3x5 is my rotated version of Vertical5x3.

View Source
var JarvisJudiceNinke = ErrorDiffusionMatrix{
	{0, 0, 0, 7.0 / 48, 5.0 / 48},
	{3.0 / 48, 5.0 / 48, 7.0 / 48, 5.0 / 48, 3.0 / 48},
	{1.0 / 48, 3.0 / 48, 5.0 / 48, 3.0 / 48, 1.0 / 48},
}
View Source
var Sierra = ErrorDiffusionMatrix{
	{0, 0, 0, 5.0 / 32, 3.0 / 32},
	{2.0 / 32, 4.0 / 32, 5.0 / 32, 4.0 / 32, 2.0 / 32},
	{0, 2.0 / 32, 3.0 / 32, 2.0 / 32, 0},
}
View Source
var Sierra2 = TwoRowSierra

Sierra2 is another name for TwoRowSierra

View Source
var Sierra2_4A = SierraLite

Sierra2_4A (usually written as Sierra2-4A) is another name for SierraLite.

View Source
var Sierra3 = Sierra

Sierra3 is another name for the original Sierra matrix.

View Source
var SierraLite = ErrorDiffusionMatrix{
	{0, 0, 2.0 / 4},
	{1.0 / 4, 1.0 / 4, 0},
}
View Source
var Simple2D = ErrorDiffusionMatrix{
	{0, 0.5},
	{0.5, 0},
}
View Source
var StevenPigeon = ErrorDiffusionMatrix{
	{0, 0, 0, 2.0 / 14, 1.0 / 14},
	{0, 2.0 / 14, 2.0 / 14, 2.0 / 14, 0},
	{1.0 / 14, 0, 1.0 / 14, 0, 1.0 / 14},
}

StevenPigeon is an error diffusion matrix developed by Steven Pigeon. Source: https://hbfs.wordpress.com/2013/12/31/dithering/

View Source
var Stucki = ErrorDiffusionMatrix{
	{0, 0, 0, 8.0 / 42, 4.0 / 42},
	{2.0 / 42, 4.0 / 42, 8.0 / 42, 4.0 / 42, 2.0 / 42},
	{1.0 / 42, 2.0 / 42, 4.0 / 42, 2.0 / 42, 1.0 / 42},
}
View Source
var TwoRowSierra = ErrorDiffusionMatrix{
	{0, 0, 0, 4.0 / 16, 3.0 / 16},
	{1.0 / 16, 2.0 / 16, 3.0 / 16, 2.0 / 16, 1.0 / 16},
}
View Source
var Vertical5x3 = OrderedDitherMatrix{
	Matrix: [][]uint{
		{9, 3, 0, 6, 12},
		{10, 4, 1, 7, 13},
		{11, 5, 2, 8, 14},
	},
	Max: 15,
}

Vertical5x3 comes from http://caca.zoy.org/study/part2.html

They say it "creates artistic vertical line artifacts".

Functions

func RoundClamp

func RoundClamp(i float32) uint16

RoundClamp clamps the number and rounds it, rounding ties to the nearest even number. This should be used if you're writing your own PixelMapper.

Types

type Ditherer

type Ditherer struct {

	// Matrix is the ErrorDiffusionMatrix for dithering.
	Matrix ErrorDiffusionMatrix

	// Special is the special dithering algorithm that's being used. The default
	// value of 0 indicates that no special dithering algorithm is being used.
	Special SpecialDither

	// SingleThreaded controls whether the dithering happens sequentially or using
	// runtime.GOMAXPROCS(0) workers, which defaults to the number of CPUs.
	//
	// Note that error diffusion dithering (using Matrix) is sequential by nature
	// and so this field has no effect.
	//
	// Setting this to true is only useful in rare cases, like when numbers are
	// used sequentially in a PixelMapper, and the output must be deterministic.
	// Because otherwise the numbers will be retrieved in a different order each
	// time, as the goroutines call on the PixelMapper.
	SingleThreaded bool

	// Serpentine controls whether the error diffusion matrix is applied in a
	// serpentine manner, meaning that it goes right-to-left every other line.
	// This greatly reduces line-type artifacts. If a Mapper is being used this
	// field will have no effect.
	Serpentine bool
	// contains filtered or unexported fields
}

Ditherer dithers images according to the settings in the struct. It can be safely reused for many images, and used concurrently.

Some members of the struct are public. Those members can be changed in-between dithering images, if you would like to dither again. If you change those public methods while an image is being dithered, the output image will have problems, so only change in-between dithering.

You can only set one of Matrix, Mapper, or Special. Trying to dither when none or more than one of those are set will cause the function to panic.

All methods can handle images with transparency, unless otherwise specified. Read the docs before using!

func NewDitherer

func NewDitherer(palette []color.Color) *Ditherer

NewDitherer creates a new Ditherer that uses a copy of the provided palette. If the palette is empty or nil then nil will be returned. All palette colors should be opaque.

func (*Ditherer) ClearMapper

func (d *Ditherer) ClearMapper()

ClearMapper clears out Mapper field of Ditherer struct. Useful if you want to reuse Ditherer object for the next dithering.

func (*Ditherer) Dither

func (d *Ditherer) Dither(src image.Image) image.Image

Dither dithers the provided image.

It will always try to change the provided image and return it, but if that is not possible it will return the dithered image as a copy.

In comparison to DitherCopy, this can greatly reduce memory usage, and is quicker because it usually won't copy the image at the beginning. It should be preferred if you don't need to keep the original image.

Cases where a copy will be are limited to: If the input image is *image.Paletted and the image's palette is different than the Ditherer's, or if the image can't be casted to draw.Image.

The returned image type when copied is *image.RGBA. But it may be different if the image wasn't copied.

func (*Ditherer) DitherConfig

func (d *Ditherer) DitherConfig(src draw.Image) (image.Image, image.Config)

DitherConfig is like Dither, but returns an image.Config as well.

func (*Ditherer) DitherCopy

func (d *Ditherer) DitherCopy(src image.Image) *image.RGBA

DitherCopy dithers a copy of the src image and returns it. The src image remains unchanged. If you don't need to keep the original image, use Dither.

func (*Ditherer) DitherCopyConfig

func (d *Ditherer) DitherCopyConfig(src image.Image) (*image.RGBA, image.Config)

DitherCopyConfig is like DitherCopy, but returns an image.Config as well.

func (*Ditherer) DitherPaletted

func (d *Ditherer) DitherPaletted(src image.Image) *image.Paletted

DitherPaletted dithers a copy of the src image and returns it as an *image.Paletted. The src image remains unchanged. If you don't need an *image.Paletted, using Dither or DitherCopy should be preferred.

The palette of the returned image is the same palette the ditherer uses internally -- it will be equal to the output of GetPalette().

If the Ditherer's palette has over 256 colors then the function will panic, because *image.Paletted does not allow for that.

DitherPaletted can't handle images with transparency.

func (*Ditherer) DitherPalettedConfig

func (d *Ditherer) DitherPalettedConfig(src image.Image) (*image.Paletted, image.Config)

DitherPalettedConfig is like DitherPaletted, but returns an image.Config as well.

DitherPalettedConfig can't handle images with transparency.

func (*Ditherer) Draw

func (d *Ditherer) Draw(dst draw.Image, r image.Rectangle, src image.Image, sp image.Point)

Draw implements draw.Drawer. This means you can use a Ditherer in many places, such as for encoding GIFs.

Draw ignores whether dst has a palette or not, and just uses the internal Ditherer palette. If the dst image passed has a palette (i.e. is of the type *image.Paletted), and the palette is the not the same as the Ditherer's palette, it will panic.

func (*Ditherer) GetColorModel

func (d *Ditherer) GetColorModel() color.Model

GetColorModel returns a copy of the Ditherer's palette as a color.Model that finds the closest color using Euclidean distance in sRGB space.

func (*Ditherer) GetPalette

func (d *Ditherer) GetPalette() []color.Color

GetPalette returns a copy of the current palette being used by the Ditherer.

func (*Ditherer) Quantize

func (d *Ditherer) Quantize(p color.Palette, m image.Image) color.Palette

Quantize implements draw.Quantizer. It ignores the provided image and just returns the Ditherer's palette each time. This is useful for places that only allow you to set the palette through a draw.Quantizer, like the image/gif package.

This function will panic if the Ditherer's palette has more colors than the caller wants, which the caller indicates by cap(p).

It will also panic if there's already colors in the color.Palette provided to the func and not all of those colors are included in the Ditherer's palette. This is because the caller is indicating that certain colors must be in the palette, but the user who created the Ditherer does not want those colors.

func (*Ditherer) SetBayer

func (d *Ditherer) SetBayer(x, y uint, strength float32)

Sets Bayer PixelMapper to Ditherer stuct.

The provided dimensions of the bayer matrix [x,y] can only be powers of 2, but they do not need to be the same. If they are not powers of two, this function will panic.

Refer to documentation for `Bayer` function to get more information: https://pkg.go.dev/github.com/makeworld-the-better-one/dither/v2#Bayer

func (*Ditherer) SetOrdered

func (d *Ditherer) SetOrdered(odm OrderedDitherMatrix, strength float32)

SetOrdered sets a dither matrix as a PixelMapper to Ditherer stuct. Refer to documentation for `PixelMapperFromMatrix` function to get more information: https://pkg.go.dev/github.com/makeworld-the-better-one/dither/v2#PixelMapperFromMatrix

func (*Ditherer) SetRandomGrayscale

func (d *Ditherer) SetRandomGrayscale(min, max float32)

SetRandomGrayscale generates a grayscale random noise dithering and sets it to Ditherer stuct. Refer to documentation for `RandomNoiseGrayscale` function to get more information: https://pkg.go.dev/github.com/makeworld-the-better-one/dither/v2#RandomNoiseGrayscale

func (*Ditherer) SetRandomRGB

func (d *Ditherer) SetRandomRGB(minR, maxR, minG, maxG, minB, maxB float32)

SetRandomRGB generates a random noise dithering in RGB format and sets it to Ditherer stuct. Refer to documentation for `RandomNoiseRGB` function to get more information: https://pkg.go.dev/github.com/makeworld-the-better-one/dither/v2#RandomNoiseRGB

type ErrorDiffusionMatrix

type ErrorDiffusionMatrix [][]float32

ErrorDiffusionMatrix holds the matrix for the error-diffusion type of dithering. An example of this would be Floyd-Steinberg or Atkinson.

Zero values can be used to represent pixels that have already been processed. The current pixel is assumed to be the right-most zero value in the top row.

func ErrorDiffusionStrength

func ErrorDiffusionStrength(edm ErrorDiffusionMatrix, strength float32) ErrorDiffusionMatrix

ErrorDiffusionStrength modifies an existing error diffusion matrix so that it will be applied with the specified strength.

strength is usually a value from 0 to 1.0, where 1.0 means 100% strength, and will not modify the matrix at all. It is inversely proportional to contrast - reducing the strength increases the contrast. It can be useful at values like 0.8 for reducing noise in the dithered image.

See the documentation for Bayer for more details.

func (ErrorDiffusionMatrix) CurrentPixel

func (e ErrorDiffusionMatrix) CurrentPixel() int

CurrentPixel returns the index the current pixel. The current pixel is assumed to be the right-most zero value in the top row. In all matrixes that I have seen, the current pixel is always in the middle, but this function exists just in case.

Therefore with an ErrorDiffusionMatrix named edm, the current pixel is at:

edm[0][edm.CurrentPixel()]

Usually you'll want to cache this value.

func (ErrorDiffusionMatrix) Offset

func (e ErrorDiffusionMatrix) Offset(x, y, curPx int) (int, int)

Offset will take the index of where you are in the matrix and return the offset from the current pixel. You have to pass the curPx value yourself to allow for caching, but it can be retrieved by calling CurrentPixel().

type OrderedDitherMatrix

type OrderedDitherMatrix struct {
	Matrix [][]uint `json:"matrix"`
	Max    uint     `json:"max"`
}

OrderedDitherMatrix is used to hold a matrix used for ordered dithering. This is useful if you find a matrix somewhere and would like to try it out. You can create this struct and then give it to PixelMapperFromMatrix.

The matrix must be rectangular - each slice inside the first one must be the same length.

Max is the value all the matrix values will be divided by. Usually this is the product of the dimensions of the matrix (x*y), or the greatest value in the matrix plus one. For diagonal matrices or other matrices with repeated values, it is the latter.

Leaving Max as 0 will cause a panic.

Matrix values should almost always range from 0 to Max-1. If the matrix you found ranges from 1 to Max, just subtract 1 from every value when programming it.

type SpecialDither

type SpecialDither int

SpecialDither is used to represent dithering algorithms that require custom code, because they cannot be represented by a PixelMapper or error diffusion matrix.

There are currently no SpecialDither options, but they will be added in the future.

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL