Converting Jpegs To Gifs Is Too Long
I'm trying to make gif animation from jpegs I get from video camera. But this process is unreal long. I used two different libraries. First is written with native C++ code and seco
Solution 1:
Firstly I have to thank to the @Spektre for this answer: Effective gif/image color quantization?
My colleague and I just translated it from the C++ to the Java. It shows good results in 4x less time. I'll try to improve it, but this is already much better result, than AnimatedGifEncoder.java (I used before)
Here is the code:
publicstaticfinalintMAX_COLOR_COUNT=65536;
/**
* @param pixels rgb 888
* @param palette int[256]
* @return indices of colors in palette
*/privateint[][][] createPalette(int[] pixels, int[] palette) {
finalint[] histogram = newint[MAX_COLOR_COUNT]; // pixel count histogramfinalint[] indices = newint[MAX_COLOR_COUNT]; // here index is color valuefor (inti=0; i < MAX_COLOR_COUNT; i++) {
indices[i] = i;
}
// creating histogramfor (int color : pixels) {
// 0001 1111 0111 1110 0000 1111 1000 0000 0000
color = ((color >> 3) & 0x1F) | ((color >> 5) & 0x7E0) | ((color >> 8) & 0xF800);
if (histogram[color] < Integer.MAX_VALUE) { // picture must be really big
histogram[color]++;
}
}
// removing zerosintj=0;
for (inti=0; i < MAX_COLOR_COUNT; i++) {
histogram[j] = histogram[i];
indices[j] = indices[i];
if (histogram[j] != 0) {
j++;
}
}
finalinthistograms= j;
// bubble sortfor (inti=1; i != 0; ) {
i = 0;
for (intx=0, y = 1; y < histograms; x++, y++) {
if (histogram[x] < histogram[y]) {
i = histogram[x];
histogram[x] = histogram[y];
histogram[y] = i;
i = indices[x];
indices[x] = indices[y];
indices[y] = i;
i = 1;
}
}
}
finalint[][][] colorMap = newint[32][64][32];
intcolorTableIndex=0, x = 0;
for (; x < histograms; x++) { // main colorsfinalintcolor= indices[x];
// 1f (16) = 0001 1111 (2)// 3f (16) = 0011 1111 (2)// (1111 1)(111 111)(1 1111)finalintb= color & 0x1f;
finalintg= (color >> 5) & 0x3f;
finalintr= (color >> 11) & 0x1f;
// skip if similar color already in palette[]inta=0, i = 0;
for (; i < colorTableIndex; i++) {
finalbytetempB= (byte) ((palette[i] >> 3) & 0x1f);
finalbytetempG= (byte) ((palette[i] >> 10) & 0x3f);
finalbytetempR= (byte) ((palette[i] >> 19) & 0x1f);
// if difference between two colors is pretty small// taxicab distanceintdifference= tempB - b;
if (difference < 0) {
difference = -difference;
}
a = difference;
difference = tempG - g;
if (difference < 0) {
difference = -difference;
}
a += difference;
difference = tempR - r;
if (difference < 0) {
difference = -difference;
}
a += difference;
if (a <= 2) { // smaller than 16/8
a = 1;
break;
}
a = 0;
}
if (a != 0) {
colorMap[r][g][b] = i; // map to existing color
} else {
colorMap[r][g][b] = colorTableIndex; // map to new index// 1111 1000 1111 1100 1111 1000
palette[colorTableIndex] = b << 3 | (g << 10) | (r << 19); // fill this index with new color
colorTableIndex++;
if (colorTableIndex >= 256/*palette.length*/) {
x++;
break;
}
}
} // colorTableIndex = new color table sizefor (; x < histograms; x++) { // minor colorsfinalintcolor= indices[x];
finalintb= color & 0x1f;
finalintg= (color >> 5) & 0x3f;
finalintr= (color >> 11) & 0x1f;
// find closest colorintminDistance= -1;
intcolorIndex=0;
for (int a, i = 0; i < colorTableIndex; i++) {
finalbytetempB= (byte) ((palette[i] >> 3) & 0x1f);
finalbytetempG= (byte) ((palette[i] >> 10) & 0x3f);
finalbytetempR= (byte) ((palette[i] >> 19) & 0x1f);
intdifference= tempB - b;
if (difference < 0) {
difference = -difference;
}
a = difference;
difference = tempG - g;
if (difference < 0) {
difference = -difference;
}
a += difference;
difference = tempR - r;
if (difference < 0) {
difference = -difference;
}
a += difference;
if ((minDistance < 0) || (minDistance > a)) {
minDistance = a;
colorIndex = i;
}
}
colorMap[r][g][b] = colorIndex;
}
return colorMap;
}
privatebyte[] map(int[] pixels, int[][][] colorMap) {
finalintpixelsLength= pixels.length;
finalbyte[] mapped = newbyte[pixelsLength];
for (inti=0; i < pixelsLength; i++) {
finalintcolor=
((pixels[i] >> 3) & 0x1F) | ((pixels[i] >> 5) & 0x7E0) | ((pixels[i] >> 8) & 0xF800);
finalintb= color & 0x1f;
finalintg= (color >> 5) & 0x3f;
finalintr= (color >> 11) & 0x1f;
mapped[i] = (byte) colorMap[r][g][b];
}
return mapped;
}
Post a Comment for "Converting Jpegs To Gifs Is Too Long"