Package: dither-go
Dither Go!Dither Go! is a fast image processing library, making use ofditherGolang library to provide the most correct image dithering.WarningKeep in mind, that this library is currently in alpha state, and although there probably won't be that many breaking changes (unless there will be indither), there might be some bugs laying around in the less tested parts of the library. If you find some, please report them to thebug tracker.Features:A vast variety of dithering algorithms built-in with an option to specify your own (under construction),Very fast backend written in Go,Unique correctness from most dithering libraries, thanks to image linearization and color comparisons based on channel weighting technique,Support for images with transparency.Types of dithering supportedRandom noise (in grayscale and RGB)Ordered DitheringBayer matrix of any size (as long as dimensions are powers of two)Clustered-dot - many different preprogrammed matricesSome unusual horizontal or vertical line matricesYours?UsingSetOrdered, this library can dither using any matrix (under construction)Error diffusion ditheringSimple 2DFloyd-Steinberg, False Floyd-SteinbergJarvis-Judice-NinkeAtkinsonStuckiBurkesSierra/Sierra3, Sierra2, Sierra2-4A/Sierra-LiteSteven PigeonHow to install?To install Dither Go! from PyPI, setupvenvand run:$pipinstalldither-goAnd import library usingimport dither_go.UsageHere's a simple example using Floyd-Steinberg dithering:try:img=dither_go.open_image("input.jpg")exceptExceptionase:print(f"Couldn't load the requested image. Exception:{e}")# This is the color palette used in output imagepalette=dither_go.create_palette([[0,0,0],[255,255,255],# You can put here any color you want])# Create new `Ditherer` object using a constructorditherer=dither_go.new_ditherer(palette)ditherer.Matrix=dither_go.ErrorDiffusers.FloydSteinberg# Dither the image, attempting to modify the existing image# If it can't then a dithered copy will be returned.img=ditherer.Dither(img)dither_go.save_image(img,"dither_go.png","png")If you always want to dither a copy of the image, you can useDitherCopyinstead.Here's how you create aDithererthat does Bayer dithering. Note thatditherer.SetBayeris used instead ofditherer.Matrix.ditherer=dither_go.new_ditherer(palette)ditherer.SetBayer(8,8,1.0)# 8x8 Bayer matrix at 100% strengthHere's how you create aDithererthat does clustered-dot dithering - dithering with a predefined matrix.ditherer=dither_go.new_ditherer(palette)ditherer.SetOrdered(dither_go.OrderedDitherers.ClusteredDotDiagonal8x8,1.0)What method should I use?Generally, using Floyd-Steinberg serpentine dithering will produce the best results. The code would be:ditherer=dither_go.new_ditherer(palette)ditherer.Matrix=dither_go.ErrorDiffusers.FloydSteinbergditherer.Serpentine=TruePlaying with the strength of the matrix might also be useful. The example above is at full strength, but sometimes that's too noisy. The code for 80% strength looks like this:ditherer.Matrix=dither_go.error_diffusion_strength(dither_go.ErrorDiffusers.FloydSteinberg,0.8)The main reason for using any other dithering algorithm would beAesthetics- dithering can be a cool image effect, and different methods will look differentSpeed- error diffusion dithering is sequential and therefore single-threaded. But ordered dithering, like usingBayer, will use all available CPUs, which is much faster.How to access built-in matrices?Built-in error diffusion and ordered dither matrices are located inErrorDiffusersandOrderedDitherersdata classes.In order to apply error diffusion matrix toDitherer, first construct a new instance by usingnew_ditherer()constructor and setMatrixvariable value to any of theErrorDiffusersmatrices.To apply ordered dither matrix, useSetOrderedmethod instead.WarningYou can't have both types of dither applied at the same time, so in order to change dithering type, you'll need to clear currently used dither type.To clear error diffusion matrix, setNoneas a value inMatrixand to clear ordered dither matrix, useClearMapper.How do I get the palette?Sometimes the palette isn't an option, as it might determined by the hardware. Many e-ink screens can only display black and white for example, and so your palette is chosen for you.But in most cases you have all the colors available, and so you have to pick the ones that represent your image best. This is calledcolor quantization.There isn't currently any built-in color quantization functionality available in this library. You'll instead need to use a library for that, likecolor-thiefwhich is the most popular, or something likecolorgram.pyorPylette. There is alsopywalwhich you canuse as a module.Scaling imagesA dithered output image will only look right at 100% size. As you scaledown, the image will immediately get darker, and strange grid-like artifacts will appear, known as amoiré pattern. This is due to how dithered images work, and is not something this library can fix.The best thing to do is to scale theinputimage to theexactsize you want before using this library. But sometimes you want to scale the image up after dithering, to make the dithering effect more obvious for aesthetic purposes.So for scaling the dithered output imageup(above 100%), that will only look fine if you usenearest-neighbor scaling- the kind of scaling that produces pixelated results. Otherwise the dither pixel values will be blurred and averaged, which will mess things up. And even once you're using that, it will still produce moiré patterns, unless you're scaling by a multiple of the original dimensions.So when scaling up, you should be scaling by 2x or 3x, rather than a non-integer like 1.34x.Encoding and decodingDue to how Golang'simagelibrary works, there is only support for the most basic image formats built-in into the standard library.To add more, you need to use custom decoders/encoders, of which Dither Go! already has several added and a couple planned to be added. You can check theimage format matrixto see which are available and planned to be added.If you want support for a format which isn't currently on that list, submit a feature request in thebug tracker.Tips:If the palette is grayscale, the input image should be converted to grayscale first to get accurate results.All the[][]uintmatrices are supposed to be applied withPixelMapperFromMatrix.You can generate a list of available dither matrices with their display names usingMatrixUtils().generate_matrices_list()method.Notes:This README has some of its parts copied fromditherproject to provide sufficient information about features of this libraryLicenseThis repository is licensed under the terms of the GNU GPLv3 license. You can find a copy of the license in the COPYING file.Theditherlibrary which this project is making use of, is the terms of Mozilla Public License 2.0. The copy of the license can be foundhere.