java生成动态gif格式与png格式的验证码(代码2)

来源:互联网 发布:hash算法的实现原理 编辑:程序博客网 时间:2024/05/01 20:33
Java代码  收藏代码
  1. import java.awt.AlphaComposite;  
  2. import java.awt.Color;  
  3. import java.awt.Font;  
  4. import java.awt.Graphics2D;  
  5. import java.awt.image.BufferedImage;  
  6. import java.io.OutputStream;  
  7. import java.util.Random;  
  8.   
  9. /** 
  10.  * Gif验证码类 
  11.  * @author wzztestin 
  12.  * 
  13.  */  
  14. public class GifCaptcha extends Captcha {  
  15.     public GifCaptcha() {  
  16.     }  
  17.   
  18.     public GifCaptcha(int width, int height) {  
  19.         this.width = width;  
  20.         this.height = height;  
  21.     }  
  22.   
  23.     public GifCaptcha(int width, int height, int alpha) {  
  24.         this(width, height);  
  25.     }  
  26.   
  27.     public GifCaptcha(int width, int height, int alpha, Font font) {  
  28.         this(width, height, alpha);  
  29.         this.font = font;  
  30.     }  
  31.   
  32.     @Override  
  33.     public void out(OutputStream os) {  
  34.         try {  
  35.             //是一个用来生成 GIF 图片格式的 Java 图形处理类库  
  36.             GifEncoder gifEncoder = new GifEncoder();  
  37.             //生成字符  
  38.             gifEncoder.start(os);  
  39.             //品质  
  40.             gifEncoder.setQuality(180);  
  41.             //推迟  
  42.             gifEncoder.setDelay(200);  
  43.             //重复  
  44.             gifEncoder.setRepeat(0);  
  45.             BufferedImage frame;  
  46.             char[] rands = this.getYanzhenmastr().toCharArray();  
  47.             Color fontcolor[] = new Color[rands.length];  
  48.             for (int i = 0; i < rands.length; i++) {  
  49.                 fontcolor[i] = new Color(20 + Randoms.num(110),  
  50.                         20 + Randoms.num(110), 20 + Randoms.num(110));  
  51.             }  
  52.             int start = 8;  
  53.             for (int i = 0; i < rands.length; i++) {  
  54.                 frame = graphicsImage(fontcolor, rands, i,start);  
  55.                 //添加帧图  
  56.                 gifEncoder.addFrame(frame);  
  57.                 start = start + 8;  
  58.                 //输出  
  59.                 frame.flush();  
  60.             }  
  61.             gifEncoder.finish();  
  62.         } finally {  
  63.             Streams.close(os);  
  64.         }  
  65.   
  66.     }  
  67.   
  68.     /** 
  69.      * 画随机码图 
  70.      *  
  71.      * @param fontcolor 
  72.      *            随机字体颜色 
  73.      * @param strs 
  74.      *            字符数组 
  75.      * @param flag 
  76.      *            透明度使用 
  77.      * @return BufferedImage 
  78.      */  
  79.     private BufferedImage graphicsImage(Color[] fontcolor, char[] strs, int flag,int start) {  
  80.         BufferedImage image = new BufferedImage(width, height,  
  81.                 BufferedImage.TYPE_INT_RGB);  
  82.         Random r = new Random();  
  83.         // 或得图形上下文  
  84.         // Graphics2D g2d=image.createGraphics();  
  85.         Graphics2D g2d = (Graphics2D) image.getGraphics();  
  86.         // 利用指定颜色填充背景  
  87.         g2d.setColor(Color.WHITE);  
  88.         g2d.fillRect(00, width, height);  
  89.         g2d.setColor(getRandColor(120200));  
  90.         for (int i = 0; i < 200; i++) {  
  91.             int x = r.nextInt(width - 1);  
  92.             int y = r.nextInt(height - 1);  
  93.             int xl = r.nextInt(6) + 1;  
  94.             int yl = r.nextInt(12) + 1;  
  95.             g2d.drawLine(x, y, x + xl, y + yl);  
  96.         }  
  97.         for (int i = 0; i < 100; i++) {  
  98.             int x = r.nextInt(width - 1);  
  99.             int y = r.nextInt(height - 1);  
  100.             int xl = r.nextInt(12) + 1;  
  101.             int yl = r.nextInt(6) + 1;  
  102.             g2d.drawLine(x, y, x - xl, y - yl);  
  103.         }   
  104.         int degree = r.nextInt(20);//旋转度数 最好小于45度      
  105.         if (flag % 2 == 1){  
  106.             degree = degree * (-1);    
  107.         }  
  108.         g2d.rotate(Math.toRadians(degree), start, 21);    
  109.   
  110.         //类实现一些基本的 alpha 合成规则,将源色与目标色组合,在图形和图像中实现混合和透明效果。  
  111.         AlphaComposite ac3;  
  112.         //得到写入所需的宽和高  
  113.         int h = height - ((height - font.getSize()) >> 1);  
  114.         int w = width / strs.length;  
  115.         //设置字体  
  116.         g2d.setFont(font);  
  117.         //画圈和字符  
  118.         for (int i = 0; i < strs.length; i++) {  
  119.             ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER,  
  120.                     getAlpha(flag, i));  
  121.             g2d.setComposite(ac3);  
  122.             g2d.setColor(fontcolor[i]);  
  123.             //画圈  
  124.             g2d.drawOval(Randoms.num(width), Randoms.num(height),  
  125.                     5 + Randoms.num(10), 5 + Randoms.num(10));  
  126.             //画字  
  127.             g2d.drawString(strs[i] + "",  
  128.                     (width - (strs.length - i) * w) + (w - font.getSize()) + 1, h - 4);  
  129.         }  
  130.         g2d.rotate(-Math.toRadians(degree), start, 21);//旋转之后,必须旋转回来    
  131.         g2d.dispose();  
  132.         return image;  
  133.     }  
  134.   
  135.     /** 
  136.      * 获取透明度,从0到1,自动计算步长 
  137.      *  
  138.      * @return float 透明度 
  139.      */  
  140.     private float getAlpha(int i, int j) {  
  141.         int num = i + j;  
  142.         float r = (float1 / alpha, s = (alpha + 1) * r;  
  143.         float value = num > 5 ? (num * r - s) : num * r;  
  144.         if(value > 1.0f){  
  145.             value = 1.0f;  
  146.         }  
  147.         return value;  
  148.     }  
  149.   
  150. }  

 

Java代码  收藏代码
  1. import java.awt.AlphaComposite;  
  2. import java.awt.Color;  
  3. import java.awt.Dimension;  
  4. import java.awt.Graphics2D;  
  5. import java.awt.Rectangle;  
  6. import java.awt.image.BufferedImage;  
  7. import java.awt.image.DataBufferInt;  
  8. import java.io.BufferedInputStream;  
  9. import java.io.FileInputStream;  
  10. import java.io.IOException;  
  11. import java.io.InputStream;  
  12. import java.net.URL;  
  13. import java.util.ArrayList;  
  14.   
  15. /** 
  16.  *  
  17.  * @author wzztestin 
  18.  * 
  19.  */  
  20. public class GifDecoder {  
  21.     /** 
  22.      * File read status: No errors. 
  23.      */  
  24.     public static final int STATUS_OK = 0;  
  25.   
  26.     /** 
  27.      * File read status: Error decoding file (may be partially decoded) 
  28.      */  
  29.     public static final int STATUS_FORMAT_ERROR = 1;  
  30.   
  31.     /** 
  32.      * File read status: Unable to open source. 
  33.      */  
  34.     public static final int STATUS_OPEN_ERROR = 2;  
  35.   
  36.     protected BufferedInputStream in;  
  37.     protected int status;  
  38.   
  39.     protected int width; // full image width  
  40.     protected int height; // full image height  
  41.     protected boolean gctFlag; // global color table used  
  42.     protected int gctSize; // size of global color table  
  43.     protected int loopCount = 1// iterations; 0 = repeat forever  
  44.   
  45.     protected int[] gct; // global color table  
  46.     protected int[] lct; // local color table  
  47.     protected int[] act; // active color table  
  48.   
  49.     protected int bgIndex; // background color index  
  50.     protected int bgColor; // background color  
  51.     protected int lastBgColor; // previous bg color  
  52.     protected int pixelAspect; // pixel aspect ratio  
  53.   
  54.     protected boolean lctFlag; // local color table flag  
  55.     protected boolean interlace; // interlace flag  
  56.     protected int lctSize; // local color table size  
  57.   
  58.     protected int ix, iy, iw, ih; // current image rectangle  
  59.     protected Rectangle lastRect; // last image rect  
  60.     protected BufferedImage image; // current frame  
  61.     protected BufferedImage lastImage; // previous frame  
  62.   
  63.     protected byte[] block = new byte[256]; // current data block  
  64.     protected int blockSize = 0// block size  
  65.   
  66.     // last graphic control extension info  
  67.     protected int dispose = 0;  
  68.     // 0=no action; 1=leave in place; 2=restore to bg; 3=restore to prev  
  69.     protected int lastDispose = 0;  
  70.     protected boolean transparency = false// use transparent color  
  71.     protected int delay = 0// delay in milliseconds  
  72.     protected int transIndex; // transparent color index  
  73.   
  74.     protected static final int MaxStackSize = 4096;  
  75.     // max decoder pixel stack size  
  76.   
  77.     // LZW decoder working arrays  
  78.     protected short[] prefix;  
  79.     protected byte[] suffix;  
  80.     protected byte[] pixelStack;  
  81.     protected byte[] pixels;  
  82.   
  83.     protected ArrayList<GifFrame> frames; // frames read from current file  
  84.     protected int frameCount;  
  85.   
  86.     static class GifFrame {  
  87.         public GifFrame(BufferedImage im, int del) {  
  88.             image = im;  
  89.             delay = del;  
  90.         }  
  91.   
  92.         public BufferedImage image;  
  93.         public int delay;  
  94.     }  
  95.   
  96.     /** 
  97.      * Gets display duration for specified frame. 
  98.      *  
  99.      * @param n 
  100.      *            int index of frame 
  101.      * @return delay in milliseconds 
  102.      */  
  103.     public int getDelay(int n) {  
  104.         //  
  105.         delay = -1;  
  106.         if ((n >= 0) && (n < frameCount)) {  
  107.             delay = (frames.get(n)).delay;  
  108.         }  
  109.         return delay;  
  110.     }  
  111.   
  112.     /** 
  113.      * Gets the number of frames read from file. 
  114.      *  
  115.      * @return frame count 
  116.      */  
  117.     public int getFrameCount() {  
  118.         return frameCount;  
  119.     }  
  120.   
  121.     /** 
  122.      * Gets the first (or only) image read. 
  123.      *  
  124.      * @return BufferedImage containing first frame, or null if none. 
  125.      */  
  126.     public BufferedImage getImage() {  
  127.         return getFrame(0);  
  128.     }  
  129.   
  130.     /** 
  131.      * Gets the "Netscape" iteration count, if any. A count of 0 means repeat 
  132.      * indefinitiely. 
  133.      *  
  134.      * @return iteration count if one was specified, else 1. 
  135.      */  
  136.     public int getLoopCount() {  
  137.         return loopCount;  
  138.     }  
  139.   
  140.     /** 
  141.      * Creates new frame image from current data (and previous frames as 
  142.      * specified by their disposition codes). 
  143.      */  
  144.     protected void setPixels() {  
  145.         // expose destination image's pixels as int array  
  146.         int[] dest = ((DataBufferInt) image.getRaster().getDataBuffer())  
  147.                 .getData();  
  148.   
  149.         // fill in starting image contents based on last image's dispose code  
  150.         if (lastDispose > 0) {  
  151.             if (lastDispose == 3) {  
  152.                 // use image before last  
  153.                 int n = frameCount - 2;  
  154.                 if (n > 0) {  
  155.                     lastImage = getFrame(n - 1);  
  156.                 } else {  
  157.                     lastImage = null;  
  158.                 }  
  159.             }  
  160.   
  161.             if (lastImage != null) {  
  162.                 int[] prev = ((DataBufferInt) lastImage.getRaster()  
  163.                         .getDataBuffer()).getData();  
  164.                 System.arraycopy(prev, 0, dest, 0, width * height);  
  165.                 // copy pixels  
  166.   
  167.                 if (lastDispose == 2) {  
  168.                     // fill last image rect area with background color  
  169.                     Graphics2D g = image.createGraphics();  
  170.                     Color c = null;  
  171.                     if (transparency) {  
  172.                         c = new Color(0000); // assume background is  
  173.                                                     // transparent  
  174.                     } else {  
  175.                         c = new Color(lastBgColor); // use given background  
  176.                                                     // color  
  177.                     }  
  178.                     g.setColor(c);  
  179.                     g.setComposite(AlphaComposite.Src); // replace area  
  180.                     g.fill(lastRect);  
  181.                     g.dispose();  
  182.                 }  
  183.             }  
  184.         }  
  185.   
  186.         // copy each source line to the appropriate place in the destination  
  187.         int pass = 1;  
  188.         int inc = 8;  
  189.         int iline = 0;  
  190.         for (int i = 0; i < ih; i++) {  
  191.             int line = i;  
  192.             if (interlace) {  
  193.                 if (iline >= ih) {  
  194.                     pass++;  
  195.                     switch (pass) {  
  196.                     case 2:  
  197.                         iline = 4;  
  198.                         break;  
  199.                     case 3:  
  200.                         iline = 2;  
  201.                         inc = 4;  
  202.                         break;  
  203.                     case 4:  
  204.                         iline = 1;  
  205.                         inc = 2;  
  206.                     }  
  207.                 }  
  208.                 line = iline;  
  209.                 iline += inc;  
  210.             }  
  211.             line += iy;  
  212.             if (line < height) {  
  213.                 int k = line * width;  
  214.                 int dx = k + ix; // start of line in dest  
  215.                 int dlim = dx + iw; // end of dest line  
  216.                 if ((k + width) < dlim) {  
  217.                     dlim = k + width; // past dest edge  
  218.                 }  
  219.                 int sx = i * iw; // start of line in source  
  220.                 while (dx < dlim) {  
  221.                     // map color and insert in destination  
  222.                     int index = ((int) pixels[sx++]) & 0xff;  
  223.                     int c = act[index];  
  224.                     if (c != 0) {  
  225.                         dest[dx] = c;  
  226.                     }  
  227.                     dx++;  
  228.                 }  
  229.             }  
  230.         }  
  231.     }  
  232.   
  233.     /** 
  234.      * Gets the image contents of frame n. 
  235.      *  
  236.      * @return BufferedImage representation of frame, or null if n is invalid. 
  237.      */  
  238.     public BufferedImage getFrame(int n) {  
  239.         BufferedImage im = null;  
  240.         if ((n >= 0) && (n < frameCount)) {  
  241.             im = (frames.get(n)).image;  
  242.         }  
  243.         return im;  
  244.     }  
  245.   
  246.     /** 
  247.      * Gets image size. 
  248.      *  
  249.      * @return GIF image dimensions 
  250.      */  
  251.     public Dimension getFrameSize() {  
  252.         return new Dimension(width, height);  
  253.     }  
  254.   
  255.     /** 
  256.      * Reads GIF image from stream 
  257.      *  
  258.      * @param is 
  259.      *            BufferedInputStream containing GIF file. 
  260.      * @return read status code (0 = no errors) 
  261.      */  
  262.     public int read(BufferedInputStream is) {  
  263.         init();  
  264.         try {  
  265.             if (is != null) {  
  266.                 in = is;  
  267.                 readHeader();  
  268.                 if (!err()) {  
  269.                     readContents();  
  270.                     if (frameCount < 0) {  
  271.                         status = STATUS_FORMAT_ERROR;  
  272.                     }  
  273.                 }  
  274.             } else {  
  275.                 status = STATUS_OPEN_ERROR;  
  276.             }  
  277.         } finally {  
  278.             Streams.close(is);  
  279.         }  
  280.         return status;  
  281.     }  
  282.   
  283.     /** 
  284.      * Reads GIF image from stream 
  285.      *  
  286.      * @param is 
  287.      *            InputStream containing GIF file. 
  288.      * @return read status code (0 = no errors) 
  289.      */  
  290.     public int read(InputStream is) {  
  291.         init();  
  292.         try {  
  293.             if (is != null) {  
  294.                 if (!(is instanceof BufferedInputStream))  
  295.                     is = new BufferedInputStream(is);  
  296.                 in = (BufferedInputStream) is;  
  297.                 readHeader();  
  298.                 if (!err()) {  
  299.                     readContents();  
  300.                     if (frameCount < 0) {  
  301.                         status = STATUS_FORMAT_ERROR;  
  302.                     }  
  303.                 }  
  304.             } else {  
  305.                 status = STATUS_OPEN_ERROR;  
  306.             }  
  307.         } finally {  
  308.             Streams.close(is);  
  309.         }  
  310.         return status;  
  311.     }  
  312.   
  313.     /** 
  314.      * Reads GIF file from specified file/URL source (URL assumed if name 
  315.      * contains ":/" or "file:") 
  316.      *  
  317.      * @param name 
  318.      *            String containing source 
  319.      * @return read status code (0 = no errors) 
  320.      */  
  321.     public int read(String name) {  
  322.         status = STATUS_OK;  
  323.         try {  
  324.             name = name.trim().toLowerCase();  
  325.             if ((name.contains("file:")) || (name.indexOf(":/") > 0)) {  
  326.                 URL url = new URL(name);  
  327.                 in = new BufferedInputStream(url.openStream());  
  328.             } else {  
  329.                 in = new BufferedInputStream(new FileInputStream(name));  
  330.             }  
  331.             status = read(in);  
  332.         } catch (IOException e) {  
  333.             status = STATUS_OPEN_ERROR;  
  334.         }  
  335.   
  336.         return status;  
  337.     }  
  338.   
  339.     /** 
  340.      * Decodes LZW image data into pixel array. Adapted from John Cristy's 
  341.      * ImageMagick. 
  342.      */  
  343.     protected void decodeImageData() {  
  344.         int NullCode = -1;  
  345.         int npix = iw * ih;  
  346.         int available, clear, code_mask, code_size, end_of_information, in_code, old_code, bits, code, count, i, datum, data_size, first, top, bi, pi;  
  347.   
  348.         if ((pixels == null) || (pixels.length < npix)) {  
  349.             pixels = new byte[npix]; // allocate new pixel array  
  350.         }  
  351.         if (prefix == null)  
  352.             prefix = new short[MaxStackSize];  
  353.         if (suffix == null)  
  354.             suffix = new byte[MaxStackSize];  
  355.         if (pixelStack == null)  
  356.             pixelStack = new byte[MaxStackSize + 1];  
  357.   
  358.         // Initialize GIF data stream decoder.  
  359.   
  360.         data_size = read();  
  361.         clear = 1 << data_size;  
  362.         end_of_information = clear + 1;  
  363.         available = clear + 2;  
  364.         old_code = NullCode;  
  365.         code_size = data_size + 1;  
  366.         code_mask = (1 << code_size) - 1;  
  367.         for (code = 0; code < clear; code++) {  
  368.             prefix[code] = 0;  
  369.             suffix[code] = (byte) code;  
  370.         }  
  371.   
  372.         // Decode GIF pixel stream.  
  373.   
  374.         datum = bits = count = first = top = pi = bi = 0;  
  375.   
  376.         for (i = 0; i < npix;) {  
  377.             if (top == 0) {  
  378.                 if (bits < code_size) {  
  379.                     // Load bytes until there are enough bits for a code.  
  380.                     if (count == 0) {  
  381.                         // Read a new data block.  
  382.                         count = readBlock();  
  383.                         if (count <= 0)  
  384.                             break;  
  385.                         bi = 0;  
  386.                     }  
  387.                     datum += (((int) block[bi]) & 0xff) << bits;  
  388.                     bits += 8;  
  389.                     bi++;  
  390.                     count--;  
  391.                     continue;  
  392.                 }  
  393.   
  394.                 // Get the next code.  
  395.   
  396.                 code = datum & code_mask;  
  397.                 datum >>= code_size;  
  398.                 bits -= code_size;  
  399.   
  400.                 // Interpret the code  
  401.   
  402.                 if ((code > available) || (code == end_of_information))  
  403.                     break;  
  404.                 if (code == clear) {  
  405.                     // Reset decoder.  
  406.                     code_size = data_size + 1;  
  407.                     code_mask = (1 << code_size) - 1;  
  408.                     available = clear + 2;  
  409.                     old_code = NullCode;  
  410.                     continue;  
  411.                 }  
  412.                 if (old_code == NullCode) {  
  413.                     pixelStack[top++] = suffix[code];  
  414.                     old_code = code;  
  415.                     first = code;  
  416.                     continue;  
  417.                 }  
  418.                 in_code = code;  
  419.                 if (code == available) {  
  420.                     pixelStack[top++] = (byte) first;  
  421.                     code = old_code;  
  422.                 }  
  423.                 while (code > clear) {  
  424.                     pixelStack[top++] = suffix[code];  
  425.                     code = prefix[code];  
  426.                 }  
  427.                 first = ((int) suffix[code]) & 0xff;  
  428.   
  429.                 // Add a new string to the string table,  
  430.   
  431.                 if (available >= MaxStackSize)  
  432.                     break;  
  433.                 pixelStack[top++] = (byte) first;  
  434.                 prefix[available] = (short) old_code;  
  435.                 suffix[available] = (byte) first;  
  436.                 available++;  
  437.                 if (((available & code_mask) == 0)  
  438.                         && (available < MaxStackSize)) {  
  439.                     code_size++;  
  440.                     code_mask += available;  
  441.                 }  
  442.                 old_code = in_code;  
  443.             }  
  444.   
  445.             // Pop a pixel off the pixel stack.  
  446.   
  447.             top--;  
  448.             pixels[pi++] = pixelStack[top];  
  449.             i++;  
  450.         }  
  451.   
  452.         for (i = pi; i < npix; i++) {  
  453.             pixels[i] = 0// clear missing pixels  
  454.         }  
  455.   
  456.     }  
  457.   
  458.     /** 
  459.      * Returns true if an error was encountered during reading/decoding 
  460.      */  
  461.     protected boolean err() {  
  462.         return status != STATUS_OK;  
  463.     }  
  464.   
  465.     /** 
  466.      * Initializes or re-initializes reader 
  467.      */  
  468.     protected void init() {  
  469.         status = STATUS_OK;  
  470.         frameCount = 0;  
  471.         frames = new ArrayList<GifFrame>();  
  472.         gct = null;  
  473.         lct = null;  
  474.     }  
  475.   
  476.     /** 
  477.      * Reads a single byte from the input stream. 
  478.      */  
  479.     protected int read() {  
  480.         int curByte = 0;  
  481.         try {  
  482.             curByte = in.read();  
  483.         } catch (IOException e) {  
  484.             status = STATUS_FORMAT_ERROR;  
  485.         }  
  486.         return curByte;  
  487.     }  
  488.   
  489.     /** 
  490.      * Reads next variable length block from input. 
  491.      *  
  492.      * @return number of bytes stored in "buffer" 
  493.      */  
  494.     protected int readBlock() {  
  495.         blockSize = read();  
  496.         int n = 0;  
  497.         if (blockSize > 0) {  
  498.             try {  
  499.                 int count = 0;  
  500.                 while (n < blockSize) {  
  501.                     count = in.read(block, n, blockSize - n);  
  502.                     if (count == -1)  
  503.                         break;  
  504.                     n += count;  
  505.                 }  
  506.             } catch (IOException ignored) {  
  507.             }  
  508.   
  509.             if (n < blockSize) {  
  510.                 status = STATUS_FORMAT_ERROR;  
  511.             }  
  512.         }  
  513.         return n;  
  514.     }  
  515.   
  516.     /** 
  517.      * Reads color table as 256 RGB integer values 
  518.      *  
  519.      * @param ncolors 
  520.      *            int number of colors to read 
  521.      * @return int array containing 256 colors (packed ARGB with full alpha) 
  522.      */  
  523.     protected int[] readColorTable(int ncolors) {  
  524.         int nbytes = 3 * ncolors;  
  525.         int[] tab = null;  
  526.         byte[] c = new byte[nbytes];  
  527.         int n = 0;  
  528.         try {  
  529.             n = in.read(c);  
  530.         } catch (IOException ignored) {  
  531.         }  
  532.         if (n < nbytes) {  
  533.             status = STATUS_FORMAT_ERROR;  
  534.         } else {  
  535.             tab = new int[256]; // max size to avoid bounds checks  
  536.             int i = 0;  
  537.             int j = 0;  
  538.             while (i < ncolors) {  
  539.                 int r = ((int) c[j++]) & 0xff;  
  540.                 int g = ((int) c[j++]) & 0xff;  
  541.                 int b = ((int) c[j++]) & 0xff;  
  542.                 tab[i++] = 0xff000000 | (r << 16) | (g << 8) | b;  
  543.             }  
  544.         }  
  545.         return tab;  
  546.     }  
  547.   
  548.     /** 
  549.      * Main file parser. Reads GIF content blocks. 
  550.      */  
  551.     protected void readContents() {  
  552.         // read GIF file content blocks  
  553.         boolean done = false;  
  554.         while (!(done || err())) {  
  555.             int code = read();  
  556.             switch (code) {  
  557.   
  558.             case 0x2C// image separator  
  559.                 readImage();  
  560.                 break;  
  561.   
  562.             case 0x21// extension  
  563.                 code = read();  
  564.                 switch (code) {  
  565.                 case 0xf9// graphics control extension  
  566.                     readGraphicControlExt();  
  567.                     break;  
  568.   
  569.                 case 0xff// application extension  
  570.                     readBlock();  
  571.                     String app = "";  
  572.                     for (int i = 0; i < 11; i++) {  
  573.                         app += (char) block[i];  
  574.                     }  
  575.                     if (app.equals("NETSCAPE2.0")) {  
  576.                         readNetscapeExt();  
  577.                     } else  
  578.                         skip(); // don't care  
  579.                     break;  
  580.   
  581.                 default// uninteresting extension  
  582.                     skip();  
  583.                 }  
  584.                 break;  
  585.   
  586.             case 0x3b// terminator  
  587.                 done = true;  
  588.                 break;  
  589.   
  590.             case 0x00// bad byte, but keep going and see what happens  
  591.                 break;  
  592.   
  593.             default:  
  594.                 status = STATUS_FORMAT_ERROR;  
  595.             }  
  596.         }  
  597.     }  
  598.   
  599.     /** 
  600.      * Reads Graphics Control Extension values 
  601.      */  
  602.     protected void readGraphicControlExt() {  
  603.         read(); // block size  
  604.         int packed = read(); // packed fields  
  605.         dispose = (packed & 0x1c) >> 2// disposal method  
  606.         if (dispose == 0) {  
  607.             dispose = 1// elect to keep old image if discretionary  
  608.         }  
  609.         transparency = (packed & 1) != 0;  
  610.         delay = readShort() * 10// delay in milliseconds  
  611.         transIndex = read(); // transparent color index  
  612.         read(); // block terminator  
  613.     }  
  614.   
  615.     /** 
  616.      * Reads GIF file header information. 
  617.      */  
  618.     protected void readHeader() {  
  619.         String id = "";  
  620.         for (int i = 0; i < 6; i++) {  
  621.             id += (char) read();  
  622.         }  
  623.         if (!id.startsWith("GIF")) {  
  624.             status = STATUS_FORMAT_ERROR;  
  625.             return;  
  626.         }  
  627.   
  628.         readLSD();  
  629.         if (gctFlag && !err()) {  
  630.             gct = readColorTable(gctSize);  
  631.             bgColor = gct[bgIndex];  
  632.         }  
  633.     }  
  634.   
  635.     /** 
  636.      * Reads next frame image 
  637.      */  
  638.     protected void readImage() {  
  639.         ix = readShort(); // (sub)image position & size  
  640.         iy = readShort();  
  641.         iw = readShort();  
  642.         ih = readShort();  
  643.   
  644.         int packed = read();  
  645.         lctFlag = (packed & 0x80) != 0// 1 - local color table flag  
  646.         interlace = (packed & 0x40) != 0// 2 - interlace flag  
  647.         // 3 - sort flag  
  648.         // 4-5 - reserved  
  649.         lctSize = 2 << (packed & 7); // 6-8 - local color table size  
  650.   
  651.         if (lctFlag) {  
  652.             lct = readColorTable(lctSize); // read table  
  653.             act = lct; // make local table active  
  654.         } else {  
  655.             act = gct; // make global table active  
  656.             if (bgIndex == transIndex)  
  657.                 bgColor = 0;  
  658.         }  
  659.         int save = 0;  
  660.         if (transparency) {  
  661.             save = act[transIndex];  
  662.             act[transIndex] = 0// set transparent color if specified  
  663.         }  
  664.   
  665.         if (act == null) {  
  666.             status = STATUS_FORMAT_ERROR; // no color table defined  
  667.         }  
  668.   
  669.         if (err())  
  670.             return;  
  671.   
  672.         decodeImageData(); // decode pixel data  
  673.         skip();  
  674.   
  675.         if (err())  
  676.             return;  
  677.   
  678.         frameCount++;  
  679.   
  680.         // create new image to receive frame data  
  681.         image = new BufferedImage(width, height,  
  682.                 BufferedImage.TYPE_INT_ARGB_PRE);  
  683.   
  684.         setPixels(); // transfer pixel data to image  
  685.   
  686.         frames.add(new GifFrame(image, delay)); // add image to frame list  
  687.   
  688.         if (transparency) {  
  689.             act[transIndex] = save;  
  690.         }  
  691.         resetFrame();  
  692.   
  693.     }  
  694.   
  695.     /** 
  696.      * Reads Logical Screen Descriptor 
  697.      */  
  698.     protected void readLSD() {  
  699.   
  700.         // logical screen size  
  701.         width = readShort();  
  702.         height = readShort();  
  703.   
  704.         // packed fields  
  705.         int packed = read();  
  706.         gctFlag = (packed & 0x80) != 0// 1 : global color table flag  
  707.         // 2-4 : color resolution  
  708.         // 5 : gct sort flag  
  709.         gctSize = 2 << (packed & 7); // 6-8 : gct size  
  710.   
  711.         bgIndex = read(); // background color index  
  712.         pixelAspect = read(); // pixel aspect ratio  
  713.     }  
  714.   
  715.     /** 
  716.      * Reads Netscape extenstion to obtain iteration count 
  717.      */  
  718.     protected void readNetscapeExt() {  
  719.         do {  
  720.             readBlock();  
  721.             if (block[0] == 1) {  
  722.                 // loop count sub-block  
  723.                 int b1 = ((int) block[1]) & 0xff;  
  724.                 int b2 = ((int) block[2]) & 0xff;  
  725.                 loopCount = (b2 << 8) | b1;  
  726.             }  
  727.         } while ((blockSize > 0) && !err());  
  728.     }  
  729.   
  730.     /** 
  731.      * Reads next 16-bit value, LSB first 
  732.      */  
  733.     protected int readShort() {  
  734.         // read 16-bit value, LSB first  
  735.         return read() | (read() << 8);  
  736.     }  
  737.   
  738.     /** 
  739.      * Resets frame state for reading next image. 
  740.      */  
  741.     @SuppressWarnings("unused")  
  742.     protected void resetFrame() {  
  743.         lastDispose = dispose;  
  744.         lastRect = new Rectangle(ix, iy, iw, ih);  
  745.         lastImage = image;  
  746.         lastBgColor = bgColor;  
  747.         int dispose = 0;  
  748.         boolean transparency = false;  
  749.         int delay = 0;  
  750.         lct = null;  
  751.     }  
  752.   
  753.     /** 
  754.      * Skips variable length blocks up to and including next zero length block. 
  755.      */  
  756.     protected void skip() {  
  757.         do {  
  758.             readBlock();  
  759.         } while ((blockSize > 0) && !err());  
  760.     }  
  761. }  
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 【题目2】设计一个结构体类型,包含姓名、出生日期。其中出生日期又包含年、月、日三部分信息。输入n个好 【题目2】设计一个结构体类型,包含姓名、出生日期。其中出生日期又包含年、月、日三部分信息。输入n个好 结构体比较好友中年纪最小的 matlab三维矩阵可视化 使QQ崩溃 scanIP 按照规定,在高速公路上行使的机动车,达到或超出本车道限速的10%则处200元罚款;若达到或超出50% c语言输入三个数字 c语言如何输入三个数求平均值 c语言如何输入三个数求和 C语言为什么只录入了第一个数字 输入多个数字 c语言scanf只有第一个数字 scanf三个整数 double double类型 www和http 会计 日记账 myamnatfound IntroductiontoIoT IntroductiontoIoT 使用哪种类型的无线网络连接城市中的设备来创建城域网 傲世九重天绿帽版 节日 第一章《Java》的思维导图 《Java》的思维导图 python登录大华摄像机 2019普通高等学校招生全国统一考试诊断卷a 考前诊断卷 Travelingsalesmenofnhn.(theprestigiousKoreanintern www。qwer123。com Ubuntu --------------------------http://s.jiafeiyun.com/p getpid函数执行过程 增量模型 Hresult:0x80041966 qt音视频 verilig verilogifinput 安卓代码