java图片处理——多张图片合成一张Gif图片并播放或Gif拆分成多张图片
1、多张jpg图合成gif动画
/**
* 把多张jpg图片合成一张
* @param pic String[] 多个jpg文件名 包含路径
* @param newPic String 生成的gif文件名 包含路径
*/
private synchronized void jpgToGif(String pic[], String newPic) {
try {
AnimatedGifEncoder e = new AnimatedGifEncoder();
e.setRepeat(0);
e.start(newPic);
BufferedImage src[] = new BufferedImage[pic.length];
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( "jpgToGif Failed:");
e.printStackTrace();
}
}
2、gif动画分解成多张jpg
/**
* 把gif图片按帧拆分成jpg图片
* @param gifName String 小gif图片(路径+名称)
* @param path String 生成小jpg图片的路径
* @return String[] 返回生成小jpg图片的名称
*/
private synchronized String[] splitGif(String gifName,String path) {
try {
GifDecoder decoder = new GifDecoder();
decoder.read(gifName);
int n = decoder.getFrameCount(); //得到frame的个数
String[] subPic = new String[n];
String tag = this.getTag();
for (int i = 0; i < n; i++) {
BufferedImage frame = decoder.getFrame(i); //得到帧
//int delay = decoder.getDelay(i); //得到延迟时间
//生成小的JPG文件
subPic[i] = path + String.value(i)+ ".jpg";
FileOutputStream out = new FileOutputStream(subPic[i]);
ImageIO.write(frame, "jpeg", out);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
encoder.encode(frame); //存盘
out.flush();
out.close();
}
return subPic;
} catch (Exception e) {
System.out.println( "splitGif Failed!");
e.printStackTrace();
return null;
}
}
3、根据提供的文字生成jpg图片
/**
* 根据提供的文字生成jpg图片
* @param s String 文字
* @param smallWidth int 每个字的宽度和高度是一样的
* @param bgcolor Color 背景色
* @param fontcolor Color 字色
* @param fontPath String 字体文件
* @param jpgname String jpg图片名
* @return
*/
private String createJpgByFont(String s, int smallWidth,Color bgcolor,Color fontcolor,String fontPath,String jpgname) {
try {
BufferedImage bimage = new BufferedImage(s.length()*smallWidth,
smallWidth,BufferedImage.TYPE_INT_RGB);
Graphics2D g = bimage.createGraphics();
g.setColor(bgcolor); //背景色
g.fillRect(0, 0, smallWidth, smallWidth); //画一个矩形
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON); //去除锯齿(当设置的字体过大的时候,会出现锯齿)
g.setColor(fontcolor); //字的颜色
File file = new File(fontPath); //字体文件
Font font = Font.createFont(Font.TRUETYPE_FONT, file); //根据字体文件所在位置,创建新的字体对象(此语句在jdk1.5下面才支持)
g.setFont(font.deriveFont((float) smallWidth)); //font.deriveFont(float f)复制当前 Font 对象并应用新设置字体的大小
g.drawString(s,0, smallWidth); //在指定坐标除添加文字
g.dispose();
FileOutputStream out = new FileOutputStream(jpgname); //指定输出文件
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bimage);
param.setQuality(50f, true);
encoder.encode(bimage, param); //存盘
out.flush();
out.close();
} catch (Exception e) {
System.out.println( "createJpgByFont Failed!");
e.printStackTrace();
}
}
4、多张小jpg图合成一张大JPG图,在这里对大图只作宽度限制,不做高度限制
/**
* 将多个小图片合成一张大jpg图 (小的jpg图片按照行列顺序平铺)
* @param smallJPG ArrayList 一组小的jpg图片
* @param bigWidth int 大图宽度
* @param smallWidth int 单个文字生成的小图的宽度和高度是一致的
* @return
*/
private void createBigJPG(ArrayList smallJPG, int bigWidth,
int smallHeigh,Color bgColor ,String picName) {
try {
if (bigWidth < smallWidth) //如果大图片的高度比小图片的高度还小 直接返回
return;
int colCount = bigWidth / smallWidth; //每行放置的字数
int leftMargin = (int) ((bigWidth - colCount * smallWidth) / 2f); //左边距
int rowCount = smallJPG.size(); //小图行数
int setWidth = bigWidth; //每列中间不留空隙,只留左右边距
int setHeight = smallWidth * rowCount ;
//按照大图片宽高绘制一个背景图片
BufferedImage bufImage = new BufferedImage(setWidth, setHeight,
BufferedImage.TYPE_INT_RGB);
Graphics2D g = bufImage.createGraphics();
g.setColor(bgColor); //背景的颜色
g.fillRect(0, 0, setWidth, setHeight);
int y = 0; //纵坐标
for (int i = 0; i < rowCount; i++) { //遍历每行
ArrayList col = (ArrayList) (smallJPG.get(i));
int x = leftMargin; //横坐标 可能会出现左边距
for (int j = 0; j < col.size(); j++) {
String jpgname = (String) (col.get(j));
ImageIcon icon = new ImageIcon(jpgname);
Image img = icon.getImage();
int imgWidth = img.getHeight(null);
g.drawImage(img, x, y, null);
x += imgWidth;
}
y += (smallWidth);
}
g.dispose();
FileOutputStream out = new FileOutputStream(picName); //指定输出文件
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); //设置文件格式
JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bufImage); //从图片缓冲中读取
param.setQuality(50f, true);
encoder.encode(bufImage, param); //存盘
out.flush();
out.close();
} catch (Exception e) {
System.out.println( "createBigJPG Failed!");
e.printStackTrace();
}
}
5、根据指定字符串生成图片
//根据str,font的样式以及输出文件目录
public static void createImage(String str,Font font,File outFile) throws Exception{
//获取font的样式应用在str上的整个矩形
Rectangle2D r=font.getStringBounds(str, new FontRenderContext(AffineTransform.getScaleInstance(1, 1),false,false));
int unitHeight=(int)Math.floor(r.getHeight());//获取单个字符的高度
//获取整个str用了font样式的宽度这里用四舍五入后+1保证宽度绝对能容纳这个字符串作为图片的宽度
int width=(int)Math.round(r.getWidth())+1;
int height=unitHeight+3;//把单个字符的高度+3保证高度绝对能容纳字符串作为图片的高度
//创建图片
BufferedImage image=new BufferedImage(width,height,BufferedImage.TYPE_INT_BGR);
Graphics g=image.getGraphics();
g.setColor(Color.WHITE);
g.fillRect(0, 0, width, height);//先用白色填充整张图片,也就是背景
g.setColor(Color.black);//在换成黑色
g.setFont(font);//设置画笔字体
g.drawString(str, 0, font.getSize());//画出字符串
g.dispose();
ImageIO.write(image, "png", outFile);//输出png图片
}
6、多个图片叠加
public static void combineImage(List<String> urlList, int width,
int height, String destPath, String imgFormat) throws IOException {
BufferedImage combinedImage = new BufferedImage(width, height,
BufferedImage.TYPE_INT_ARGB);
Graphics g = combinedImage.getGraphics();
for (String urlStr : urlList) {
URL url = new URL(urlStr);
URLConnection conn = url.openConnection();
conn.setReadTimeout(10 * 1000);
InputStream in = conn.getInputStream();
BufferedImage image = ImageIO.read(in);
g.drawImage(image, 0, 0, width, height, null);
}
ImageIO.write(combinedImage, imgFormat, new File(destPath));
}
注:
(1)AnimatedGifEncoder和GifDecoder,以及这两个类涉及到的相关类,在网上搜索一下就可以找到。
(2)在linux系统下,如果你想支持更多系统外的字体,使用下面两句话,可以不用为系统添加字体,直接把字体文件拷贝到相应位置即可,但是需要jdk1.5环境。
File file = new File(fontPath); //字体文件
Font font = Font.createFont(Font.TRUETYPE_FONT, file); //根据字体文件所在位置,创建新的字体对象
如果是jdk1.5以下版本则需要为系统添加字体,因为createFont(int fontFormat, File fontFile)
这个方法,是从1.5才开始有的。
(3)g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
我在测试中发现,当设置的字体过大的时候,会出现很明星的锯齿,后来在网上找到了这个解决方法。
(4)有了以上几个方法,就可以做出更好看的闪信了。我也是因为需求才写下这些方法的,美工做了一些热门词汇的gif图片,在短信转彩信遇到这些词汇时,要使用提供的图片替换文字。
本文转自:http://blog.csdn.net/ycb1689/article/details/8071714
java图片处理——多张图片合成一张Gif图片并播放或Gif拆分成多张图片的更多相关文章
- java 对图片的添加文字描述,以及两张图片合成一张
最近公司一个需要,需要把商品的优惠卷分享链接,生成一个二维码然后和商品主图合成一张,并且在新合成的主图增加商品信息的描述,好了直接看合成后图片的样式 下面我就直接贴代码,首先是Contorller层 ...
- 【代码笔记】iOS-多张图片合成一张
代码: RootViewController.m #import "RootViewController.h" @interface RootViewController () @ ...
- iOS开发中的小技巧 - 多张图合成一张
iOS多张图片合成一张 本文来源于http://www.cnblogs.com/yang-guang-girl/p/5197099.html,感谢博主 代码 #import "RootVie ...
- <<< 将一个rar格式的文件变成一张jpg图片,按照后缀来选择打开他的模式
把一个压缩格式和一张图片合成,按照后缀来判断他打开是图片还是解压文件,后缀是jpg打开的就是一张图片,后缀是rar打开的就是一个压缩包,里面存放你放的东西 :例如(秘密) 准备一张图片,test. ...
- 音视频入门-18-手动生成一张GIF图片
* 音视频入门文章目录 * GIF 编码知识 GIF 包含的数据块: 文件头(Header) 逻辑屏幕标识符(Logical Screen Descriptor) 全局颜色表(Global Color ...
- 音视频入门-12-手动生成一张PNG图片
* 音视频入门文章目录 * 预热 上一篇 [PNG文件格式详解]详细介绍了 PNG 文件的格式. PNG 图像格式文件由一个 8 字节的 PNG 文件署名域和 3 个以上的后续数据块(IHDR.IDA ...
- Atitit.java图片图像处理attilax总结 BufferedImage extends java.awt.Image获取图像像素点image.getRGB(i, lineIndex); 图片剪辑/AtiPlatf_cms/src/com/attilax/img/imgx.javacutImage图片处理titit 判断判断一张图片是否包含另一张小图片 atitit 图片去噪算法的原理与
Atitit.java图片图像处理attilax总结 BufferedImage extends java.awt.Image 获取图像像素点 image.getRGB(i, lineIndex); ...
- Atitit 判断判断一张图片是否包含另一张小图片
Atitit 判断判断一张图片是否包含另一张小图片 1. keyword1 2. 模板匹配是在图像中寻找目标的方法之一(切割+图像相似度计算)1 3. 匹配效果2 4. 图片相似度的算法(感知哈希算 ...
- android开发 两张bitmap图片合成一张图片
场景:对android4.4解码gif(解码文章见前面一篇)后的图片进行每帧处理,android4.3 解码出来的每帧都很完整,但是到android4.4版本就不完整了,每帧都是在第一帧的基础上把被改 ...
随机推荐
- iOS 和Android中的正则表达式简单使用
ios 中需要使用NSRegularExpression类,NSTextCheckingResult类. 下面给出最基本的实现代码 NSRegularExpression *regex = [NSRe ...
- 转数据库Sharding的基本思想和切分策略
本文着重介绍sharding的基本思想和理论上的切分策略,关于更加细致的实施策略和参考事例请参考我的另一篇博文:数据库分库分表(sharding)系列(一) 拆分实施策略和示例演示 一.基本思想 Sh ...
- C#模拟百度登录
目录: 1.fiddler解析百度登录地址 2.处理传入参数 1.fiddler解析百度登录地址 因工作需要,所以研究了下百度的登陆.首先打开https://passport.baidu.com/v2 ...
- codeforces B. Making Sequences is Fun 解题报告
题目链接:http://codeforces.com/problemset/problem/373/B 题目意思:给出w,m和k,需要找出从m开始,可以有多少个连续的数(m+1,m+2,...)(在添 ...
- codeforces A. The Wall 解题报告
题目链接:http://codeforces.com/problemset/problem/340/A 这道题目理解不难,就是在[a, b]区间内,找出同时能够被x和y整除的个数.第一次想当然的开了两 ...
- poj 2013 Symmetric Order 解题报告
题目链接:http://poj.org/problem?id=2013 设长度非递减的字串序列为s[1]...s[n].设计递归子程序print(n),其中n为字串序号,每分析1个字串,n=n-1. ...
- MySQL主备停机步骤与注意事项
双十一马上到了,一堆的事情,今天登录mysql数据库服务器的时候突然发现服务器时间戳不对,比北京时间快了几分钟,我的天...随后检查了其他的几台数据库服务器发现同样都存在不同的偏差,最小的比北京时间快 ...
- -- Warning: Skipping the data of table mysql.event. Specify the --events option explicitly.
[root@DB ~]# mysqldump -uroot -p123 --flush-logs --all-databases >fullbackup_sunday_11_PM.sql -- ...
- Entity FrameWork 中使用Expression<Func<T,true>>访问数据库性能优化
问题的本质是:扩展的Where方法有四个参数重载.传进去Func<T,true>那么返回值是IEnumable的接口类型的集合,如果是Expression<Func<T,tru ...
- VS读取文件或写入文件时出现中文乱码问题
最近我发现我从文本文档中读取文件处理后再存入新文本文档后,只要是有中文的都显示乱码了~~当我把中文去掉后一切又都正常了,而在我处理过程中,很确定没有对中文进行处理.使用记事本打开发现没有乱码现象,但是 ...