?? gifcom.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 + -