前面写了利用java合并图片的文章,一位朋友说应该把gif图片不失真的合并起来,自己想想也是,可是自己技术还没过关,所以没有找到解决方法,于是上网GOOGLE一番,以外发现了一套java生成gif图片的方法,现在贴上来,跟大家共同学习。
先看一下效果图:
主方法:
- import com.sun.image.codec.jpeg.*;
- import com.sun.image.codec.*;
- import javax.imageio.*;
- import java.awt.*;
- import java.io.*;
- import java.awt.image.*;
- public class DrawImage{
- public static void main(String[] args) throws Exception{
- try{
- BufferedImage src = ImageIO.read(new File("Img221785570.jpg")); // ¶ÁÈëÎļþ
- BufferedImage src1 = ImageIO.read(new File("W.gif")); // ¶ÁÈëÎļþ
- //BufferedImage src2 = ImageIO.read(new File("c:/ship3.jpg")); // ¶ÁÈëÎļþ
- AnimatedGifEncoder e = new AnimatedGifEncoder();
- e.setRepeat(0);
- e.start("laoma.gif");
- e.setDelay(300); // 1 frame per sec
- e.addFrame(src);
- e.setDelay(100);
- e.addFrame(src1);
- e.setDelay(100);
- // e.addFrame(src2);
- e.finish();
- }catch(IOException e){
- e.printStackTrace();
- }
- }
- }
其中有两个关键类:
- import java.io.*;
- import java.awt.*;
- import java.awt.image.*;
- /**
- * Class AnimatedGifEncoder - Encodes a GIF file consisting of one or
- * more frames.
- * <pre>
- * Example:
- * AnimatedGifEncoder e = new AnimatedGifEncoder();
- * e.start(outputFileName);
- * e.setDelay(1000); // 1 frame per sec
- * e.addFrame(image1);
- * e.addFrame(image2);
- * e.finish();
- * </pre>
- * No copyright asserted on the source code of this class. May be used
- * for any purpose, however, refer to the Unisys LZW patent for restrictions
- * on use of the associated LZWEncoder class. Please forward any corrections
- * to kweiner@fmsware.com.
- *
- * @author Kevin Weiner, FM Software
- * @version 1.03 November 2003
- *
- */
- public class AnimatedGifEncoder {
- protected int width; // image size
- protected int height;
- protected Color transparent = null; // transparent color if given
- protected int transIndex; // transparent index in color table
- protected int repeat = -1; // no repeat
- protected int delay = 0; // frame delay (hundredths)
- protected boolean started = false; // ready to output frames
- protected OutputStream out;
- protected BufferedImage image; // current frame
- protected byte[] pixels; // BGR byte array from frame
- protected byte[] indexedPixels; // converted frame indexed to palette
- protected int colorDepth; // number of bit planes
- protected byte[] colorTab; // RGB palette
- protected boolean[] usedEntry = new boolean[256]; // active palette entries
- protected int palSize = 7; // color table size (bits-1)
- protected int dispose = -1; // disposal code (-1 = use default)
- protected boolean closeStream = false; // close stream when finished
- protected boolean firstFrame = true;
- protected boolean sizeSet = false; // if false, get size from first frame
- protected int sample = 10; // default sample interval for quantizer
- /**
- * Sets the delay time between each frame, or changes it
- * for subsequent frames (applies to last frame added).
- *
- * @param ms int delay time in milliseconds
- */
- public void setDelay(int ms) {
- delay = Math.round(ms / 10.0f);
- }
- /**
- * Sets the GIF frame disposal code for the last added frame
- * and any subsequent frames. Default is 0 if no transparent
- * color has been set, otherwise 2.
- * @param code int disposal code.
- */
- public void setDispose(int code) {
- if (code >= 0) {
- dispose = code;
- }
- }
- /**
- * Sets the number of times the set of GIF frames
- * should be played. Default is 1; 0 means play
- * indefinitely. Must be invoked before the first
- * image is added.
- *
- * @param iter int number of iterations.
- * @return
- */
- public void setRepeat(int iter) {
- if (iter >= 0) {
- repeat = iter;
- }
- }
- /**
- * Sets the transparent color for the last added frame
- * and any subsequent frames.
- * Since all colors are subject to modification
- * in the quantization process, the color in the final
- * palette for each frame closest to the given color
- * becomes the transparent color for that frame.
- * May be set to null to indicate no transparent color.
- *
- * @param c Color to be treated as transparent on display.
- */
- public void setTransparent(Color c) {
- transparent = c;
- }
- /**
- * Adds next GIF frame. The frame is not written immediately, but is
- * actually deferred until the next frame is received so that timing
- * data can be inserted. Invoking <code>finish()</code> flushes all
- * frames. If <code>setSize</code> was not invoked, the size of the
- * first image is used for all subsequent frames.
- *
- * @param im BufferedImage containing frame to write.
- * @return true if successful.
- */
- public boolean addFrame(BufferedImage im) {
- if ((im == null) || !started) {
- return false;
- }
- boolean ok = true;
- try {
- if (!sizeSet) {
- // use first frame's size
- setSize(im.getWidth(), im.getHeight());
- }
- image = im;
- getImagePixels(); // convert to correct format if necessary
- analyzePixels(); // build color table & map pixels
- if (firstFrame) {
- writeLSD(); // logical screen descriptior
- writePalette(); // global color table
- if (repeat >= 0) {
- // use NS app extension to indicate reps
- writeNetscapeExt();
- }
- }
- writeGraphicCtrlExt(); // write graphic control extension
- writeImageDesc(); // image descriptor
- if (!firstFrame) {
- writePalette(); // local color table
- }
- writePixels(); // encode and write pixel data
- firstFrame = false;
- } catch (IOException e) {
- ok = false;
- }
- return ok;
- }
- /**
- * Flushes any pending data and closes output file.
- * If writing to an OutputStream, the stream is not
- * closed.
- */
- 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;
- }
- /**
- * Sets frame rate in frames per second. Equivalent to
- * <code>setDelay(1000/fps)</code>.
- *
- * @param fps float frame rate (frames per second)
- */
- public void setFrameRate(float fps) {
- if (fps != 0f) {
- delay = Math.round(100f / fps);
- }
- }
- /**
- * Sets quality of color quantization (conversion of images