⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gifcom.java

📁 利用lzw算法将.bmp图像文件压缩成.gif文件 点击打开载入图像
💻 JAVA
字号:
package gifcode;

import java.io.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.*;
import javax.imageio.ImageIO;
import javax.swing.*;

public class GIFCom extends JFrame implements ActionListener{

	protected int width; // image size
	protected int height;
	protected Color transparent = null; // transparent color
	protected int transIndex; // transparent index in color table
	protected boolean started = false; // ready to output frames
	protected OutputStream out;
	protected BufferedImage image;
	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; 
	protected boolean closeStream = false; // close stream when finished
	protected boolean isImage = true;
	protected boolean sizeSet = false; 
	protected int sample = 10; 

	String filesplit=new String();
	JButton buttonCom=new JButton("打开");
	JButton buttonDecom=new JButton("压缩");
	JLabel labelMes=new JLabel();
	JFileChooser fc=new JFileChooser();
	JPanel panel=new JPanel();
	BufferedImage src;
	String filename;
	
	GIFCom(){
		super("GIF压缩演示");
		Container con=this.getContentPane();
		con.setLayout(new BorderLayout());
		panel.add(buttonCom);
		panel.add(buttonDecom);
		buttonCom.addActionListener(this);
		buttonDecom.addActionListener(this);
		con.add(panel,"South");
		con.add(labelMes,"Center");
		this.setSize(600, 450);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setVisible(true);
	}
	
	public boolean toGIF(BufferedImage im) {
		if ((im == null) || !started) {
			return false;
		}
		boolean ok = true;
		try {
			if (!sizeSet) {
				setImgSize(im.getWidth(), im.getHeight());
			}
			image = im;
			getImagePixels(); 
			analyzePixels(); 
			if (isImage) {
				writeLSD(); 
				writePalette(); 
			}
			writeGraphicCtrlExt(); 
			writeImageDesc(); 
			if (!isImage) {
				writePalette(); 
			}
			writePixels(); 
			isImage = false;
		} catch (IOException e) {
			ok = false;
		}

		return ok;
	}
	
	public boolean FileTailer() {
		if (!started) return false;
		boolean ok = true;
		started = false;
		try {
			out.write(0x3b);
			out.flush();
			if (closeStream) {
				out.close();
			}
		} catch (IOException e) {
			ok = false;
		}

		transIndex = 0;
		out = null;
		image = null;
		pixels = null;
		indexedPixels = null;
		colorTab = null;
		closeStream = false;
		isImage = true;

		return ok;
	}
	
	
	public void setQuality(int quality) {
		if (quality < 1) quality = 1;
		sample = quality;
	}
	
	public void setImgSize(int w, int h) {
		if (started && !isImage) return;
		width = w;
		height = h;
		if (width < 1) width = 320;
		if (height < 1) height = 240;
		sizeSet = true;
	}
	
	public boolean FileHeader(OutputStream os) {
		if (os == null) return false;
		boolean ok = true;
		closeStream = false;
		out = os;
		try {
			writeString("GIF89a"); // header
		} catch (IOException e) {
			ok = false;
		}
		return started = ok;
	}
	
	public boolean FileHeader(File dir,String file) {
		boolean ok = true;
		try {
			out = new BufferedOutputStream(new FileOutputStream(new File(dir,file)));
			ok = FileHeader(out);
			closeStream = true;
		} catch (IOException e) {
			ok = false;
		}
		return started = ok;
	}
	
	protected void analyzePixels() {
		int len = pixels.length;
		int nPix = len / 3;
		indexedPixels = new byte[nPix];
		PixelQuant nq = new PixelQuant(pixels, len, sample);
		colorTab = nq.process(); // create reduced palette
		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 k = 0;
		for (int i = 0; i < nPix; i++) {
			int index =
				nq.map(pixels[k++] & 0xff,
					   pixels[k++] & 0xff,
					   pixels[k++] & 0xff);
			usedEntry[index] = true;
			indexedPixels[i] = (byte) index;
		}
		pixels = null;
		colorDepth = 8;
		palSize = 7;
		if (transparent != null) {
			transIndex = findClosest(transparent);
		}
	}
	
	protected int findClosest(Color c) {
		if (colorTab == null) return -1;
		int r = c.getRed();
		int g = c.getGreen();
		int b = c.getBlue();
		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;
	}
	
	protected void getImagePixels() {
		int w = image.getWidth();
		int h = image.getHeight();
		int type = image.getType();
		if ((w != width)
			|| (h != height)
			|| (type != BufferedImage.TYPE_3BYTE_BGR)) {
			BufferedImage temp =
				new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
			Graphics2D g = temp.createGraphics();
			g.drawImage(image, 0, 0, null);
			image = temp;
		}
		pixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
	}
	
	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 == null) {
			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;
		out.write(0 | disp | 0 | transp); 
		writeShort(0); // delay x 1/100 sec
		out.write(transIndex); // transparent color index
		out.write(0); // block terminator
	}
	
	/**
	 * Writes Image Descriptor
	 */
	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 (isImage) {
			out.write(0);
		} else {

			out.write(0x80 | 0 | 0 | 0 | palSize); 
		}
	}
	
	/**
	 * Writes Logical Screen Descriptor
	 */
	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 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 {
		LZWCompress encoder =
			new LZWCompress(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));
		}
	}
	
	public static void main(String args[]){
		new GIFCom();	
	}

	public void actionPerformed(ActionEvent e) {
		// TODO 自动生成方法存根
		if(e.getSource()==buttonCom){
			try{ 
				fc.setFileFilter(new   javax.swing.filechooser.FileFilter()   
				{   
					public   boolean   accept(File   f)   
					{   
						return   f.getName().toLowerCase().endsWith(".bmp");   
					}   
					public   String   getDescription()   
					{   
						return   "位图文件 (*.BMP)";
					}   
				}   );
				
				fc.showDialog(this, "打开");
				File file=fc.getSelectedFile();
				filename=new String();
				try{
					filename=file.getName();
				}catch(NullPointerException ex){

				}
				if(file==null){
					return;
				}
				
				src = ImageIO.read(file); // 读入文件 
				labelMes.setIcon(new ImageIcon(src));
				labelMes.setText(filename);
				
				
				}catch(IOException ex){ 
				ex.printStackTrace(); 
				} 
		}else{
			filesplit="";
			int ind=0;
			while(filename.charAt(ind)!='.'){
				filesplit+=filename.charAt(ind);
				ind++;
			}
			FileHeader(fc.getCurrentDirectory(),filesplit+".gif"); 
			toGIF(src); 
			FileTailer(); 
			labelMes.setIcon(new ImageIcon(src));
			labelMes.setText(filesplit+".gif");
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -