您的位置:首页 > 其它

终于搞定多张JPG图片转成GIF动画这个难题,解决方法如下。

2011-10-10 18:05 661 查看
这几天,一直在搞这个问题,就是想把自己所得到的多张的JPG图片文件,转成一张GIF的动画,然后让它来执行。

刚开始的时候,也摸索了很久,这个问题,看到网上面的也有很多的方法,但是都是不能够使用,很是郁闷。其实网上的方法,也是能够用的,但是有它的局限性,一般来说,都是用的是LZW的一种GIF算法来实现这个过程,作为一名软件人员,所要做的事是使用轮子,所以,可以直接使用别人写好的算法,然后根据自己的需求来实现一些相应的功能,GIF也是如此。

刚才提到了网上的一些方法,它的局限性在于,只是适用于J***A,而不是android上,而我们的目标正是实现在andorid上,到底有什么不一样的地方呢,下面我详细说一下。

根据我几天以来的发现,第一种方案, android里面,也可以实现一些纯java 的程度,只是会有一些限制,例如有很多纯java 的库包在android中,并不存在,所以这个方法实现起来并不容易,故弃之。

说到这里,还是要提到网上一些适用于J***A的方法,为什么在android里面,就不能用了呢,这是因为,在这些代码里面,使用了一些java.awt.*里面的库,以及一个ImageIO的库包,所以不能在android里面实现,我也想过,把这些库包提出来放到android工程下面去使用,结果失败,老是报 Conversion to Dalvik format failed with error 1错误,查了网上各种各样的方法,都没有生效,郁闷之。如果各网友想要查,可以在jdk的lib下面找到一个rt.jar的库包,里面就有这些所需要调用到的库文件。所以这种方法,也被我放弃。

最后,我还是想,到底怎么才可以实现这个功能,我后来想到对这些java文件,进行一些改造,用一些android里面的类来替代awt和ImageIO库,这样应该可以吧,

在自己的不断努力之下,终于实现了这一功能,说起来实现的非常巧,并不是说我功力有多深,只是随例试了一下,给我试出来了,个人也是感觉自己运气比较好,呵呵。

下面就不说废话了,直接帖代码:



public class jpgToGif {



//synchronized

public static void jpgToGif(String pic[],

String newPic) {

try {

Log.i("jpgToGif","is connection ="+newPic);

AnimatedGifEncoder1 e = new AnimatedGifEncoder1();

e.setRepeat(1);

e.start(newPic);



for (int i = 0; i < pic.length; i++) {

e.setDelay(200); // 设置播放的延迟时间

Bitmap src=BitmapFactory.decodeFile(pic[i]);

e.addFrame(src); // 添加到帧中

}

e.finish();//刷新任何未决的数据,并关闭输出文件

} catch (Exception e) {

e.printStackTrace();

}

}

}

AnimatedGifEncoder1.java

public class AnimatedGifEncoder1

{

protected boolean closeStream;

protected int colorDepth;

protected byte[] colorTab;

protected int delay = 0;

protected int dispose;

protected boolean firstFrame;

protected int height;

protected Bitmap image;

protected byte[] indexedPixels;

protected OutputStream out;

protected int palSize;

protected byte[] pixels;

protected int repeat = -1;

protected int sample;

protected boolean sizeSet;

protected boolean started ;

protected int transIndex;

protected int transparent = 0;

protected boolean[] usedEntry;

protected int width;

public AnimatedGifEncoder1()

{

boolean[] arrayOfBoolean = new boolean[256];

this.usedEntry = arrayOfBoolean;

this.palSize = 7;

this.dispose = -1;

this.closeStream = false;

this.firstFrame = true;

this.sizeSet = false;

this.sample = 10;

}

public boolean addFrame(Bitmap paramBitmap)

{

boolean ok = true;

if(paramBitmap==null || !started)

{

return false;

}



try

{

Log.i("AnimatedGifEncode...","AnimatedGifEncode is addFrame ="+paramBitmap);

if (!sizeSet)

{

int i = paramBitmap.getWidth();

int l = paramBitmap.getHeight();

setSize(i, l);

}

this.image = paramBitmap;

getImagePixels();

analyzePixels();

if(firstFrame)

{

writeLSD();

writePalette();

if(repeat>=0)

writeNetscapeExt();

}

writeGraphicCtrlExt();

writeImageDesc();



if (!firstFrame)

writePalette();

writePixels();

this.firstFrame = false;



}

catch (IOException localIOException1)

{

ok=false;







}

return ok;



}

protected void analyzePixels()

{

int len = this.pixels.length;

int nPix = len / 3;

byte[] arrayOfByte1 = new byte[nPix];

this.indexedPixels = arrayOfByte1;

byte[] arrayOfByte2 = this.pixels;

int k = this.sample;

NeuQuant nq = new NeuQuant(arrayOfByte2, len, k);

this.colorTab = nq.process();

int l = 0;

int i1 = this.colorTab.length;

Object localObject;

if (l >= i1)

{

l = 0;

localObject = null;

}



for (int i = 0; i < colorTab.length; i += 3) {

byte temp = colorTab[i];

colorTab[i] = colorTab[i + 2];

colorTab[i + 2] = temp;

usedEntry[i / 3] = false;

}

int k1 = 0;

for (int i = 0; i < nPix; i++) {

int index =

nq.map(pixels[k1++] & 0xff,

pixels[k1++] & 0xff,

pixels[k1++] & 0xff);

usedEntry[index] = true;

indexedPixels[i] = (byte) index;

}

pixels = null;

colorDepth = 8;

palSize = 7;

if (transparent != 0) {

transIndex = findClosest(transparent);

}



}

protected int findClosest(int paramInt)

{



if (colorTab == null)

{

return -1;

}

int r = Color.red(paramInt);

int g = Color.green(paramInt);

int b = Color.blue(paramInt);

int minpos = 0;

int dmin = 256 * 256 * 256;

int len = colorTab.length;



for (int i = 0; i < len;) {

int dr = r - (colorTab[i++] & 0xff);

int dg = g - (colorTab[i++] & 0xff);

int db = b - (colorTab[i] & 0xff);

int d = dr * dr + dg * dg + db * db;

int index = i / 3;

if (usedEntry[index] && (d < dmin)) {

dmin = d;

minpos = index;

}

i++;

}

return minpos;

}





public boolean finish()

{

if (!started) return false;

boolean ok = true;

started = false;

try {

out.write(0x3b); // gif trailer

out.flush();

if (closeStream) {

out.close();

}

} catch (IOException e) {

ok = false;

}

// reset for subsequent use

transIndex = 0;

out = null;

image = null;

pixels = null;

indexedPixels = null;

colorTab = null;

closeStream = false;

firstFrame = true;

return ok;

}

protected void getImagePixels()

{

int w = this.image.getWidth();

int h = this.image.getHeight();

Bitmap.Config localConfig = Bitmap.Config.ARGB_8888;

Bitmap localBitmap1 = Bitmap.createBitmap(w, h, localConfig);

Canvas localCanvas = new Canvas(localBitmap1);

localCanvas.save();

Paint localPaint = new Paint();

localCanvas.drawBitmap(image, 0, 0, localPaint);

localCanvas.restore();



this.pixels =new byte[w * h * 3];

int[] arrayOfInt = new int[w * h];

int k = 0;

int l = 0;

int i1 = w;

localBitmap1.getPixels(arrayOfInt, 0, w, k, l, i1, h);

int localObject = 0;

while (true)

{



if (localObject >= arrayOfInt.length)

return;

pixels[localObject * 3] = (byte)Color.blue(arrayOfInt[localObject]);

pixels[localObject * 3+1] = (byte)Color.green(arrayOfInt[localObject]);

pixels[localObject * 3+2] = (byte)Color.red(arrayOfInt[localObject]);

++localObject;

}

}

public void setDelay(int ms) {

delay = Math.round(ms / 10.0f);

}





public void setDispose(int code) {

if (code >= 0) {

dispose = code;

}

}





public void setFrameRate(float fps) {

if (fps != 0f) {

delay = Math.round(100f / fps);

}

}

public void setQuality(int quality) {

if (quality < 1) quality = 1;

sample = quality;

}





public void setRepeat(int iter) {

if (iter >= 0) {

Log.i("AnimatedGifEncode...","AnimatedGifEncode is setRepeat..setRepeat =");

repeat = iter;

}

}

public void setSize(int w, int h) {

if (started && !firstFrame) return;

width = w;

height = h;

if (width < 1) width = 320;

if (height < 1) height = 240;

sizeSet = true;

}





public void setTransparent(int c)

{

this.transparent = c;

}

public boolean start(OutputStream os)

{

if (os == null) return false;

boolean ok = true;

closeStream = false;

out = os;

Log.i("AnimatedGifEncode...","AnimatedGifEncode is start outputSteam");

try {

writeString("GIF89a"); // header

} catch (IOException e) {

ok = false;

}

return started = ok;

}



public boolean start(String file) {

boolean ok = true;

try {

out = new BufferedOutputStream(new FileOutputStream(file));

ok = start(out);

Log.i("AnimatedGifEncode...","AnimatedGifEncode is start ="+file);

closeStream = true;

} catch (IOException e) {

ok = false;

}

return started = ok;

}

protected void writeGraphicCtrlExt() throws IOException {

out.write(0x21); // extension introducer

out.write(0xf9); // GCE label

out.write(4); // data block size

int transp, disp;

if (transparent == 0) {

transp = 0;

disp = 0; // dispose = no action

} else {

transp = 1;

disp = 2; // force clear if using transparent color

}

if (dispose >= 0) {

disp = dispose & 7; // user override

}

disp <<= 2;

// packed fields

out.write(0 | // 1:3 reserved

disp | // 4:6 disposal

0 | // 7 user input - 0 = none

transp); // 8 transparency flag

writeShort(delay); // delay x 1/100 sec

out.write(transIndex); // transparent color index

out.write(0); // block terminator

}

protected void writeImageDesc() throws IOException {

out.write(0x2c); // image separator

writeShort(0); // image position x,y = 0,0

writeShort(0);

writeShort(width); // image size

writeShort(height);

// packed fields

if (firstFrame) {

// no LCT - GCT is used for first (or only) frame

out.write(0);

} else {

// specify normal LCT

out.write(0x80 | // 1 local color table 1=yes

0 | // 2 interlace - 0=no

0 | // 3 sorted - 0=no

0 | // 4-5 reserved

palSize); // 6-8 size of color table

}

}





protected void writeLSD() throws IOException {

// logical screen size

writeShort(width);

writeShort(height);

// packed fields

out.write((0x80 | // 1 : global color table flag = 1 (gct used)

0x70 | // 2-4 : color resolution = 7

0x00 | // 5 : gct sort flag = 0

palSize)); // 6-8 : gct size

out.write(0); // background color index

out.write(0); // pixel aspect ratio - assume 1:1

}



protected void writeNetscapeExt() throws IOException {

out.write(0x21); // extension introducer

out.write(0xff); // app extension label

out.write(11); // block size

writeString("NETSCAPE" + "2.0"); // app id + auth code

out.write(3); // sub-block size

out.write(1); // loop sub-block id

writeShort(repeat); // loop count (extra iterations, 0=repeat forever)

out.write(0); // block terminator

}

protected void writePalette() throws IOException {

out.write(colorTab, 0, colorTab.length);

int n = (3 * 256) - colorTab.length;

for (int i = 0; i < n; i++) {

out.write(0);

}

}



protected void writePixels() throws IOException {

LZWEncoder encoder =

new LZWEncoder(width, height, indexedPixels, colorDepth);

encoder.encode(out);

}



protected void writeShort(int value) throws IOException {

out.write(value & 0xff);

out.write((value >> 8) & 0xff);

}



protected void writeString(String s) throws IOException {

for (int i = 0; i < s.length(); i++) {

out.write((byte) s.charAt(i));

Log.i("AnimatedGifEncode...","AnimatedGifEncode is read header!!!");

}

}

}



LZWEncoder.java

class LZWEncoder {

private static final int EOF = -1;

private int imgW, imgH;

private byte[] pixAry;

private int initCodeSize;

private int remaining;

private int curPixel;

// GIFCOMPR.C - GIF Image compression routines

//

// Lempel-Ziv compression based on 'compress'. GIF modifications by

// David Rowley (mgardi@watdcsu.waterloo.edu)

// General DEFINEs

static final int BITS = 12;

static final int HSIZE = 5003; // 80% occupancy

// GIF Image compression - modified 'compress'

//

// Based on: compress.c - File compression ala IEEE Computer, June 1984.

//

// By Authors: Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas)

// Jim McKie (decvax!mcvax!jim)

// Steve Davies (decvax!vax135!petsd!peora!srd)

// Ken Turkowski (decvax!decwrl!turtlevax!ken)

// James A. Woods (decvax!ihnp4!ames!jaw)

// Joe Orost (decvax!vax135!petsd!joe)

int n_bits; // number of bits/code

int maxbits = BITS; // user settable max # bits/code

int maxcode; // maximum code, given n_bits

int maxmaxcode = 1 << BITS; // should NEVER generate this code

int[] htab = new int[HSIZE];

int[] codetab = new int[HSIZE];

int hsize = HSIZE; // for dynamic table sizing

int free_ent = 0; // first unused entry

// block compression parameters -- after all codes are used up,

// and compression rate changes, start over.

boolean clear_flg = false;

// Algorithm: use open addressing double hashing (no chaining) on the

// prefix code / next character combination. We do a variant of Knuth's

// algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime

// secondary probe. Here, the modular division first probe is gives way

// to a faster exclusive-or manipulation. Also do block compression with

// an adaptive reset, whereby the code table is cleared when the compression

// ratio decreases, but after the table fills. The variable-length output

// codes are re-sized at this point, and a special CLEAR code is generated

// for the decompressor. Late addition: construct the table according to

// file size for noticeable speed improvement on small files. Please direct

// questions about this implementation to ames!jaw.

int g_init_bits;

int ClearCode;

int EOFCode;

// output

//

// Output the given code.

// Inputs:

// code: A n_bits-bit integer. If == -1, then EOF. This assumes

// that n_bits =< wordsize - 1.

// Outputs:

// Outputs code to the file.

// Assumptions:

// Chars are 8 bits long.

// Algorithm:

// Maintain a BITS character long buffer (so that 8 codes will

// fit in it exactly). Use the VAX insv instruction to insert each

// code in turn. When the buffer fills up empty it and start over.

int cur_accum = 0;

int cur_bits = 0;

int masks[] =

{

0x0000,

0x0001,

0x0003,

0x0007,

0x000F,

0x001F,

0x003F,

0x007F,

0x00FF,

0x01FF,

0x03FF,

0x07FF,

0x0FFF,

0x1FFF,

0x3FFF,

0x7FFF,

0xFFFF };

// Number of characters so far in this 'packet'

int a_count;

// Define the storage for the packet accumulator

byte[] accum = new byte[256];

//----------------------------------------------------------------------------

LZWEncoder(int width, int height, byte[] pixels, int color_depth) {

imgW = width;

imgH = height;

pixAry = pixels;

initCodeSize = Math.max(2, color_depth);

}



// Add a character to the end of the current packet, and if it is 254

// characters, flush the packet to disk.

void char_out(byte c, OutputStream outs) throws IOException {

accum[a_count++] = c;

if (a_count >= 254)

flush_char(outs);

}



// Clear out the hash table

// table clear for block compress

void cl_block(OutputStream outs) throws IOException {

cl_hash(hsize);

free_ent = ClearCode + 2;

clear_flg = true;

output(ClearCode, outs);

}



// reset code table

void cl_hash(int hsize) {

for (int i = 0; i < hsize; ++i)

htab[i] = -1;

}



void compress(int init_bits, OutputStream outs) throws IOException {

int fcode;

int i /* = 0 */;

int c;

int ent;

int disp;

int hsize_reg;

int hshift;

// Set up the globals: g_init_bits - initial number of bits

g_init_bits = init_bits;

// Set up the necessary values

clear_flg = false;

n_bits = g_init_bits;

maxcode = MAXCODE(n_bits);

ClearCode = 1 << (init_bits - 1);

EOFCode = ClearCode + 1;

free_ent = ClearCode + 2;

a_count = 0; // clear packet

ent = nextPixel();

hshift = 0;

for (fcode = hsize; fcode < 65536; fcode *= 2)

++hshift;

hshift = 8 - hshift; // set hash code range bound

hsize_reg = hsize;

cl_hash(hsize_reg); // clear hash table

output(ClearCode, outs);

outer_loop : while ((c = nextPixel()) != EOF) {

fcode = (c << maxbits) + ent;

i = (c << hshift) ^ ent; // xor hashing

if (htab[i] == fcode) {

ent = codetab[i];

continue;

} else if (htab[i] >= 0) // non-empty slot

{

disp = hsize_reg - i; // secondary hash (after G. Knott)

if (i == 0)

disp = 1;

do {

if ((i -= disp) < 0)

i += hsize_reg;

if (htab[i] == fcode) {

ent = codetab[i];

continue outer_loop;

}

} while (htab[i] >= 0);

}

output(ent, outs);

ent = c;

if (free_ent < maxmaxcode) {

codetab[i] = free_ent++; // code -> hashtable

htab[i] = fcode;

} else

cl_block(outs);

}

// Put out the final code.

output(ent, outs);

output(EOFCode, outs);

}



//----------------------------------------------------------------------------

void encode(OutputStream os) throws IOException {

os.write(initCodeSize); // write "initial code size" byte

remaining = imgW * imgH; // reset navigation variables

curPixel = 0;

compress(initCodeSize + 1, os); // compress and write the pixel data

os.write(0); // write block terminator

}



// Flush the packet to disk, and reset the accumulator

void flush_char(OutputStream outs) throws IOException {

if (a_count > 0) {

outs.write(a_count);

outs.write(accum, 0, a_count);

a_count = 0;

}

}



final int MAXCODE(int n_bits) {

return (1 << n_bits) - 1;

}



//----------------------------------------------------------------------------

// Return the next pixel from the image

//----------------------------------------------------------------------------

private int nextPixel() {

if (remaining == 0)

return EOF;

--remaining;

byte pix = pixAry[curPixel++];

return pix & 0xff;

}



void output(int code, OutputStream outs) throws IOException {

cur_accum &= masks[cur_bits];

if (cur_bits > 0)



cur_accum |= (code << cur_bits);

else

cur_accum = code;

cur_bits += n_bits;

while (cur_bits >= 8) {

char_out((byte) (cur_accum & 0xff), outs);

cur_accum >>= 8;

cur_bits -= 8;

}

// If the next entry is going to be too big for the code size,

// then increase it, if possible.

if (free_ent > maxcode || clear_flg) {

if (clear_flg) {

maxcode = MAXCODE(n_bits = g_init_bits);

clear_flg = false;

} else {

++n_bits;

if (n_bits == maxbits)

maxcode = maxmaxcode;

else

maxcode = MAXCODE(n_bits);

}

}

if (code == EOFCode) {

// At EOF, write the rest of the buffer.

while (cur_bits > 0) {

char_out((byte) (cur_accum & 0xff), outs);

cur_accum >>= 8;

cur_bits -= 8;

}

flush_char(outs);

}

}

}



NeuQuant.java

public class NeuQuant {

protected static final int netsize = 256; /* number of colours used */

/* four primes near 500 - assume no image has a length so large */

/* that it is divisible by all four primes */

protected static final int prime1 = 499;

protected static final int prime2 = 491;

protected static final int prime3 = 487;

protected static final int prime4 = 503;

protected static final int minpicturebytes = (3 * prime4);

/* minimum size for input image */

/* Program Skeleton

----------------

[select samplefac in range 1..30]

[read image from input file]

pic = (unsigned char*) malloc(3*width*height);

initnet(pic,3*width*height,samplefac);

learn();

unbiasnet();

[write output image header, using writecolourmap(f)]

inxbuild();

write output image using inxsearch(b,g,r) */

/* Network Definitions

------------------- */

protected static final int maxnetpos = (netsize - 1);

protected static final int netbiasshift = 4; /* bias for colour values */

protected static final int ncycles = 100; /* no. of learning cycles */

/* defs for freq and bias */

protected static final int intbiasshift = 16; /* bias for fractions */

protected static final int intbias = (((int) 1) << intbiasshift);

protected static final int gammashift = 10; /* gamma = 1024 */

protected static final int gamma = (((int) 1) << gammashift);

protected static final int betashift = 10;

protected static final int beta = (intbias >> betashift); /* beta = 1/1024 */

protected static final int betagamma =

(intbias << (gammashift - betashift));

/* defs for decreasing radius factor */

protected static final int initrad = (netsize >> 3); /* for 256 cols, radius starts */

protected static final int radiusbiasshift = 6; /* at 32.0 biased by 6 bits */

protected static final int radiusbias = (((int) 1) << radiusbiasshift);

protected static final int initradius = (initrad * radiusbias); /* and decreases by a */

protected static final int radiusdec = 30; /* factor of 1/30 each cycle */

/* defs for decreasing alpha factor */

protected static final int alphabiasshift = 10; /* alpha starts at 1.0 */

protected static final int initalpha = (((int) 1) << alphabiasshift);

protected int alphadec; /* biased by 10 bits */

/* radbias and alpharadbias used for radpower calculation */

protected static final int radbiasshift = 8;

protected static final int radbias = (((int) 1) << radbiasshift);

protected static final int alpharadbshift = (alphabiasshift + radbiasshift);

protected static final int alpharadbias = (((int) 1) << alpharadbshift);

/* Types and Global Variables

-------------------------- */

protected byte[] thepicture; /* the input image itself */

protected int lengthcount; /* lengthcount = H*W*3 */

protected int samplefac; /* sampling factor 1..30 */

// typedef int pixel[4]; /* BGRc */

protected int[][] network; /* the network itself - [netsize][4] */

protected int[] netindex = new int[256];

/* for network lookup - really 256 */

protected int[] bias = new int[netsize];

/* bias and freq arrays for learning */

protected int[] freq = new int[netsize];

protected int[] radpower = new int[initrad];

/* radpower for precomputation */

/* Initialise network in range (0,0,0) to (255,255,255) and set parameters

----------------------------------------------------------------------- */

public NeuQuant(byte[] thepic, int len, int sample) {

int i;

int[] p;

thepicture = thepic;

lengthcount = len;

samplefac = sample;

network = new int[netsize][];

for (i = 0; i < netsize; i++) {

network[i] = new int[4];

p = network[i];

p[0] = p[1] = p[2] = (i << (netbiasshift + 8)) / netsize;

freq[i] = intbias / netsize; /* 1/netsize */

bias[i] = 0;

}

}



public byte[] colorMap() {

byte[] map = new byte[3 * netsize];

int[] index = new int[netsize];

for (int i = 0; i < netsize; i++)

index[network[i][3]] = i;

int k = 0;

for (int i = 0; i < netsize; i++) {

int j = index[i];

map[k++] = (byte) (network[j][0]);

map[k++] = (byte) (network[j][1]);

map[k++] = (byte) (network[j][2]);

}

return map;

}



/* Insertion sort of network and building of netindex[0..255] (to do after unbias)

------------------------------------------------------------------------------- */

public void inxbuild() {

int i, j, smallpos, smallval;

int[] p;

int[] q;

int previouscol, startpos;

previouscol = 0;

startpos = 0;

for (i = 0; i < netsize; i++) {

p = network[i];

smallpos = i;

smallval = p[1]; /* index on g */

/* find smallest in i..netsize-1 */

for (j = i + 1; j < netsize; j++) {

q = network[j];

if (q[1] < smallval) { /* index on g */

smallpos = j;

smallval = q[1]; /* index on g */

}

}

q = network[smallpos];

/* swap p (i) and q (smallpos) entries */

if (i != smallpos) {

j = q[0];

q[0] = p[0];

p[0] = j;

j = q[1];

q[1] = p[1];

p[1] = j;

j = q[2];

q[2] = p[2];

p[2] = j;

j = q[3];

q[3] = p[3];

p[3] = j;

}

/* smallval entry is now in position i */

if (smallval != previouscol) {

netindex[previouscol] = (startpos + i) >> 1;

for (j = previouscol + 1; j < smallval; j++)

netindex[j] = i;

previouscol = smallval;

startpos = i;

}

}

netindex[previouscol] = (startpos + maxnetpos) >> 1;

for (j = previouscol + 1; j < 256; j++)

netindex[j] = maxnetpos; /* really 256 */

}



/* Main Learning Loop

------------------ */

public void learn() {

int i, j, b, g, r;

int radius, rad, alpha, step, delta, samplepixels;

byte[] p;

int pix, lim;

if (lengthcount < minpicturebytes)

samplefac = 1;

alphadec = 30 + ((samplefac - 1) / 3);

p = thepicture;

pix = 0;

lim = lengthcount;

samplepixels = lengthcount / (3 * samplefac);

delta = samplepixels / ncycles;

alpha = initalpha;

radius = initradius;

rad = radius >> radiusbiasshift;

if (rad <= 1)

rad = 0;

for (i = 0; i < rad; i++)

radpower[i] =

alpha * (((rad * rad - i * i) * radbias) / (rad * rad));

//fprintf(stderr,"beginning 1D learning: initial radius=%d\n", rad);

if (lengthcount < minpicturebytes)

step = 3;

else if ((lengthcount % prime1) != 0)

step = 3 * prime1;

else {

if ((lengthcount % prime2) != 0)

step = 3 * prime2;

else {

if ((lengthcount % prime3) != 0)

step = 3 * prime3;

else

step = 3 * prime4;

}

}

i = 0;

while (i < samplepixels) {

b = (p[pix + 0] & 0xff) << netbiasshift;

g = (p[pix + 1] & 0xff) << netbiasshift;

r = (p[pix + 2] & 0xff) << netbiasshift;

j = contest(b, g, r);

altersingle(alpha, j, b, g, r);

if (rad != 0)

alterneigh(rad, j, b, g, r); /* alter neighbours */

pix += step;

if (pix >= lim)

pix -= lengthcount;

i++;

if (delta == 0)

delta = 1;

if (i % delta == 0) {

alpha -= alpha / alphadec;

radius -= radius / radiusdec;

rad = radius >> radiusbiasshift;

if (rad <= 1)

rad = 0;

for (j = 0; j < rad; j++)

radpower[j] =

alpha * (((rad * rad - j * j) * radbias) / (rad * rad));

}

}

//fprintf(stderr,"finished 1D learning: final alpha=%f !\n",((float)alpha)/initalpha);

}



/* Search for BGR values 0..255 (after net is unbiased) and return colour index

---------------------------------------------------------------------------- */

public int map(int b, int g, int r) {

int i, j, dist, a, bestd;

int[] p;

int best;

bestd = 1000; /* biggest possible dist is 256*3 */

best = -1;

i = netindex[g]; /* index on g */

j = i - 1; /* start at netindex[g] and work outwards */

while ((i < netsize) || (j >= 0)) {

if (i < netsize) {

p = network[i];

dist = p[1] - g; /* inx key */

if (dist >= bestd)

i = netsize; /* stop iter */

else {

i++;

if (dist < 0)

dist = -dist;

a = p[0] - b;

if (a < 0)

a = -a;

dist += a;

if (dist < bestd) {

a = p[2] - r;

if (a < 0)

a = -a;

dist += a;

if (dist < bestd) {

bestd = dist;

best = p[3];

}

}

}

}

if (j >= 0) {

p = network[j];

dist = g - p[1]; /* inx key - reverse dif */

if (dist >= bestd)

j = -1; /* stop iter */

else {

j--;

if (dist < 0)

dist = -dist;

a = p[0] - b;

if (a < 0)

a = -a;

dist += a;

if (dist < bestd) {

a = p[2] - r;

if (a < 0)

a = -a;

dist += a;

if (dist < bestd) {

bestd = dist;

best = p[3];

}

}

}

}

}

return (best);

}

public byte[] process() {

learn();

unbiasnet();

inxbuild();

return colorMap();

}



/* Unbias network to give byte values 0..255 and record position i to prepare for sort

----------------------------------------------------------------------------------- */

public void unbiasnet() {

int i, j;

for (i = 0; i < netsize; i++) {

network[i][0] >>= netbiasshift;

network[i][1] >>= netbiasshift;

network[i][2] >>= netbiasshift;

network[i][3] = i; /* record colour no */

}

}



/* Move adjacent neurons by precomputed alpha*(1-((i-j)^2/[r]^2)) in radpower[|i-j|]

--------------------------------------------------------------------------------- */

protected void alterneigh(int rad, int i, int b, int g, int r) {

int j, k, lo, hi, a, m;

int[] p;

lo = i - rad;

if (lo < -1)

lo = -1;

hi = i + rad;

if (hi > netsize)

hi = netsize;

j = i + 1;

k = i - 1;

m = 1;

while ((j < hi) || (k > lo)) {

a = radpower[m++];

if (j < hi) {

p = network[j++];

try {

p[0] -= (a * (p[0] - b)) / alpharadbias;

p[1] -= (a * (p[1] - g)) / alpharadbias;

p[2] -= (a * (p[2] - r)) / alpharadbias;

} catch (Exception e) {

} // prevents 1.3 miscompilation

}

if (k > lo) {

p = network[k--];

try {

p[0] -= (a * (p[0] - b)) / alpharadbias;

p[1] -= (a * (p[1] - g)) / alpharadbias;

p[2] -= (a * (p[2] - r)) / alpharadbias;

} catch (Exception e) {

}

}

}

}



/* Move neuron i towards biased (b,g,r) by factor alpha

---------------------------------------------------- */

protected void altersingle(int alpha, int i, int b, int g, int r) {

/* alter hit neuron */

int[] n = network[i];

n[0] -= (alpha * (n[0] - b)) / initalpha;

n[1] -= (alpha * (n[1] - g)) / initalpha;

n[2] -= (alpha * (n[2] - r)) / initalpha;

}



/* Search for biased BGR values

---------------------------- */

protected int contest(int b, int g, int r) {

/* finds closest neuron (min dist) and updates freq */

/* finds best neuron (min dist-bias) and returns position */

/* for frequently chosen neurons, freq[i] is high and bias[i] is negative */

/* bias[i] = gamma*((1/netsize)-freq[i]) */

int i, dist, a, biasdist, betafreq;

int bestpos, bestbiaspos, bestd, bestbiasd;

int[] n;

bestd = ~(((int) 1) << 31);

bestbiasd = bestd;

bestpos = -1;

bestbiaspos = bestpos;

for (i = 0; i < netsize; i++) {

n = network[i];

dist = n[0] - b;

if (dist < 0)

dist = -dist;

a = n[1] - g;

if (a < 0)

a = -a;

dist += a;

a = n[2] - r;

if (a < 0)

a = -a;

dist += a;

if (dist < bestd) {

bestd = dist;

bestpos = i;

}

biasdist = dist - ((bias[i]) >> (intbiasshift - netbiasshift));

if (biasdist < bestbiasd) {

bestbiasd = biasdist;

bestbiaspos = i;

}

betafreq = (freq[i] >> betashift);

freq[i] -= betafreq;

bias[i] += (betafreq << gammashift);

}

freq[bestpos] += beta;

bias[bestpos] -= betagamma;

return (bestbiaspos);

}

}

在调用的时候, jpgToGif.jpgToGif(pic, "/mnt/sdcard/1.gif"); 其中pic为一个string数组,具体内容是路径的名称,也就是多个JPEG文件的路径,1.gif为生成的gif文件,

如果有问题,可以在下面问,谢谢来看我的博客。。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: