Skip to content

Commit

Permalink
Bring in NeuQuant as an option for GIF.
Browse files Browse the repository at this point in the history
It was here originally, so we might as well have it just to compare what's different. It tends to analyze the color table well, but doesn't really dither, so maybe it could be used for an analysis step...
  • Loading branch information
tommyettinger committed May 4, 2024
1 parent 0b5061a commit 3c47b21
Show file tree
Hide file tree
Showing 3 changed files with 551 additions and 4 deletions.
39 changes: 38 additions & 1 deletion src/main/java/com/github/tommyettinger/anim8/AnimatedGif.java
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,12 @@ public void write(OutputStream output, Array<Pixmap> frames, int fps) {
*/
public boolean fastAnalysis = true;

/**
* Can be changed to true to use a completely different color quantization and dithering algorithm, NeuQuant.
* When enabled, the {@link #palette} is ignored, and so is {@link #ditherStrength}.
*/
public boolean useNeuQuant = false;

/**
* Often assigned as a field, the palette can be null (which means this may analyze each frame for its palette,
* based on the setting for {@link #fastAnalysis}), or can be an existing PaletteReducer. You may want to create a
Expand Down Expand Up @@ -338,7 +344,11 @@ public boolean addFrame(Pixmap im) {
++seq;
image = im;
getImagePixels(); // convert to correct format if necessary
analyzePixels(); // build color table & map pixels
// build color table & map pixels
if(useNeuQuant)
analyzePixelsNQ();
else
analyzePixels();
if (firstFrame) {
writeLSD(); // logical screen descriptor
writePalette(); // global color table
Expand Down Expand Up @@ -1504,6 +1514,33 @@ protected void analyzePixels() {
}
}

/**
* Analyzes image colors and creates color map.
*/
protected void analyzePixelsNQ() {
int nPix = width * height;
indexedPixels = new byte[nPix];
NeuQuant nq = new NeuQuant(image, 10);
// initialize quantizer
colorTab = nq.process(); // create reduced palette

for (int i = 0, c = 0; i < colorTab.length; i += 3, c++) {
usedEntry[c] = false;
}
// map image pixels to new palette
int k = 0;
for (int y = 0, i = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int rgba = image.getPixel(x, y);
int index = nq.map(rgba >>> 24, rgba >>> 16 & 255, rgba >>> 8 & 255);
usedEntry[index] = true;
indexedPixels[i++] = (byte) index;
}
}
colorDepth = 8;
palSize = 7;
}

/**
* Extracts image pixels into byte array "pixels"
*/
Expand Down
Loading

0 comments on commit 3c47b21

Please sign in to comment.