anim8-gdx

Adds support for writing animated GIF, PNG8, and animated PNG (including full-color) from libGDX

APACHE-2.0 License

Stars
37

Bot releases are visible (Hide)

anim8-gdx - 0.4.2 "Cleanse Your Palette" Latest Release

Published by tommyettinger about 1 year ago

This release mostly revamps the PaletteReducer-related classes, such as FastPalette and QualityPalette, to be much simpler, and makes the FastSomething classes (like FastGif and FastPNG8) almost only differ by using FastPalette as their default. This allows the FastGif and FastPalette classes to be used on GWT, though they aren't actually much faster now (they may look different with some palettes, which could be useful).

FastPalette mostly differs in its color difference metric now, which is about the same as what PaletteReducer used before. Similarly, QualityPalette uses a better color difference metric, and PaletteReducer uses something similar but with some calculations done beforehand and cached. PaletteReducer and QualityPalette tend to perform similarly, but so does FastPalette, so the appearance may be all that sets them apart. This updates the WREN dither, changing how it clamps diffused error so that large flat areas are less common. It also updates LOAF, using a generally-better version that I had been testing in another repo (ColorWeaver) for a while. A few other dither algorithms may have changed.

I think this is generally a nice set of improvements; I hope you agree!

anim8-gdx - 0.4.1 "Wren Free"

Published by tommyettinger about 1 year ago

This release mostly adds the new WREN dither algorithm, a mix of error-diffusion, the R2 sequence pattern, and blue noise that would make Dr. Frankenstein cry tears of joy. WREN is almost as good at preserving hue as the closely-related WOVEN, but is much better at avoiding "flatness" where there should be a gradient of shading. Like WOVEN, it works especially well with small, mixed-color palettes like the DB8 palette in the README.md previews, and still works great with larger palettes. WREN is the current default; it just in general does better than NEUE did on more input images. NEUE may still do better on black-and-white-only palettes, or some other situations like that, because it doesn't treat the 3 RGB channels separately.

The other change in here is not an API change, but still may be noticeable: The lightness curve, which determines how a given float between 0.0 and 1.0 representing lightness gets converted to actual pixel colors, has been slightly adjusted and should be much closer to how it (probably) should be. It's also much easier to think about and potentially port to shader code, because it no longer uses as many conditionals or other code that changes the curve in confusing ways -- actually, the two functions are now equivalent to Math.pow(3.0/2.0) and Math.pow(2.0/3.0).

PaletteReducer.colorsFrom(Pixmap) is also a possibly-convenient new feature that gets the most frequently-encountered colors in a Pixmap (typically up to 256) and returns them as an array of RGBA8888 ints (like PaletteReducer.exact(int[]) can use. This may be handy for loading a palette from a user-provided image.

Considering I had a fever for some of the development here, I'm pretty happy with it! Enjoy!

anim8-gdx - 0.4.0 "Lo-Fi Dithers to Study and Relax To"

Published by tommyettinger over 1 year ago

This release adds a new dither, LOAF, and makes small adjustments to DODGY (added earlier, in 0.3.15). This has one breaking API change (barely): the removal of an undocumented public field, reverseMap in PaletteReducer, because it was only used in PATTERN dither and wasn't even helpful there. As for LOAF, it's a low-fidelity dither that typically only mixes two colors per 2x2 pixel area, though if the original area had 3 or 4 very different colors in that area, it could use up to 4 colors. LOAF tends to look much more like a hand-drawn pixel art dither than the others here, though it may look too simplistic to seem made by a human. It looks good when dithering pixel art, and not very good for high-detail images like paintings or photos. DODGY had very subtle changes, but it tends to look smoother/less-noisy now and has fewer repetitive artifacts, at the expense of not being quite as accurate at matching hue (still better than NEUE, but worse than WOVEN).

Good luck on your animating, image-writing, dithering adventures!

anim8-gdx - 0.3.15 "Dodge This"

Published by tommyettinger over 1 year ago

This release adds a new dither algorithm, DODGY, which mixes attributes of NEUE and WOVEN, and usually looks rather good. It also adds QualityPalette, which is a subclass of PaletteReducer that changes its color difference function to a usually-more-accurate, generally-slower version. Code can choose whether it wants the greatest compatibility and close-to-the-best speed (PaletteReducer), to lose GWT compatibility and maybe gain some speed (FastPalette), or to keep compatibility, give up speed, and potentially gain image quality (QualityPalette).

Also, because I forgot to make a complete GitHub release for 0.3.13 or 0.3.14, here are some notes for those:

0.3.13 brings back compatibility with Java 7, just in time for Java 20 to no longer support it. Supporting Java 7 is important for RoboVM right now, which is stuck in the distant past with its time machine broken. Most of the work in this release was to add "Fast" variants on each file type (plus non-animated PNG, in the new FastPNG class), which give up GWT compatibility and also the ability to flip the output, but may read and write files faster by using NIO Buffers.

0.3.14 makes some adjustments to BLUE_NOISE and ROBERTS dither, but doesn't do much else. Those two should look better, though. It does have some improved handling for non-RGB/RGBA inputs to FastPalette.

anim8-gdx - 0.3.12 "Web Wuv"

Published by tommyettinger almost 2 years ago

This release pretty much only exists to improve GWT support -- earlier releases didn't use a package/namespace/folder for their .gwt.xml files, and this can cause problems in many GWT projects. Now the GWT inherits line is:

<inherits name="com.github.tommyettinger.anim8" />

Other than the version, almost nothing else has changed. There's a new experimental dithering option, "Igneous", in PaletteReducer, but it isn't a complete Dithered.DitherAlgorithm like the others. That's all, though!

anim8-gdx - 0.3.11 "From The Same Cloth"

Published by tommyettinger almost 2 years ago

This release adds a new dither algorithm (WOVEN), updates another (ROBERTS), and doesn't do much else. If you didn't use ROBERTS before and don't want to try WOVEN, this release won't be needed for you; otherwise, WOVEN can look quite good sometimes, and I feel that ROBERTS is better as well.

anim8-gdx - 0.3.10 "From Blue To Violet"

Published by tommyettinger about 2 years ago

This release has several significant changes! There's a new dither algorithm (ROBERTS), simplified and improved GRADIENT_NOISE, a change to the default palette (back to DawnBringer's Aurora), and a change to how the threshold is calculated when you call PaletteReducer.analyze(). The last two of these can change what existing code will produce, so be advised that you may need to make some changes.

The palette change affects PaletteReducer objects created with no palette, with an invalid palette, or that had setDefaultPalette() called on them; Aurora was used in the earliest versions of the library, but I tried to increase yellow coverage by switching to a randomly distributed palette, Haltonic. Unfortunately, Haltonic was probably too random, and couldn't handle smooth gradients well at all because it jumped around between hues as it went up or down in lightness. You can still use Haltonic as a palette by passing it to PaletteReducer's constructor or to PaletteReducer.exact(), and it is available as a constant array in PaletteReducer.

The threshold change could be trickier, and you might need to raise or lower the threshold from the default 100 when you call analyze(). The threshold is automatically adjusted based on the limit for how many colors the palette can use; to try to maximize color coverage, PaletteReducer lowers the threshold to allow more colors in when the limit is larger. The threshold is hard to evaluate for all images equally, and it's a good idea to try and see which of 50, 100, and 200 looks best to you when the palette matters.

Hopefully this release will result in some nicer looking palette reductions and animations. Good luck.

Oh yeah, and happy birthday, Violeta!

anim8-gdx - 0.3.9 "Blue In The Face"

Published by tommyettinger about 2 years ago

This release adjusts BLUE_NOISE dither (like the previous release), but also changes the default palette from HALTONIC (made by a program) to AURORA (made by DawnBringer). There are also some small tweaks to defaults for thresholds on PaletteReducer.analyze() and related methods. BLUE_NOISE dither is now more subtle and keeps flat areas in input images more reliably; raising dither strength can reduce the flatness if desired. NEUE remains a great choice for realistic images and almost anything with smooth gradients, but BLUE_NOISE is targeted differently at pixel art and animations in particular.

anim8-gdx - 0.3.8 "Blue Noister Cult"

Published by tommyettinger about 2 years ago

This release only changes the BLUE_NOISE dither, making it have fewer (or no) scaly artifacts while keeping its strong performance on animations. This dither mode now works especially well on pixel art; isonomicon now has much higher-quality GIFs compared to when it used NEUE before. Nothing else changed, so if you're happy with your current dithering, there's no real reason to update, but if you want less-artifact-laden animations, this might be something to consider.

anim8-gdx - 0.3.7 "Simple Silky Smooth Spaces"

Published by tommyettinger over 2 years ago

This release is mostly concerned with palette analysis, including with analyze(), exact(), and the new analyzeHueWise(). Palettes are expected to change with analysis, and dithers are expected to change just a little with all of those methods. Now we use the simplest possible color difference comparison: squared Euclidean distance in RGB space. Somehow, this seems to work quite well. Several small palettes that were unusable before are very usable now; DawnBringer's DB8 palette, with just 8 colors (and transparent) is able to dither many images quite well. This is an 8-color image. I think, judging by what testing I have done, the new metric should work well, but if it doesn't, you can subclass PaletteReducer (potentially anonymously) and override the differenceMatch(), differenceAnalyzing(), and/or differenceHW() methods.

anim8-gdx - 0.3.6 "A Metric Ton of Feathers"

Published by tommyettinger over 2 years ago

This release includes a grab bag of fixes, features, and in-general changes; I encourage you to try it out, but I will understand if you want to go back to an earlier release. I'm just an understanding person that way. A main fix affects primarily PATTERN dither, which could rarely place transparent pixels in a dither even if the image didn't have any transparent colors in it originally. The main feature is also the main change; the color metric is simpler now and seems to respect blue more when it didn't before. I can't really explain how this works, so here's a before image and an after image. Especially when zoomed out to cause interpolation between pixels, the after image is much closer to the original (the couch in the upper left is royal blue in the un-dithered image). This change does mean low-color dithers can be differently-sensitive to the presence of uncommon colors; in this before image that should have 6 colors of pixel art army colors as well as light and dark armies, the algorithm struggled with blue and purple, but in this after image, it does considerably better. There are trade-offs; images like the remastered Mona Lisa we use here don't show green as much, if at all, with low color counts (though they look just as good with high color counts).

So, try it out, and I'll appreciate any feedback that gets thrown at me. If you have an idea for a better way of analyzing colors in an image to generate a palette (quickly), this would be very useful! I hope anim8-gdx comes in handy for you.

anim8-gdx - 0.3.5 "Smooth Operator"

Published by tommyettinger over 2 years ago

This release has a sometimes-significant improvement to Neue dither, as well as some lesser changes to Chaotic Noise dither and a smaller JAR size. You can also configure dither strength on a PNG8 or AnimatedGif object now without needing a PaletteReducer; this works well with AnimatedGif when its palette is null (indicating that each frame should be analyzed, either in bulk or one-at-a-time). Neue is much smoother now on gradients, and has even less banding. This should be a fairly safe release to update to, except for a breaking change: PaletteReducer.RAW_BLUE_NOISE is removed because we only use the triangular-mapped noise now. This saves a lot of JAR size.

anim8-gdx - 0.3.4 "I Was Framed!"

Published by tommyettinger almost 3 years ago

This release is mostly a fix for the main new feature in the last release, where frames were analyzed individually. When color counts were very low, in the last version and potentially earlier versions, calling PaletteReducer's analyze() or analyzeFast() could produce bizarre visual glitches for only those frames with low color counts. This is fixed now, by reserving a color in the palette for "fully transparent" every time. This means the most opaque colors you can have in a GIF or PNG8 is 255.

anim8-gdx - 0.3.3 "Cyber-Mechanoid Environment Probe Frame"

Published by tommyettinger almost 3 years ago

This release goes from having one option for making palettes for GIF animations (using PaletteReducer.analyze(Array<Pixmap>) to process all frames at once) to having three (the earlier method, plus "fastAnalysis" and "not fastAnalysis"). The two new methods produce a palette for every frame of the GIF (local colormaps), which can help color quality in some cases. When fastAnalysis is set to true in AnimatedGif, a hasty algorithm is run per-frame that generally looks pretty good and takes about the same time as the earlier method. When fastAnalysis is false, every frame is analyzed like a still image, with lots of color comparisons to find the best match. This last one is about 5x slower than the others, but is higher quality. These last two run only when the AnimatedGif.palette field is null, and only for animations with two or more frames.

I hope this can be useful! You may want to use the default fastAnalysis=true setting while prototyping, and set it to false when doing a release-like viewing where the appearance of gifs matters.

anim8-gdx - 0.3.2 "Symphony of Colorimetry"

Published by tommyettinger almost 3 years ago

This release has two purposes: one, it updates Gradle to a more secure version (something I'm updating wherever I can), and two, it really improves the behavior of PaletteReducer.analyze(). There's rarely a need to adjust the threshold now, and the default of 150 generally is sufficient in most cases. Analyzing the palette seems to preserve most important colors once it gets to about 16 colors or just above, with more colors needed for images with many very-different hues, naturally. This is a small release, but code that needs to analyze full-color images may really benefit from it.

anim8-gdx - 0.3.1 "That Timeless Quality"

Published by tommyettinger almost 3 years ago

This release backtracks on some of the (mis-)features added to NEUE dither in the last release. Temporal dithering made mostly-still images look like they were crawling slightly all over, so it's been removed from NEUE (it's still in CHAOTIC_NOISE, which is looking like it should be removed). The checkerboard pattern that NEUE used in addition to its blue noise pattern turned out to make the images rougher, and caused the "fine sand" artifact in 0.3.0. The checkerboard is gone now, and the behavior regarding banding is really just almost as good without it. The behavior on flat areas is much better now.

I also attempted to put the large amount of generated images here on Git LFS, which was a disaster and so now I'm using Imgur to host previews of generated images.

If you use NEUE dither, updating is strongly recommended. For other dithers, it's up to you. NEUE is still the default because it's so much better regarding banding (it was better even when it was added in 0.3.0), and it's significantly improved in this release.

anim8-gdx - 0.3.0 "Light Show"

Published by tommyettinger almost 3 years ago

This release brings a new dither algorithm and makes it the default: Neue. It is very similar to the previous default, Scatter; both are a mix of an error-diffusion dither with blue-noise error adjustment. The major difference is that Neue handles smooth gradients much more, well, smoothly; Scatter and all of the other dithers except for Blue_Noise and Pattern have some amount of banding on gradients. Neue doesn't have the strong spongy artifacts that Blue_Noise has, nor does it have the 4x4 grid of Pattern, but it does have a fine-sand-like, slightly-grainy appearance because of how it mixes nearby pixels to get a smooth transition. Neue also does temporal dithering in animations, so it doesn't keep any artifacts for multiple frames unless those frames are identical.

The other major change here is how lightness is handled; this is related to dither strength, which also changed. Before, we used Oklab's L channel as our lightness as-is. As Oklab's author recently discussed, by default Oklab's L has more very-dark values than very-light ones, and this has a significant effect on both the palette analysis and dithering that anim8-gdx does. I noticed this originally in colorful-gdx, and have been working on fixes there. Using a simple adjustment that I found worked in colorful-gdx, we can now quickly stretch the lighter values and shrink the darker ones, while leaving hue and saturation the same. This shouldn't have much effect other than improving the analyzed palettes a bit (they seem to allow smoother transitions between bright colors now)... and changing the appearance of the default dither strength for pretty much all dither algorithms. This last point is why this release is 0.3.0 instead of 0.2.13. I think most of the dither algorithms look better, especially Neue and Scatter, with the current lightness technique. I hope this works well for everyone!

anim8-gdx - 0.2.12 "Blue Steel"

Published by tommyettinger about 3 years ago

This release has some small, but useful improvements to BLUE_NOISE and GRADIENT_NOISE dithers; blue noise, in particular, should be pretty competitive with the other non-pattern dithers now on quality, and even comes close to PATTERN on some smoothly-changing colors. There's a major fix to a stupid bug in a demo (InteractiveReducer now disposes Pixmaps it doesn't use any more; you should do this too). There's also a small possible improvement for large palettes, since all 8 bits of a channel are considered now in some color calculations, instead of just the most significant 5 bits. All around, small but hopefully helpful changes.

anim8-gdx - 0.2.11 "Off The Beaten Paeth"

Published by tommyettinger about 3 years ago

This release is rather focused on the time it takes to write files, and has some good improvements there. There's also some improvements to the file size of PNG-8 images this writes by default, and although full-color APNG files are slightly larger by default, both can be compressed just as well as before by tools like oxipng (for still images) and APNG Optimizer (for animated ones). All PNGs should write quite a bit faster with lower compression; compression level 2 is generally a good pick, especially if you intend to optimize selected PNGs later using one of the above tools.

The improvements here are mostly due to changing the default "filter" from Paeth, which is slower to compute, to None, which is faster. Paeth produces smaller file sizes in full-color images, but we get close to Paeth's gains by using the Sub filter for AnimatedPNG (and only there); it is between Paeth and None in speed, but closer to Paeth in size for APNGs. Running an optimizer on a PNG mostly changes filters on a line-by-line basis to find the best combination it can; here we only use one filter at a time.

The BLUE_NOISE dither has also been improved significantly by switching to triangular-mapped blue noise for that option; this softens the artifacts in the blue noise. It still has a very different quality to it than something like PATTERN or SCATTER, so there are reasons to use it.

anim8-gdx - 0.2.10 "Flowing Like Silk"

Published by tommyettinger over 3 years ago

This release mostly contains two improvements: some awkward differences between PaletteReducer and PNG8/AnimatedGif regarding PATTERN dither have been cleared up, and the default palette is significantly smoother and more accurate by using a (slowly) precalculated set of data. The latest commit (not including the palette improvement) had been tested in colorful-gdx for a while now, and really everyone should have access to the PATTERN fixes. Updating is encouraged, but if you don't use the default palette or PATTERN dither, you probably won't notice a difference relative to 0.2.9 .

Package Rankings
Top 6.69% on Proxy.golang.org
Top 26.14% on Repo1.maven.org