精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-07-07
代码如下,有没做过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)); } } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-07-07
ImageIO.write(bufferedImage,"JPEG",new File(fileNameTarget));
只生成JPG格式? |
|
返回顶楼 | |
发表时间:2007-07-07
Readonly 写道 ImageIO.write(bufferedImage,"JPEG",new File(fileNameTarget));
只生成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不知道有没有支持了?还是有其它的解决方案? |
|
返回顶楼 | |
发表时间: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写了. |
|
返回顶楼 | |
发表时间:2007-07-07
GIF太复杂了。 java的2D API太原始了。 用起来不爽
|
|
返回顶楼 | |
发表时间: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 |
|
返回顶楼 | |
发表时间: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文档 |
|
返回顶楼 | |
发表时间:2007-07-08
谢谢Eastsun
这样可以,但是无论放大还是缩小,看到的全是破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); |
|
返回顶楼 | |
发表时间:2007-07-09
YuLimin 写道 谢谢Eastsun
这样可以,但是无论放大还是缩小,看到的全是破DVD的播放效果,呵呵。。。马赛克。。。 马赛克?那应该是你的代码那儿有问题. 有空我写个试试. |
|
返回顶楼 | |
发表时间:2007-07-09
直接调用ImageMagick就行了, 自己写重新造轮子?
|
|
返回顶楼 | |