GIF 解码和编码操作库源码
2007-01-10 16:52
GIF 解码和编码操作库源码,共有四个类文件(请下载):
1.AnimatedGifEncoder.java
2.GifDecoder.java
3.LZWEncoder.java
4.NeuQuant.java
简单应用:
import
import
import
public
javax.imageio.ImageIO;
java.io.*;
java.awt.image.*;
class
Testgif{
public
static
void
main(String
args[]){
try{
BufferedImage
src
=
ImageIO.read(new
File("c:/w
ork/1.jpg"));
// 读入文件
work/2.jpg"));
// 读入文件
BufferedImage
src1
BufferedImage
src2
=
=
work/3.jpg"));
// 读入文件
AnimatedGifEncoder();
ImageIO.read(new
File("c:/
ImageIO.read(new
File("c:/
AnimatedGifEncoder
e
=
new
e.setRepeat(0);
e.start("c:/work/laoma.gif");
e.setDelay(3000);
//
1
frame
per
sec
e.addFrame(src);
e.setDelay(1000);
e.addFrame(src1);
e.setDelay(100);
e.addFrame(src2);
e.finish();
}catch(IOException
e){
e.printStackTrace();
}
}
}
下面的例子来
自:http://blog.csdn.net/ideas/archive/2006/08/25/1116198.aspx 作
者:
ideas
1 多张 jpg 图合成 gif 动画
/**
* 把多张 jpg 图片合成一张
*
*
*/
@param
@param
pic
newPic
String[] 多个 jpg 文件名 包含路径
String 生成的 gif 文件名 包含路径
private
synchronized
void
jpgToGif(String
pic[],
String
newPi
c)
{
oder();
ic.length];
{
间
try
{
AnimatedGifEncoder
e
=
new
AnimatedGifEnc
e.setRepeat(0);
e.start(newPic);
BufferedImage
src[]
=
new
BufferedImage[p
for
(int
i
=
0;
i
<
src.length;
i++)
e.setDelay(200);
//设置播放的延迟时
src[i]
=
ImageIO.read(new
File(pic
[i]));
// 读入需要播放的 jpg 文件
e.addFrame(src[i]);
//添加到帧中
}
e.finish();
}
catch
(Exception
e)
{
System.out.println(
e.printStackTrace();
"jpgToGif
Failed:");
}
}
2
gif 动画分解成多张 jpg
/**
*//**
* 把 gif 图片按帧拆分成 jpg 图片
*
*
*
*/
@param
@param
@return
gifName
path
String 生成小 jpg 图片的路径
String[] 返回生成小 jpg 图片的名称
String 小 gif 图片(路径+名称)
private
{
path)
ing
synchronized
String[]
splitGif(String
gifName,Str
try
{
GifDecoder
=
decoder.read(gifName);
decoder
new
GifDecoder();
frame 的个数
int
n
=
decoder.getFrameCount();
//得到
String[]
String
for
(int
subPic
=
new
String[n];
tag
=
this.getTag();
i
=
0;
i
<
n;
i++)
{
rame(i);
//得到帧
//得到延迟时间
)+
".jpg";
tputStream(subPic[i]);
BufferedImage
frame
=
decoder.getF
//int
delay
=
decoder.getDelay(i);
//生成小的 JPG 文件
path
subPic[i]
=
+
String.value(i
FileOutputStream
out
=
new
FileOu
ImageIO.write(frame,
JPEGImageEncoder
"jpeg",
out);
encoder
=
JPEGCod
ec.createJPEGEncoder(out);
encoder.encode(frame);
//存盘
out.flush();
out.close();
}
return
subPic;
}
catch
(Exception
e)
{
System.out.println(
e.printStackTrace();
return
null;
"splitGif
Failed!");
}
}
3 根据提供的文字生成 jpg 图片
/**
*//**
文字
int
String
* 根据提供的文字生成 jpg 图片
*
*
*
*
*
*
*
*/
s
smallWidth
bgcolor
fontcolor
fontPath
jpgname
@param
@param
@param
@param
@param
@param
@return
Color
Color
String 字体文件
jpg 图片名
String
每个字的宽度和高度是一样的
背景色
字色
private
String
createJpgByFont(String
s,
int
smallWidth,
Color
bgcolor,Color
fontcolor,String
fontPath,String
jpgname)
{
try
{
s.length()*smallWidth,
e.TYPE_INT_RGB);
//画一个矩形
齿)
BufferedImage
bimage
=
new
BufferedImage(
smallWidth,BufferedImag
=
g
Graphics2D
g.setColor(bgcolor);
g.fillRect(0,
0,
//背景色
smallWidth,
bimage.createGraphics();
smallWidth);
//去除锯齿(当设置的字体过大的时候,会出现锯
ASING,RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_ANTIALI
g.setColor(fontcolor);
File
file
new
=
//字的颜色
File(fontPath);
//字体
文件
句在 jdk1.5 下面才支持)
FONT,
file);
并应用新设置字体的大小
));
除添加文字
//根据字体文件所在位置,创建新的字体对象(此语
Font
font
=
Font.createFont(Font.TRUETYPE_
//font.deriveFont(float
f)复制当前 Font 对象
g.setFont(font.deriveFont((float)
smallWidth
g.drawString(s,0,
smallWidth);
//在指定坐标
g.dispose();
FileOutputStream
out
=
new
FileOutputStre
am(jpgname);
//指定输出文件
eJPEGEncoder(out);
JPEGEncodeParam(bimage);
JPEGImageEncoder
encoder
=
JPEGCodec.creat
JPEGEncodeParam
param
=
encoder.getDefault
param.setQuality(50f,
encoder.encode(bimage,
out.flush();
true);
param);
//存盘
}
catch
out.close();
(Exception
e)
{
System.out.println(
"createJpgByFont
Failed
!");
}
}
e.printStackTrace();
4 多张小 jpg 图合成一张大 JPG 图,在这里对大图只作宽度限制,不做高度限
制
/**
*//**
* 将多个小图片合成一张大 jpg 图
(小的 jpg 图片按照行列顺序
平铺)
度是一致的
*
*
*
*
*/
@param
@param
@param
smallJPG
bigWidth
smallWidth
ArrayList 一组小的 jpg 图片
int 大图宽度
int
单个文字生成的小图的宽度和高
@return
private
void
createBigJPG(ArrayList
smallJPG,
int
bigWid
th,
int
smallHeigh,Color
bgColor
,String
picName)
{
try
{
if
(bigWidth
<
smallWidth)
//如果大图片的
高度比小图片的高度还小 直接返回
return;
/每行放置的字数
int
colCount
=
bigWidth
/
smallWidth;
/
int
leftMargin
=
(int)
((bigWidth
-
col
Count
*
smallWidth)
/
2f);
//左边距
=
rowCount
int
smallJPG.size();
//小图
行数
隙,只留左右边距
int
setWidth
=
bigWidth;
//每列中间不留空
int
setHeight
=
smallWidth
*
rowCount
;
e(setWidth,
setHeight,
//按照大图片宽高绘制一个背景图片
BufferedImage
bufImage
new
=
BufferedImag
BufferedImage.TYPE_INT_RGB);
=
g
Graphics2D
g.setColor(bgColor);
g.fillRect(0,
0;
int
for
i
y
=
(int
0;
0,
//纵坐标
=
i
bufImage.createGraphics();
//背景的颜色
setWidth,
setHeight);
ArrayList
col
<
=
rowCount;
i++)
(ArrayList)
(smal
int
x
=
leftMargin;
//横坐
for
(int
j
=
0;
j
<
col.size()
String
jpgname
ImageIcon
icon
=
=
(String)
new
Imag
Image
img
=
icon.getImage(
int
imgWidth
=
img.getHeig
g.drawImage(img,
x,
y,
nul
{
//遍历每行
lJPG.get(i));
标
可能会出现左边距
;
j++)
{
(col.get(j));
eIcon(jpgname);
);
ht(null);
l);
x
+=
imgWidth;
}
y
+=
(smallWidth);
}
g.dispose();
FileOutputStream
out
=
new
FileOutputStre
am(picName);
//指定输出文件
eJPEGEncoder(out);
//设置文件格式
JPEGImageEncoder
encoder
=
JPEGCodec.creat
JPEGEncodeParam(bufImage);
JPEGEncodeParam
param
//从图片缓冲中读取
=
encoder.getDefault
true);
param);
//存盘
param.setQuality(50f,
encoder.encode(bufImage,
out.flush();
out.close();
(Exception
e)
{
System.out.println(
"createBigJPG
Failed!")
e.printStackTrace();
;
}
catch
}
}
注:
(1)AnimatedGifEncoder 和 GifDecoder,以及这两个类涉及到的相关类,在网上
搜索一下就可以找到。
(2)在 linux 系统下,如果你想支持更多系统外的字体,使用下面两句话,可以
不用为系统添加字体,直接把字体文件拷贝到相应位置即可,但是需要 jdk1.5
环境。
file
font
File
Font
体文件所在位置,创建新的字体对象
File(fontPath);
new
Font.createFont(Font.TRUETYPE_FONT,
//字体文件
=
=
file);
//根据字
如果是 jdk1.5 以下版本则需要为系统添加字体,因为
createFont(int
这个方法,是从 1.5 才开始有的。
fontFormat,
fontFile)
File
(3)g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.
VALUE_ANTIALIAS_ON);
我在测试中发现,当设置的字体过大的时候,会出现很明星的锯齿,后来在网上
找到了这个解决方法。
(4)有了以上几个方法,就可以做出更好看的闪信了。我也是因为需求才写下这
些方法的,美工做了一些热门词汇的 gif 图片,在短信转彩信遇到这些词汇时,
要使用提供的图片替换文字。
AnimatedGifEncoder.java 源码(处理 GIF 图片)
2007-01-10 17:49
import
import
import
java.io.*;
java.awt.*;
java.awt.image.*;
/**
*
of
*
*
*
*
*
*
*
Class
AnimatedGifEncoder
-
Encodes
a
GIF
file
consisting
or
frames.
one
more
Example:
e
AnimatedGifEncoder
=
e.start(outputFileName);
e.setDelay(1000);
e.addFrame(image1);
//
new
AnimatedGifEncoder();
1
frame
per
sec
*
*
*
*
*
e.addFrame(image2);
e.finish();
No
May
copyright
be
used
asserted
on
the
source
code
of
this
class.
for
any
purpose,
however,
refer
to
the
Unisys
LZW
paten
t
for
restrictions
on
any
to
use
of
the
corrections
associated
LZWEncoder
class.
Please
forw
kweiner@fmsware.com.
@author
@version
Kevin
1.03
Weiner,
November
FM
Software
2003
*
ard
*
*
*
*
*
*/
public
class
AnimatedGifEncoder
{
protected
protected
protected
given
protected
protected
protected
protected
le
es
protected
protected
protected
protected
o
palette
protected
protected
protected
palette
protected
protected
efault)
protected
finished
protected
protected
int
int
Color
width;
height;
//
image
size
transparent
=
null;
//
transparent
color
if
int
transIndex;
//
transparent
index
in
color
tab
=
-1;
//
no
=
0;
//
frame
repeat
delay
(hundredths)
started
=
false;
//
ready
to
output
fram
repeat
delay
int
int
boolean
OutputStream
BufferedImage
byte[]
byte[]
out;
image;
//
current
frame
pixels;
indexedPixels;
//
BGR
byte
array
converted
//
from
frame
frame
indexed
t
colorDepth;
colorTab;
int
byte[]
boolean[]
//
number
of
bit
planes
//
RGB
palette
usedEntry
=
new
boolean[256];
//
active
entries
int
int
palSize
dispose
=
=
7;
-1;
//
color
table
size
//
disposal
code
(-1
(bits-1)
use
=
d
boolean
closeStream
=
false;
//
close
stream
when
boolean
boolean
firstFrame
=
sizeSet
true;
=
false;
//
if
false,
get
size