java 中将动态gif 图片转成静态背景图片图背景颜色异常

13868人阅读
&& 这几天,一直在搞这个问题,就是想把自己所得到的多张的JPG图片文件,转成一张GIF的动画,然后让它来执行。
&&&& 刚开始的时候,也摸索了很久,这个问题,看到网上面的也有很多的方法,但是都是不能够使用,很是郁闷。其实网上的方法,也是能够用的,但是有它的局限性,一般来说,都是用的是LZW的一种GIF算法来实现这个过程,作为一名软件人员,所要做的事是使用轮子,所以,可以直接使用别人写好的算法,然后根据自己的需求来实现一些相应的功能,GIF也是如此。
&& 刚才提到了网上的一些方法,它的局限性在于,只是适用于JAVA,而不是android上,而我们的目标正是实现在andorid上,到底有什么不一样的地方呢,下面我详细说一下。
& 根据我几天以来的发现,第一种方案, android里面,也可以实现一些纯java 的程度,只是会有一些限制,例如有很多纯java 的库包在android中,并不存在,所以这个方法实现起来并不容易,故弃之。
&&& 说到这里,还是要提到网上一些适用于JAVA的方法,为什么在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. 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 closeS
& protected int colorD
& protected byte[] colorT
& protected int delay = 0;
& protected boolean firstF
& protected B
& protected byte[] indexedP
& protected OutputS
& protected int palS
& protected byte[]
& protected int repeat = -1;
& protected boolean sizeS
& protected int transI
& protected int transparent = 0;
& protected boolean[] usedE
& public AnimatedGifEncoder1()
&&& boolean[] arrayOfBoolean = new boolean[256];
&&& this.usedEntry = arrayOfB
&&& this.palSize = 7;
&&& this.dispose = -1;
&&& this.closeStream =
&&& this.firstFrame =
&&& this.sizeSet =
&&& this.sample = 10;
& public boolean addFrame(Bitmap paramBitmap)
&&& boolean ok =
&&& if(paramBitmap==null& || !started)
&&& && Log.i(&AnimatedGifEncode...&,&AnimatedGifEncode is addFrame =&+paramBitmap);
&&&&&&& if (!sizeSet)
&&&&&&&&& int i = paramBitmap.getWidth();
&&&&&&&&& int l = paramBitmap.getHeight();
&&&&&&&&& setSize(i, l);
&&&&&&& this.image = paramB
&&&&&&& getImagePixels();
&&&&&&& analyzePixels();
&&&&& if(firstFrame)
&&&&&&&&& writeLSD();
&&&&&&&&& writePalette();
&&&&&&&&& if(repeat&=0)
&&&&&&&&&&& writeNetscapeExt();
&&&&&&& writeGraphicCtrlExt();
&&&&&&& writeImageDesc();
&&&&&&& if (!firstFrame)
&&&&&&&&& writePalette();
&&&&&&& writePixels();
&&&&&&& this.firstFrame =
&&&&& catch (IOException localIOException1)
&&& && ok=
& protected void analyzePixels()
&&& int len = this.pixels.
&&& int nPix = len / 3;
&&& byte[] arrayOfByte1 = new byte[nPix];
&&& this.indexedPixels = arrayOfByte1;
&&& byte[] arrayOfByte2 = this.
&&& int k = this.
&&& NeuQuant nq = new NeuQuant(arrayOfByte2, len, k);
&&& this.colorTab = nq.process();
&&& int l = 0;
&&& int i1 = this.colorTab.
&&& Object localO
&&& if (l &= i1)
&&&&& l = 0;
&&&&& localObject =
&&& &&& for (int i = 0; i & colorTab. i += 3) {&&
&&&&&&&&&&&&&& byte temp = colorTab[i];&&
&&&&&&&&&&&&&& colorTab[i] = colorTab[i + 2];&&
&&&&&&&&&&&&&& colorTab[i + 2] =&&
&&&&&&&&&&&&&& usedEntry[i / 3] =&&
&&&&&&&&&& }&&
&&& &&& int k1 = 0;&&
&&&&&&&&&& for (int i = 0; i & nP i++) {&&
&&&&&&&&&&&&&& int index =&&
&&&&&&&&&&&&&&&&&& nq.map(pixels[k1++] & 0xff,&&
&&&&&&&&&&&&&&&&&&&&&&&&& pixels[k1++] & 0xff,&&
&&&&&&&&&&&&&&&&&&&&&&&&& pixels[k1++] & 0xff);&&
&&&&&&&&&&&&&& usedEntry[index] =&&
&&&&&&&&&&&&&& indexedPixels[i] = (byte)&&
&&&&&&&&&& }
&&&&&&&&&& pixels =&&
&&&&&&&&&& 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.&&
&&& for (int i = 0; i &) {&&
&&&&&&& 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 *&&
&&&&&&& int index = i / 3;&&
&&&&&&& if (usedEntry[index] && (d & dmin)) {&&
&&&&&&&&&&& dmin =&&
&&&&&&&&&&& minpos =&&
&&&&&&& }&&
&&&&&&& i++;&&
& public boolean finish()
&& if (!started)&&
&&&&& boolean ok =&&
&&&&& started =&&
&&&&& try {&&
&&&&&&&&& out.write(0x3b); // gif trailer&&
&&&&&&&&& out.flush();&&
&&&&&&&&& if (closeStream) {&&
&&&&&&&&&&&&& out.close();&&
&&&&&&&&& }&&
&&&&& } catch (IOException e) {&&
&&&&&&&&& ok =&&
&&&&& // reset for subsequent use&&
&&&&& transIndex = 0;&&
&&&&& out =&&
&&&&& image =&&
&&&&& pixels =&&
&&&&& indexedPixels =&&
&&&&& colorTab =&&
&&&&& closeStream =&&
&&&&& firstFrame =&&
& 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 =
&&& localBitmap1.getPixels(arrayOfInt, 0, w, k, l, i1, h);
&&& int localObject = 0;
&&& while (true)
&&&&& if (localObject &= arrayOfInt.length)
&&&&&&&&&&
&&&&& 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]);
&&&&& ++localO
& public void setDelay(int ms) {&&
&&&&& delay = Math.round(ms / 10.0f);&&
& public void setDispose(int code) {&&
&&&&& if (code &= 0) {&&
&&&&&&&&& dispose =&&
& public void setFrameRate(float fps) {&&
&&&&& if (fps != 0f) {&&
&&&&&&&&& delay = Math.round(100f / fps);&&
& public void setQuality(int quality) {&&
&&&&& if (quality & 1) quality = 1;&&
&&&&& sample =&&
& public void setRepeat(int iter) {&&
&&&&& if (iter &= 0) {&&
&&& &&& Log.i(&AnimatedGifEncode...&,&AnimatedGifEncode is setRepeat..setRepeat =&);
&&&&&&&&& repeat =&&
& public void setSize(int w, int h) {&&
&&&&& if (started && !firstFrame)&&
&&&&& width =&&
&&&&& height =&&
&&&&& if (width & 1) width = 320;&&
&&&&& if (height & 1) height = 240;&&
&&&&& sizeSet =&&
& public void setTransparent(int c)
&&& this.transparent =
& public boolean start(OutputStream os)
&&& if (os == null)&&
&&&&&& boolean ok =&&
&&&&&& closeStream =&&
&&&&&& out =&&
&&&&&& Log.i(&AnimatedGifEncode...&,&AnimatedGifEncode is start outputSteam&);
&&&&&& try {&&
&&&&&&&&&& writeString(&GIF89a&); // header&&
&&&&&& } catch (IOException e) {&&
&&&&&&&&&& ok =&&
&&&&&& }&&
&&&&&& return started =&&
& public boolean start(String file) {&&
&&&&& boolean ok =&&
&&&&& try {&&
&&&&&&&&& out = new BufferedOutputStream(new FileOutputStream(file));&&
&&&&&&&&& ok = start(out);&&
&&&&&&&&& Log.i(&AnimatedGifEncode...&,&AnimatedGifEncode is start =&+file);
&&&&&&&&& closeStream =&&
&&&&& } catch (IOException e) {&&
&&&&&&&&& ok =&&
&&&&& return started =&&
& protected void writeGraphicCtrlExt() throws IOException {&&
&&&&& out.write(0x21); // extension introducer&&
&&&&& out.write(0xf9); // GCE label&&
&&&&& out.write(4); // data block size&&
&&&&& int transp,&&
&&&&& 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.&&
&&&&& for (int i = 0; i & 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[] pixA
&private int initCodeS
&private int curP
&// GIFCOMPR.C&&&&&& - GIF Image compression routines
&// Lempel-Ziv compression based on 'compress'.& GIF modifications by
&// David Rowley ()
&// 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_ // number of bits/code
&int maxbits = BITS; // user settable max # bits/code
& // 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 =
&// 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_
&int ClearC
&// 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'
&// Define the storage for the packet accumulator
&byte[] accum = new byte[256];
&//----------------------------------------------------------------------------
&LZWEncoder(int width, int height, byte[] pixels, int color_depth) {
&&pixAry =
&&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++] =
&&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 =
&&output(ClearCode, outs);
&// reset code table
&void cl_hash(int hsize) {
&&for (int i = 0; i & ++i)
&&&htab[i] = -1;
&void compress(int init_bits, OutputStream outs) throws IOException {
&&int i /* = 0 */;
&&int hsize_
&&// Set up the globals:& g_init_bits - initial number of bits
&&g_init_bits = init_
&&// Set up the necessary values
&&clear_flg =
&&n_bits = g_init_
&&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 = fcode & 65536; fcode *= 2)
&&&++
&&hshift = 8 - // set hash code range bound
&&hsize_reg =
&&cl_hash(hsize_reg); // clear hash table
&&output(ClearCode, outs);
&&outer_loop : while ((c = nextPixel()) != EOF) {
&&&fcode = (c && maxbits) +
&&&i = (c && hshift) ^ // xor hashing
&&&if (htab[i] == fcode) {
&&&&ent = codetab[i];
&&&} else if (htab[i] &= 0) // non-empty slot
&&&&disp = hsize_reg - // secondary hash (after G. Knott)
&&&&if (i == 0)
&&&&&disp = 1;
&&&&&if ((i -= disp) & 0)
&&&&&&i += hsize_
&&&&&if (htab[i] == fcode) {
&&&&&&ent = codetab[i];
&&&&&&continue outer_
&&&&} while (htab[i] &= 0);
&&&output(ent, outs);
&&&if (free_ent & maxmaxcode) {
&&&&codetab[i] = free_ent++; // code -& hashtable
&&&&htab[i] =
&&&&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;
&&byte pix = pixAry[curPixel++];
&&return pix & 0
&void output(int code, OutputStream outs) throws IOException {
&&cur_accum &= masks[cur_bits];
&&if (cur_bits & 0)
&&&cur_accum |= (code && cur_bits);
&&&cur_accum =
&&cur_bits += n_
&&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 =
&&&} else {
&&&&++n_
&&&&if (n_bits == maxbits)
&&&&&maxcode =
&&&&&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);
& pr /* 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[] /* the input image itself */
& prote /* lengthcount = H*W*3 */
& pro /* sampling factor 1..30 */
& //&& typedef int pixel[4];&&&&&&&&&&&&&&& /* BGRc */
& protected int[][] /* 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) {
&& thepicture =
&& lengthcount =
&& samplefac =
&& network = new int[netsize][];
&& for (i = 0; i & i++) {
&&& network[i] = new int[4];
&&& p = network[i];
&&& p[0] = p[1] = p[2] = (i && (netbiasshift + 8)) /
&&& freq[i] = intbias / /* 1/netsize */
&&& bias[i] = 0;
& public byte[] colorMap() {
&& byte[] map = new byte[3 * netsize];
&& int[] index = new int[netsize];
&& for (int i = 0; i & i++)
&&& index[network[i][3]] =
&& int k = 0;
&& for (int i = 0; i & i++) {
&&& int j = index[i];
&&& map[k++] = (byte) (network[j][0]);
&&& map[k++] = (byte) (network[j][1]);
&&& map[k++] = (byte) (network[j][2]);
& /* Insertion sort of network and building of netindex[0..255] (to do after unbias)
&&&& ------------------------------------------------------------------------------- */
& public void inxbuild() {
&& int i, j, smallpos,
&& int previouscol,
&& previouscol = 0;
&& startpos = 0;
&& for (i = 0; i & i++) {
&&& p = network[i];
&&& smallpos =
&&& smallval = p[1]; /* index on g */
&&& /* find smallest in i..netsize-1 */
&&& for (j = i + 1; j & j++) {
&&&& q = network[j];
&&&& if (q[1] & smallval) { /* index on g */
&&&&& smallpos =
&&&&& 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 = q[1];
&&&& q[1] = p[1];
&&&& p[1] =
&&&& j = q[2];
&&&& q[2] = p[2];
&&&& p[2] =
&&&& j = q[3];
&&&& q[3] = p[3];
&&&& p[3] =
&&& /* smallval entry is now in position i */
&&& if (smallval != previouscol) {
&&&& netindex[previouscol] = (startpos + i) && 1;
&&&& for (j = previouscol + 1; j & j++)
&&&&& netindex[j] =
&&&& previouscol =
&&&& startpos =
&& netindex[previouscol] = (startpos + maxnetpos) && 1;
&& for (j = previouscol + 1; j & 256; j++)
&&& netindex[j] = /* really 256 */
& /* Main Learning Loop
&&&& ------------------ */
& public void learn() {
&& int i, j, b, g,
&& int radius, rad, alpha, step, delta,
&& int pix,
&& if (lengthcount & minpicturebytes)
&&& samplefac = 1;
&& alphadec = 30 + ((samplefac - 1) / 3);
&& pix = 0;
&& samplepixels = lengthcount / (3 * samplefac);
&& delta = samplepixels /
&& alpha =
&& radius =
&& rad = radius &&
&& if (rad &= 1)
&&& rad = 0;
&& for (i = 0; i & 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;
&&& if ((lengthcount % prime2) != 0)
&&&& step = 3 * prime2;
&&& else {
&&&& if ((lengthcount % prime3) != 0)
&&&&& step = 3 * prime3;
&&&&& step = 3 * prime4;
&& while (i & samplepixels) {
&&& b = (p[pix + 0] & 0xff) &&
&&& g = (p[pix + 1] & 0xff) &&
&&& r = (p[pix + 2] & 0xff) &&
&&& j = contest(b, g, r);
&&& altersingle(alpha, j, b, g, r);
&&& if (rad != 0)
&&&& alterneigh(rad, j, b, g, r); /* alter neighbours */
&&& pix +=
&&& if (pix &= lim)
&&&& pix -=
&&& i++;
&&& if (delta == 0)
&&&& delta = 1;
&&& if (i % delta == 0) {
&&&& alpha -= alpha /
&&&& radius -= radius /
&&&& rad = radius &&
&&&& if (rad &= 1)
&&&&& rad = 0;
&&&& for (j = 0; j & 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 = 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] - /* inx key */
&&&& if (dist &= bestd)
&&&&& i = /* stop iter */
&&&& else {
&&&&& i++;
&&&&& if (dist & 0)
&&&&&& dist = -
&&&&& a = p[0] -
&&&&& if (a & 0)
&&&&&& a = -a;
&&&&& dist +=
&&&&& if (dist & bestd) {
&&&&&& a = p[2] -
&&&&&& if (a & 0)
&&&&&&& a = -a;
&&&&&& dist +=
&&&&&& if (dist & bestd) {
&&&&&&& bestd =
&&&&&&& 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 = -
&&&&& a = p[0] -
&&&&& if (a & 0)
&&&&&& a = -a;
&&&&& dist +=
&&&&& if (dist & bestd) {
&&&&&& a = p[2] -
&&&&&& if (a & 0)
&&&&&&& a = -a;
&&&&&& dist +=
&&&&&& if (dist & bestd) {
&&&&&&& bestd =
&&&&&&& 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() {
&& for (i = 0; i & i++) {
&&& network[i][0] &&=
&&& network[i][1] &&=
&&& network[i][2] &&=
&&& network[i][3] = /* 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,
&& lo = i -
&& if (lo & -1)
&&& lo = -1;
&& hi = i +
&& if (hi & netsize)
&& j = i + 1;
&& k = i - 1;
&& while ((j & hi) || (k & lo)) {
&&& a = radpower[m++];
&&& if (j & hi) {
&&&& p = network[j++];
&&&& try {
&&&&& p[0] -= (a * (p[0] - b)) /
&&&&& p[1] -= (a * (p[1] - g)) /
&&&&& p[2] -= (a * (p[2] - r)) /
&&&& } catch (Exception e) {
&&&& } // prevents 1.3 miscompilation
&&& if (k & lo) {
&&&& p = network[k--];
&&&& try {
&&&&& p[0] -= (a * (p[0] - b)) /
&&&&& p[1] -= (a * (p[1] - g)) /
&&&&& p[2] -= (a * (p[2] - r)) /
&&&& } 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)) /
&& n[1] -= (alpha * (n[1] - g)) /
&& n[2] -= (alpha * (n[2] - r)) /
& /* 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,
&& int bestpos, bestbiaspos, bestd,
&& bestd = ~(((int) 1) && 31);
&& bestbiasd =
&& bestpos = -1;
&& bestbiaspos =
&& for (i = 0; i & i++) {
&&& n = network[i];
&&& dist = n[0] -
&&& if (dist & 0)
&&&& dist = -
&&& a = n[1] -
&&& if (a & 0)
&&&& a = -a;
&&& dist +=
&&& a = n[2] -
&&& if (a & 0)
&&&& a = -a;
&&& dist +=
&&& if (dist & bestd) {
&&&& bestd =
&&&& bestpos =
&&& biasdist = dist - ((bias[i]) && (intbiasshift - netbiasshift));
&&& if (biasdist & bestbiasd) {
&&&& bestbiasd =
&&&& bestbiaspos =
&&& betafreq = (freq[i] && betashift);
&&& freq[i] -=
&&& bias[i] += (betafreq && gammashift);
&& freq[bestpos] +=
&& bias[bestpos] -=
&& return (bestbiaspos);
在调用的时候,&jpgToGif.jpgToGif(pic, &/mnt/sdcard/1.gif&);&其中pic为一个string数组,具体内容是路径的名称,也就是多个JPEG文件的路径,1.gif为生成的gif文件,
如果有问题,可以在下面问,谢谢来看我的博客。。。。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:53177次
排名:千里之外
原创:16篇
评论:31条
(7)(1)(6)(8)

我要回帖

更多关于 mfc 设置静态文本颜色 的文章

 

随机推荐