2007-07-07
写了一个实用的图像放大缩小程序,但是动画GIF转换后不会显示了,只有第一帧
关键字: 图像 放大 缩小 ImageIO JPG GIF
写了一个实用的图像放大缩小程序,但是动画GIF转换后不会显示了,只有第一帧
代码如下,有没做过GIF转换的,提提建议一下,谢谢。
代码如下,有没做过GIF转换的,提提建议一下,谢谢。
import java.awt.Canvas;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.AreaAveragingScaleFilter;
import java.awt.image.BufferedImage;
import java.awt.image.FilteredImageSource;
import java.io.File;
import java.util.Arrays;
import javax.imageio.ImageIO;
import org.apache.log4j.Logger;
/**
* 一个实用的图像放大缩小程序
*
* @author YuLimin
*/
public class ZoomImage
{
private static final Logger logger = Logger.getLogger(ZoomImage.class);
private static Component component = new Canvas();
// ".pcx","tga",".tif"这三种格式目前还不支持;
// 这些定义的格式经过我测试过是可以支持的。
private static String[] imageFormatArray = new String[]{".jpg",".jpeg",".gif",".png",".bmp"};
/**
* 测试用例
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception
{
ZoomImage zoomImage = new ZoomImage();
zoomImage.listFormt();
// 缩小四倍
zoomImage.zoom("E:/图片/城市风光",0.25,false);
// 放大四倍
zoomImage.zoom("E:/图片/自然风光",4,false);
}
/**
* 查看图像I/O库所支持的图像格式有哪些格式
*/
public void listFormt()
{
String readerMIMETypes[] = ImageIO.getReaderMIMETypes();
String writerMIMETypes[] = ImageIO.getWriterMIMETypes();
if(logger.isInfoEnabled())
{
logger.info("ReaderMIMETypes:" + Arrays.asList(readerMIMETypes));
logger.info("WriterMIMETypes:" + Arrays.asList(writerMIMETypes));
}
}
/**
* 校验图像文件的格式是否可以进行缩放
*
* @param fileName
* @return
*/
public boolean verifyImageFormat(String fileName)
{
boolean result = false;
for(int i = 0;i < imageFormatArray.length;i++)
{
if(fileName.toLowerCase().lastIndexOf(imageFormatArray[i]) == (fileName.length() - imageFormatArray[i].length()))
{
result = true;
break;
}
}
return result;
}
/**
* 将目录下的所有图像进行放大缩小
*
* @param strDir 图像的目录
* @param zoomRatio 放大缩小的倍率
* @param rebuild 是否重新创建,即已经存在的图像是否覆盖重建
* @throws Exception
*/
public void zoom(String strDir,double zoomRatio,boolean rebuild) throws Exception
{
File fileDir = new File(strDir);
if(!fileDir.exists())
{
logger.warn("Not exist:" + strDir);
return;
}
String dirTarget = strDir + "/Zoom" + zoomRatio;
File fileTarget = new File(dirTarget);
if(!fileTarget.exists())
{
fileTarget.mkdir();
}
File[] files = fileDir.listFiles();
StringBuilder stringBuilder = new StringBuilder();
for(int i = 0;i < files.length;i++)
{
String fileFullName = files[i].getCanonicalPath();
String fileShortName = files[i].getName();
if(!new File(fileFullName).isDirectory())// 排除二级目录,如果想就再递归一次,这里省略
{
if(verifyImageFormat(fileShortName))
{
if(logger.isInfoEnabled())
{
logger.info("Begin Zoom:" + fileFullName);
}
stringBuilder = new StringBuilder();
stringBuilder.append(dirTarget).append("/").append(fileShortName);
if(!new File(stringBuilder.toString()).exists() || rebuild)
{
try
{
createZoomSizeImage(fileFullName,stringBuilder.toString(),zoomRatio);
}
catch(Exception e)
{
logger.error("createZoomSizeImage Error:" + fileFullName,e);
}
}
if(logger.isInfoEnabled())
{
logger.info("End Zoom:" + fileFullName);
}
}
else
{
logger.warn("Can't Zoom:" + fileFullName);
}
}
}
}
/**
* 按比例进行放大缩小图像,zoomRatio = 1为原大,zoomRatio > 1为放大,zoomRatio < 1 为缩小
*
* @param fileName
* @param fileNameTarget
* @param zoomRatio
* @throws Exception
*/
public void createZoomSizeImage(String fileName,String fileNameTarget,double zoomRatio) throws Exception
{
Image image = ImageIO.read(new File(fileName));
int width = new Double(image.getWidth(null) * zoomRatio).intValue();
int height = new Double(image.getHeight(null) * zoomRatio).intValue();
AreaAveragingScaleFilter areaAveragingScaleFilter = new AreaAveragingScaleFilter(width,height);
FilteredImageSource filteredImageSource = new FilteredImageSource(image.getSource(),areaAveragingScaleFilter);
BufferedImage bufferedImage = new BufferedImage(width,height,BufferedImage.TYPE_3BYTE_BGR);
Graphics graphics = bufferedImage.createGraphics();
graphics.drawImage(component.createImage(filteredImageSource),0,0,null);
ImageIO.write(bufferedImage,"JPEG",new File(fileNameTarget));
}
}
评论
little06
2008-05-20
直接读写图片,虽然用java也可以做到
但是
没有试过图片服务器网站用java来处理的
可以用jni,调用底层,比如imagemagick,速度快
不相信的,可以试一试每分钟处理500M,1000张图片左右看看
但是
可以用jni,调用底层,比如imagemagick,速度快
不相信的,可以试一试每分钟处理500M,1000张图片左右看看
zelsa
2007-07-10
试试gif4j
jj5715
2007-07-10
同意楼上,java压缩大图片速度不行,还是感觉linux下自带的图片压缩工具比较快。
lordhong
2007-07-09
直接调用ImageMagick就行了, 自己写重新造轮子?
Eastsun
2007-07-09
YuLimin 写道
谢谢Eastsun
这样可以,但是无论放大还是缩小,看到的全是破DVD的播放效果,呵呵。。。马赛克。。。
这样可以,但是无论放大还是缩小,看到的全是破DVD的播放效果,呵呵。。。马赛克。。。
马赛克?那应该是你的代码那儿有问题.
有空我写个试试.
YuLimin
2007-07-08
谢谢Eastsun
这样可以,但是无论放大还是缩小,看到的全是破DVD的播放效果,呵呵。。。马赛克。。。
调用
这样可以,但是无论放大还是缩小,看到的全是破DVD的播放效果,呵呵。。。马赛克。。。
/**
* 读取GIF文件,并进行缩放,存放于BufferedImage数组中
*
* @param inputFileName
* @param zoomRatio
* @return
* @throws IOException
*/
public BufferedImage[] readGifFile(String inputFileName,double zoomRatio) throws IOException
{
Iterator imageReaders = ImageIO.getImageReadersBySuffix("GIF");
if(!imageReaders.hasNext())
{
throw new IOException("no ImageReaders for GIF");
}
ImageReader imageReader = (ImageReader)imageReaders.next();
File file = new File(inputFileName);
if(!file.exists())
{
throw new IOException("no file: " + file.getName());
}
imageReader.setInput(ImageIO.createImageInputStream(file));
List < BufferedImage > images = new ArrayList < BufferedImage >();
for(int i = 0;true;++i)
{
try
{
Image image = imageReader.read(i);
int width = new Double(image.getWidth(null) * zoomRatio).intValue();
int height = new Double(image.getHeight(null) * zoomRatio).intValue();
if(width > 0 && height > 0)
{
AreaAveragingScaleFilter areaAveragingScaleFilter = new AreaAveragingScaleFilter(width,height);
FilteredImageSource filteredImageSource = new FilteredImageSource(image.getSource(),areaAveragingScaleFilter);
BufferedImage bufferedImage = new BufferedImage(width,height,BufferedImage.TYPE_3BYTE_BGR);
Graphics graphics = bufferedImage.createGraphics();
graphics.drawImage(component.createImage(filteredImageSource),0,0,null);
images.add(bufferedImage);
}
}
catch(IndexOutOfBoundsException e)
{
break;
}
}
return images.toArray(new BufferedImage[images.size()]);
}
/**
* 根据BufferedImage数组的数据,写入到GIF文件中去
*
* @param images
* @param outputFileName
* @throws IOException
*/
public void writeGifFile(BufferedImage[] images,String outputFileName) throws IOException
{
Iterator imageWriters = ImageIO.getImageWritersBySuffix("GIF");
if(!imageWriters.hasNext())
{
throw new IOException("no ImageWriters for GIF");
}
ImageWriter imageWriter = (ImageWriter)imageWriters.next();
File file = new File(outputFileName);
file.delete();
imageWriter.setOutput(ImageIO.createImageOutputStream(file));
if(imageWriter.canWriteSequence())
{
if(logger.isInfoEnabled())
{
logger.info("Using writeToSequence for format GIF");
}
imageWriter.prepareWriteSequence(null);
for(int i = 0;i < images.length;++i)
{
imageWriter.writeToSequence(new IIOImage(images[i],null,null),null);
}
imageWriter.endWriteSequence();
}
else
{
if(logger.isInfoEnabled())
{
logger.info("cross fingers for format GIF");
}
for(int i = 0;i < images.length;++i)
{
imageWriter.write(images[i]);
}
}
}
调用
zoomImage.writeGifFile(zoomImage.readGifFile(inputFileName,zoomRatio),outputFileName);
Eastsun
2007-07-08
YuLimin 写道
直接通过ImageIO.write(bufferedImage,"GIF",new File(fileNameTarget));
但是仍不支持直接的动画写入,仍只是第一帧而已。
呵呵,谁说JDK6不支持gif动画写入了~~
当然是支持的,当然也不能通过简单的ImageIO.write的方法来写入了.
简单的说下gif动画的写入方法.
先通过
Iterator<ImageWriter> iter =ImageIO.getImageWritersByFormatName("gif");
ImageWriter writer =null;
while(iter.hasNext()){
writer =iter.next();
if(writer.canWriteSequence()) break;
}
得到gif文件的写入器.
然后创建一个image输出流
ImageOutputStream imageOut = ImageIO.createImageOutputStream(new File("xxxx.gif"));
然后设置write:
write.setOutput(imageOut);
最后反复调用wirte的writeToSequence方法即可.
注意在调用writeToSequence方法前要调用prepareWriteSequence方法,之后调用endWriteSequence方法.
还有一些细节问题可以自己参考jdk6.0的docs文档
YuLimin
2007-07-08
Eastsun 写道
YuLimin 写道
有读取GIF的,没有写GIF的,看来JDK默认的还没有支持?
1.6.0或1.7.0不知道有没有支持了?还是有其它的解决方案?
JDK1.6.0是支持GIF写的.
因为在JDK1.6之前GIF算法是受专利保护的,到JDK1.6时保护过期了,所以JDK1.6就支持GIF写了.
JDK1.6.0支持的格式如下:
ReaderMIMETypes:[image/png, image/jpeg, image/x-png, image/vnd.wap.wbmp, image/bmp, image/gif]
WriterMIMETypes:[image/jpeg, image/png, image/x-png, image/vnd.wap.wbmp, image/bmp, image/gif]
ReaderFormatNames:[BMP, bmp, jpg, JPG, wbmp, jpeg, png, PNG, JPEG, WBMP, GIF, gif]
WriterFormatNames:[jpg, BMP, bmp, JPG, jpeg, wbmp, png, JPEG, PNG, WBMP, GIF, gif]
直接通过ImageIO.write(bufferedImage,"GIF",new File(fileNameTarget));
但是仍不支持直接的动画写入,仍只是第一帧而已。
另外一些资源参考:
肢解GIF格式动画图片
http://sailing8036.spaces.live.com/Blog/cns!1pV60cmgp_2-KECsRGDNzV2w!325.entry
GIF格式可以将多个静态image组合成动画效果,所以一张GIF图片中肯定包含着每个image的内容,以及每个图片的播放演示delay时间。
这个网站提供了开源的java处理算法:
http://www.fmsware.com/stuff/gif.html
文件下载
http://www.fmsware.com/stuff/gif.zip
此开源的网站还提供了PhotoShop (.psd) reader class,Supports uncompressed or RLE-compressed RGB files only.
高级图像处理图像I/O API RC 1.0
http://www.tiantiansoft.com/Get/java/085816818.htm
下面这个地址里作者收集了好几个关于GIF的资源列表
http://www.westbrae.net/lbs/article.asp?id=77
xiaoyu
2007-07-07
GIF太复杂了。 java的2D API太原始了。 用起来不爽
Eastsun
2007-07-07
YuLimin 写道
有读取GIF的,没有写GIF的,看来JDK默认的还没有支持?
1.6.0或1.7.0不知道有没有支持了?还是有其它的解决方案?
JDK1.6.0是支持GIF写的.
因为在JDK1.6之前GIF算法是受专利保护的,到JDK1.6时保护过期了,所以JDK1.6就支持GIF写了.
YuLimin
2007-07-07
Readonly 写道
ImageIO.write(bufferedImage,"JPEG",new File(fileNameTarget));
只生成JPG格式?
只生成JPG格式?
支持的格式列表如下:
String readerFormatNames[] = ImageIO.getReaderFormatNames();
String writerFormatNames[] = ImageIO.getWriterFormatNames();
logger.info("ReaderFormatNames:" + Arrays.asList(readerFormatNames));
logger.info("WriterFormatNames:" + Arrays.asList(writerFormatNames));
结果如下:
java version "1.5.0_10"
ReaderFormatNames:[BMP, jpeg, bmp, wbmp, gif, png, JPG, jpg, JPEG, WBMP]
WriterFormatNames:[BMP, bmp, jpeg, wbmp, png, JPG, PNG, jpg, WBMP, JPEG]
java version "1.4.2_12"
ReaderFormatNames:[jpeg, gif, JPG, png, jpg, JPEG]
WriterFormatNames:[jpeg, png, JPG, PNG, jpg, JPEG]
有读取GIF的,没有写GIF的,看来JDK默认的还没有支持?
1.6.0或1.7.0不知道有没有支持了?还是有其它的解决方案?
Readonly
2007-07-07
ImageIO.write(bufferedImage,"JPEG",new File(fileNameTarget));
只生成JPG格式?
只生成JPG格式?
- 浏览: 594769 次
- 性别:

- 来自: 福建莆田@广州

- 详细资料
搜索本博客
我的相册
力拔千斤
共 146 张
共 146 张
最近加入圈子
链接
- 超越黎明
- CJSDN
- CSDN
- JavaWorld@TW
- JavaEye
- Spring中文论坛
- Matrix
- BEA dev2dev
- Agile Tao Forum
- Flickr
- developerWorks
- TheServerSide
- Sun Java Forum
- JavaRanch
- 满江红开源
- del.icio.us
- Sun中国技术社区
- 希赛网中国软考
- AJAX Design Patterns
- CSS: The Missing Manual
- Java Persistence with Hibernate
- Script in Java
- Building Spring 2 Enterprise Applications
- Tuscany中文社区
- 我爱人开的购物店,欢迎光临
- Beginning Spring 2: From Novice to Professional
- Effective Java Second Edition
最新评论
-
惊人大秘密:中国人必看! ...
怎么没人评价啊~帮你顶下!
-- by ╱/罒呍唲 -
记08.07.19 Beijing OpenP ...
呵呵 是"空军总司令呀". 介绍时在我后面:P 我是"杀手":P
-- by woods -
记08.07.19 Beijing OpenP ...
@dearwolf哈,小刀同学不厚道呀,。。。原来带o6z去制作烟囱去了。。。不 ...
-- by YuLimin -
记08.07.19 Beijing OpenP ...
引用dearwolf 18 小时前恩……o6z当时跑到外面去吸烟了,所以轮到他的 ...
-- by ozzzzzz -
记08.07.19 Beijing OpenP ...
- - 嘿嘿。那香蕉确实很赞! 不过我怀疑是ThoughtWorks员工的。 ...
-- by sg552






评论排行榜