科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基于java的图片文件格式转换和线性缩放

基于java的图片文件格式转换和线性缩放

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

基于java的图片文件格式转换和线性缩放

作者:blackpupil 来源:赛迪网技术社区 2007年10月31日

关键字: 线性缩放 文件格式

  • 评论
  • 分享微博
  • 分享邮件
图片文件格式转换最核心的问题就是要解决各种图片格式的编码和解码,推荐用jimi包,可从http://java.sun.com/products/jimi/下载该包及其源码和demo。 <~bp6<]  
Hqh(-*qS  
  需要注意的是:jimi提供了对几乎所有图片格式的解码支持,但是为提供gif和tif/tiff格式的编码api,gif编码问题在网上可以找到县相关的源码,tiff好像jai:http://java.sun.com/products/java-media/jai/index.jsp提供了它的编码,不过我没有用jai,暂时用jpeg编码代替了。 ='edy$  
ty,'A=8@~  
  察看jimi的源码,在com.sun.jimi.core中是jimi的核心处理api。 $^uy5 [N  
\c*4*@q  
public void toJPG(String source, String dest, int quality) { }{(b`;'Q9  
IJ"WOj D  
if (dest == null || dest.trim().equals("")) m\;2n%N  
 dest = source; |=<:U4m  
!{x2j0mm\  
if (!dest.toLowerCase().trim().endsWith("jpg")) { *_g+&Us1  
 dest += ".jpg"; iFa s2  
 System.out.println("Overriding to JPG, output file: " + dest); m&F?>D1@v  
} 3NgmS>  
if (quality < 0 || quality > 100 || (quality + "") == null G1+B(,J;Y  
|| (quality + "").equals("")) { jg)0L   
 System.out.println("quality must between ’0’ and ’100’"); #5H{e%}mu  
 System.out.println("set to DEFAULT value:’75’"); :ZnmoZe  
 quality = 75; r/U LVO  
GCv}$A%{"  
} -h1JdE~  
try { ^*r^=[c;  
 JPGOptions options = new JPGOptions(); [*"n#v  
 options.setQuality(quality); )oK/Onhh  
 ImageProducer image = Jimi.getImageProducer(source); e|[+.">  
 JimiWriter writer = Jimi.createJimiWriter(dest); |c7&_S<  
 writer.setSource(image); &4d~F #E  
 // 加入属性设置,非必要 !3n,zC/{_  
 // /* 0W[VIg5.v:  
 writer.setOptions(options); #EFhE=`:  
 // */ Tbc <T  
 writer.putImage(dest); cQMHJ7Z*6  
} catch (JimiException je) { pmu"(3ERTI  
 System.err.println("Error: " + je); #]]JCqfJW  
} Gqdv4L 2  
} 3AZIpB  
在进行格式转换时,并不需要关心原图的格式,只要要转换的图片格式在jimi的解码格式范围内,就可以完全透明的进行decode过程: ?}y5[0;sE  
y  pQ* n  
ImageProducer image = Jimi.getImageProducer(source); l8=VI3!FL  
M N<zt|J  
  实际的解码只需要以行代码,就这么简单。 S-N!hjDc  
JoWe^cz  
  编码过程最简单的也只需要很少的代码: #uIO>!f  
:@/PV1=Q,<  
JimiWriter writer = Jimi.createJimiWriter(dest);  9V)+ &"  
writer.setSource(image); :q$ +S[M  
// 加入属性设置,非必要 #I-6_{-a*  
// /* _WNw1j`v8m  
writer.setOptions(options); {::#z  
// */ H8V/O9|(  
writer.putImage(dest); {ph\ysC &  
R6l7"O rB  
  以上代码就完成了图片编码到输出到os生成转换后文件的全过程。 ZVB~Q $Q  
HWO;V4C_  
  上面代码中的 writer.setOptions(options)是用来对输出文件的属性进行相关的设置,每种格式的属性都不一样,com.sun.jimi.core.options.*中针对每种图片编码格式的相关属性提供了getter和setter方法,可以方便的进行设置: tUz9(!i6  
dk{;g(^^  
  com.sun.jimi.core.options.*中针对每种图片编码格式的相关属性提供了getter和setter方法,可以方便的进行设置: Pcpq>(  
#cnXx4s  
JPGOptions options = new JPGOptions(); ;zX5m-h  
options.setQuality(quality); w+wQ@7va`  
]2- X< X|  
  格式转换就这么简单。 _ZT##!Vl  
qJ\.5xYl=  
  jimi不支持的encode格式的解决 WPk;M~cDtF  
*UpV>Y=El4  
/** r rMzJ8n  
* I_}i}k~~  
* @param source rQ*<(e]FOU  
* @param dest  8 7t[  
* @throws JimiException 5mRU  
*/ =#.Pd$g  
public void toGIF(String source, String dest) throws JimiException { 13bvl; )l  
 if (dest == null || dest.trim().equals("")) !nuLfek{  
  dest = source; L?R\hs^  
 // 1:转换为jpg [B/T},  
 if (!dest.toLowerCase().trim().endsWith("jpg")) { >j%*3S t  
  dest += ".jpg"; yQ'$03,B  
 } =QdUN-ELUr  
 toJPG(source, dest, 75); H%AE`X  
U]x}_  
 BufferedImage file_in = null; o2QA[|J  
 File file = new File(dest); fK.nLia  
 try { G,%u[|UzoL  
  file_in = javax.imageio.ImageIO.read(file); MW_;XB XY  
 } catch (IOException e) { .G1.,::$  
  e.printStackTrace(); +\:k.s  
 } &M>6V?  
n_t!&  
 int end = dest.lastIndexOf("."); R\tpTn=  
 file.deleteOnExit(); ZRP R7v  
 // output *.gif [uIp[>A  
 file.renameTo(new File(dest.substring(0, end) + ".gif")); WDo730   
 // jpg to gif wiq02WM  
 AnimatedGifEncoder e = new AnimatedGifEncoder(); s n_K,8-  
 e.start(dest); y9=PfZ#C  
 e.addFrame(file_in); c -Ga9i1  
 e.finish(); Yd]&gL  
  PN^h`%w  
} XJDbR  
这里用到了AnimatedGifEncoder 类,是我在网上搜索到的,对gif编码提供了一个实现,虽然还有待晚善的地方,不过单作格式转关已经够用了:) u5x0 O\  
'aZT0[\/W  
AnimatedGifEncoder e = new AnimatedGifEncoder(); )p}/"Uc.8  
e.start(dest); PW*_:%9p%  
e.addFrame(file_in); (Njn@DB'  
e.finish(); j/-f :ZV  
QmPkbWlMt  
  需要注意的是:AnimatedGifEncoder 不能对所有格式的图片正确的识别,所以先要将其他格式转为jpg格式(最简单的方法是用imageIO) o^ m;7S"  
< .#.uiU  
BufferedImage file_in = null; "K>r_b  
File file = new File(dest); gu!.em#  
try { k=#c/o  
 file_in = javax.imageio.ImageIO.read(file); !cG=8l0Kwm  
} catch (IOException e) { apvD ^(Z  
 e.printStackTrace(); F';PfT;  
} XYr8}P  
sl\<B=  
  这样直接放入BufferedImage中就ok了 ]; t/  
3T%PM1t%  
e.addFrame(file_in); RzAMA#_  
tirng$uS  
  实际的编码过程在上面这句完成。 A+ AuRX?z  
1r6},Jv  
int end = dest.lastIndexOf("."); $2=n;ovR4a  
file.deleteOnExit(); d:YtTL@2  
// output *.gif O,E\@U  
file.renameTo(new File(dest.substring(0, end) + ".gif")); IQrsoo  
(T* &t#O  
  最后,在完成之前别忘了用上面几句消灭证据哟:) JJZN=7v  
YDXJjVqpl  
  当然这种方法其实并不好,最彻底的方法是修改AnimatedGifEncoder,不过做人涅要厚道一点,毕竟是人家写的代码嘛,如果有兴趣的朋友可以讨论一下。 y\jMA.wJS  
=w>x$|  
  格式转换解决了,缩放功能也就不算是问题了,以下代码同时实现了格式转关和线性缩放: Gq6[4*  
H=U=O)_y  
/** h8q@p  
* HW*v*`[F  
* @param img )"3e^|%  
* @param dest XREH&1+CW  
* @throws JimiException 7 ZX qK/D  
*/ =iv4n<z  
public void toTIF(Image img, String dest) throws JimiException { p4y1-  
 if (!dest.toLowerCase().trim().endsWith("tif")) {  ;d 5vXY  
  dest += ".tif"; TUJy  
  System.out.println("Overriding to TIF, output file: " + dest); S1L== d`B`  
 } N:%4?l4{S  
 dest = dest.substring(0, dest.lastIndexOf(".")) + ".jpg"; *OF- |u  
 JimiWriter writer = Jimi.createJimiWriter(dest); x^LSAe6?_  
 writer.setSource(img); yMH~){\q  
 dest = dest.substring(0, dest.lastIndexOf(".")) + ".tif"; H`` bOI*  
 writer.putImage(dest); +lMY$+  
} 7a\YD!  
!1v /I   
/** vog&HZ87FN  
* 线性改变图片尺寸(可同时改变图片格式) Id/VR<@b  
* 1(^G_2O2(  
* @param source T^W#0TjA  
* 源文件完整路径 I'<{hZ  
* @param desc < c+J|  
* 目标文件完整路径 Q.mUFU  
* @param ins H W2N*tC  
* 放大/缩小比率 C{ eoC)   
* @throws JimiException "D xS4h  
* @throws IOException ~ q p$C  
*/ BRAC ]  
public void changeDimension(String source, String desc, double ins) #Ste| ;p  
throws JimiException, IOException { V.s0}h2B  
 String temp = desc; Vjy E?Gwf  
 File _file = null; LJJR $!Qy  
 if (desc == null || desc.trim().equals("")) &#S0a=lXQ  
  desc = source; hp7:AGP-V  
 if (!desc.toLowerCase().trim().endsWith("jpg")) { g!-~FP.nd  
  temp = desc.trim() + ".jpg"; # &qW]J  
 } 1x=(R[}V  
 this.toJPG(source, temp, 75); 112 r wu  
 _file = new File(temp); // 读入文件 E10ca_=I  
7-p9Yo7/  
 Image src = javax.imageio.ImageIO.read(_file); // 构造Image对象 &)j_fh!O7w  
 double wideth = (double) src.getWidth(null); // 得到源图宽 mW}c)x].}  
 double height = (double) src.getHeight(null); // 得到源图长 _u> Otg^  
 int iWideth = (int) (wideth * ins); & %<(G5]  
 int iHeight = (int) (height * ins); 3(#qBG.*A9  
 BufferedImage tag = new BufferedImage(iWideth, iHeight, 4Fib\@,  
 BufferedImage.TYPE_INT_RGB); W"^wX;  
 tag.getGraphics().drawImage(src, 0, 0, iWideth, iHeight, null); // 绘制缩小后的图 ;yH\o+&  
[gHiW`^]U  
 if (!temp.trim().equals(desc)) "8Q1`Im;  
  _file.deleteOnExit(); 0S\]9  
{ t+T]&l1  
 if (desc.toLowerCase().trim().endsWith("gif")) { 8KV  5  
  AnimatedGifEncoder e = new AnimatedGifEncoder(); HAs#W<aM8  
  e.start(desc); OEFBFI N  
  e.addFrame(tag); Bz&CRBY5Y  
  e.finish(); Wi9XQz^?  
 } else if (desc.toLowerCase().trim().endsWith("tif") || desc.toLowerCase().trim().endsWith("tiff")) { 5d} 8?N<-  
  this.toTIF(tag, desc); Lb5K=La  
 } else { RtLVV_/S  
  JimiWriter writer = Jimi.createJimiWriter(desc); pns-5?e@  
  writer.setSource(tag); e<7v8{A=  
  writer.putImage(desc); +_w4\g(  
 } BHN`mO  
} 48PE {+  
MZ`}c*wem  
  BufferedImage的构造函数中的参数类型为int,所以以上代码在改变图象尺寸时稍有偏差,不过简单演示一下还是可以的。 6j=664  
tg^u YCj  
  jimi的example中可以找到很多单项图片处理功能的demo,有时间可以研究一下,会有不少收获的。
查看本文来源
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章