`
walksing
  • 浏览: 217168 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

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

阅读更多
2005-10-15 09:43作者:wannaberer
出处:http://dev.yesky.com/417/2153917.shtml
blog责任编辑:方舟 

 图片文件格式转换最核心的问题就是要解决各种图片格式的编码和解码,推荐用jimi包,可从http://java.sun.com/products/jimi/下载该包及其源码和demo

  需要注意的是:jimi提供了对几乎所有图片格式的解码支持,但是为提供gif和tif/tiff格式的编码api,gif编码问题在网上可以找到县相关的源码,tiff好像jai:http://java.sun.com/products/java-media/jai/index.jsp提供了它的编码,不过我没有用jai,暂时用jpeg编码代替了。

  察看jimi的源码,在com.sun.jimi.core中是jimi的核心处理api。

public void toJPG(String source, String dest, int quality) {

if (dest == null || dest.trim().equals(""))
 dest = source;

if (!dest.toLowerCase().trim().endsWith("jpg")) {
 dest += ".jpg";
 System.out.println("Overriding to JPG, output file: " + dest);
}
if (quality < 0 || quality > 100 || (quality + "") == null
|| (quality + "").equals("")) {
 System.out.println("quality must between ’0’ and ’100’");
 System.out.println("set to DEFAULT value:’75’");
 quality = 75;

}
try {
 JPGOptions options = new JPGOptions();
 options.setQuality(quality);
 ImageProducer image = Jimi.getImageProducer(source);
 JimiWriter writer = Jimi.createJimiWriter(dest);
 writer.setSource(image);
 // 加入属性设置,非必要
 // /*
 writer.setOptions(options);
 // */
 writer.putImage(dest);
} catch (JimiException je) {
 System.err.println("Error: " + je);
}
}

  在进行格式转换时,并不需要关心原图的格式,只要要转换的图片格式在jimi的解码格式范围内,就可以完全透明的进行decode过程:

ImageProducer image = Jimi.getImageProducer(source);

  实际的解码只需要以行代码,就这么简单。

  编码过程最简单的也只需要很少的代码:

JimiWriter writer = Jimi.createJimiWriter(dest);
writer.setSource(image);
// 加入属性设置,非必要
// /*
writer.setOptions(options);
// */
writer.putImage(dest);

  以上代码就完成了图片编码到输出到os生成转换后文件的全过程。

  上面代码中的 writer.setOptions(options)是用来对输出文件的属性进行相关的设置,每种格式的属性都不一样,com.sun.jimi.core.options.*中针对每种图片编码格式的相关属性提供了getter和setter方法,可以方便的进行设置:

  com.sun.jimi.core.options.*中针对每种图片编码格式的相关属性提供了getter和setter方法,可以方便的进行设置:

JPGOptions options = new JPGOptions();
options.setQuality(quality);

  格式转换就这么简单。

  jimi不支持的encode格式的解决

/**
*
* @param source
* @param dest
* @throws JimiException
*/
public void toGIF(String source, String dest) throws JimiException {
 if (dest == null || dest.trim().equals(""))
  dest = source;
 // 1:转换为jpg
 if (!dest.toLowerCase().trim().endsWith("jpg")) {
  dest += ".jpg";
 }
 toJPG(source, dest, 75);

 BufferedImage file_in = null;
 File file = new File(dest);
 try {
  file_in = javax.imageio.ImageIO.read(file);
 } catch (IOException e) {
  e.printStackTrace();
 }

 int end = dest.lastIndexOf(".");
 file.deleteOnExit();
 // output *.gif
 file.renameTo(new File(dest.substring(0, end) + ".gif"));
 // jpg to gif
 AnimatedGifEncoder e = new AnimatedGifEncoder();
 e.start(dest);
 e.addFrame(file_in);
 e.finish();
 
}

  这里用到了AnimatedGifEncoder 类,是我在网上搜索到的,对gif编码提供了一个实现,虽然还有待晚善的地方,不过单作格式转关已经够用了:)

AnimatedGifEncoder e = new AnimatedGifEncoder();
e.start(dest);
e.addFrame(file_in);
e.finish();

  需要注意的是:AnimatedGifEncoder 不能对所有格式的图片正确的识别,所以先要将其他格式转为jpg格式(最简单的方法是用imageIO)

BufferedImage file_in = null;
File file = new File(dest);
try {
 file_in = javax.imageio.ImageIO.read(file);
} catch (IOException e) {
 e.printStackTrace();
}

  这样直接放入BufferedImage中就ok了

e.addFrame(file_in);

  实际的编码过程在上面这句完成。

int end = dest.lastIndexOf(".");
file.deleteOnExit();
// output *.gif
file.renameTo(new File(dest.substring(0, end) + ".gif"));

  最后,在完成之前别忘了用上面几句消灭证据哟:)

  当然这种方法其实并不好,最彻底的方法是修改AnimatedGifEncoder,不过做人涅要厚道一点,毕竟是人家写的代码嘛,如果有兴趣的朋友可以讨论一下。

  格式转换解决了,缩放功能也就不算是问题了,以下代码同时实现了格式转关和线性缩放:

/**
*
* @param img
* @param dest
* @throws JimiException
*/
public void toTIF(Image img, String dest) throws JimiException {
 if (!dest.toLowerCase().trim().endsWith("tif")) {
  dest += ".tif";
  System.out.println("Overriding to TIF, output file: " + dest);
 }
 dest = dest.substring(0, dest.lastIndexOf(".")) + ".jpg";
 JimiWriter writer = Jimi.createJimiWriter(dest);
 writer.setSource(img);
 dest = dest.substring(0, dest.lastIndexOf(".")) + ".tif";
 writer.putImage(dest);
}

/**
* 线性改变图片尺寸(可同时改变图片格式)
*
* @param source
* 源文件完整路径
* @param desc
* 目标文件完整路径
* @param ins
* 放大/缩小比率
* @throws JimiException
* @throws IOException
*/
public void changeDimension(String source, String desc, double ins)
throws JimiException, IOException {
 String temp = desc;
 File _file = null;
 if (desc == null || desc.trim().equals(""))
  desc = source;
 if (!desc.toLowerCase().trim().endsWith("jpg")) {
  temp = desc.trim() + ".jpg";
 }
 this.toJPG(source, temp, 75);
 _file = new File(temp); // 读入文件

 Image src = javax.imageio.ImageIO.read(_file); // 构造Image对象
 double wideth = (double) src.getWidth(null); // 得到源图宽
 double height = (double) src.getHeight(null); // 得到源图长
 int iWideth = (int) (wideth * ins);
 int iHeight = (int) (height * ins);
 BufferedImage tag = new BufferedImage(iWideth, iHeight,
 BufferedImage.TYPE_INT_RGB);
 tag.getGraphics().drawImage(src, 0, 0, iWideth, iHeight, null); // 绘制缩小后的图

 if (!temp.trim().equals(desc))
  _file.deleteOnExit();

 if (desc.toLowerCase().trim().endsWith("gif")) {
  AnimatedGifEncoder e = new AnimatedGifEncoder();
  e.start(desc);
  e.addFrame(tag);
  e.finish();
 } else if (desc.toLowerCase().trim().endsWith("tif") || desc.toLowerCase().trim().endsWith("tiff")) {
  this.toTIF(tag, desc);
 } else {
  JimiWriter writer = Jimi.createJimiWriter(desc);
  writer.setSource(tag);
  writer.putImage(desc);
 }
}

  BufferedImage的构造函数中的参数类型为int,所以以上代码在改变图象尺寸时稍有偏差,不过简单演示一下还是可以的。

  jimi的example中可以找到很多单项图片处理功能的demo,有时间可以研究一下,会有不少收获的
分享到:
评论

相关推荐

    java 图片溶合特效源码

    Java Advanced Imaging(JAI)是Sun Microsystems开发的一个扩展Java 2D API的库,用于处理复杂的图像操作,包括旋转、缩放、色彩空间转换以及溶合等。使用JAI,开发者可以轻松地实现图片溶合特效。例如,通过`...

    基于JAVA实现的图像特征提取源代码

    Hu不变矩是一种用于描述图像形状的数学方法,具有旋转、缩放和镜像不变性,常用于图像识别、分类和物体检测。 Hu不变矩是由Maurice M. Hu于1962年提出的,它们通过将图像转换为它的中心矩并进行归一化来定义。中心...

    图片的缩放和拖动

    在IT行业中,图片的缩放和拖动是用户界面(UI)设计中常见的功能,尤其在图像编辑软件、照片浏览器和各种应用中。这个例子似乎是一个图像查看器或编辑器的初步实现,允许用户交互地操作图片,但还缺少图片旋转的功能...

    Java图像文件的缩小与放大.7z

    `Graphics`对象可以用来绘制、缩放和旋转图像。 10. **使用第三方库**: - 如果需要更复杂或高效的图像处理功能,可以考虑使用第三方库,如Java Advanced Imaging (JAI) 或 Apache Commons Imaging (formerly ...

    tuxiangsuofang.zip_bmp缩放

    BMP是一种无损的图像文件格式,它存储了图像的每个像素的颜色信息,因此在处理时需要考虑像素级别的细节。 首先,我们要理解BMP文件的结构。BMP文件由文件头、信息头和像素数据三部分组成。文件头包含了文件的基本...

    java图像处理 java图像处理java图像处理

    JAI API不仅支持常见的图像操作,如旋转、缩放、裁剪等,还特别适用于复杂的图像处理任务,如非线性变换和几何运算。然而,JAI API并不包含所有的图像编码和解码器,特别是对于GIF、JPEG和PNG之外的其他格式。 Java...

    RGB32转换yuv420方法

    这些公式是基于ITU-R BT.601标准,将RGB的每个分量线性缩放并加权后得到YUV的相应分量。其中,Y表示亮度,U和V表示色差,它们有助于保留图像的色彩信息。在YUV420格式中,U和V的采样率只有Y的一半,这意味着每4个...

    java实现的多元线性回归分析.doc

    【Java实现的多元线性回归分析】 多元线性回归是一种统计学方法,用于研究多个自变量与一个因变量之间的关系。在Java编程语言中,我们可以使用各种库来实现这一分析,例如Apache Commons Math库或者Weka机器学习库...

    LP.rar_LP_LP JAVA_PCA Java

    6. **PCA算法**:数据预处理、特征缩放、协方差矩阵计算、特征值分解、主成分选择和转换等步骤。 7. **结果可视化**:可能使用Java的图表库(如JFreeChart)展示解决方案或PCA的结果。 8. **文件操作**:读取和写入...

    Java编程Gauss消元和判断闰年

    在`gaussElimination`方法中,我们将实现上述的行交换、行缩放和行减法操作。最终,我们可以通过回代法得到线性方程组的解。 从提供的文件名`code6.cpp`来看,虽然它是一个C++文件而不是Java,但我们可以假设这里...

    基于opencv3.1库的JAVA源码

    第1章 Java概述、安装及简易教学 14 1-1 Java概述 14 1-2 Java安装 16 1-3 Eclipse安装 18 1-4 GUI设计工具WindowBuilder 18 1-5 在Eclipse开发第一个Java程式 23 1-6 在Eclipse开发第一个Java视窗程式-显示影像 26 ...

    14.(地图数据篇)arcgis地图瓦片数据爬取--java代码.zip

    3. **经纬度与瓦片坐标转换**:`LatLngToTileUtil.java`文件中的`LatLngToTileUtil`类可能实现了将地图上的经纬度坐标转换为对应的瓦片坐标。这涉及到Web Mercator投影的数学计算,包括纬度的线性化和经度的换算。 ...

    基于WorldWind Java加载MD2关键帧动画模型问题研究.zip

    总结来说,基于WorldWind Java加载MD2关键帧动画模型的研究涉及到多个技术层面:MD2模型解析、关键帧动画控制、3D渲染和性能优化。对于开发者来说,这既是一个挑战,也是提升技能和深入理解图形编程的好机会。通过这...

    坐标转换_zuobiaozhuanhuan_坐标系转换_坐标转换_

    7. **仿射变换(Affine Transformation)**:包括平移、旋转、缩放和剪切,是一种线性变换,常用于图像处理和几何图形变换。 实现坐标转换的编程语言有多种,如Python的`pyproj`库、C++的`PROJ`库、Java的`GeoTools...

    Java2D Demo

    7. **变换操作**:Java2D支持矩阵变换,如平移、旋转、缩放和倾斜,可以用来创建动态的视觉效果。Graphics2D的translate(), rotate(), scale()和shear()方法是进行这些变换的关键。 8. **抗锯齿和平滑处理**:为了...

    java实现SVM支持向量机算法

    同时,为了适应SVM的线性或非线性处理,需要对数据进行适当的转换,如通过核函数转换。 5. 核函数的选择: 如前所述,选择合适的核函数对SVM性能至关重要。常见的核函数有高斯核(RBF),它以数据点之间的欧氏距离...

    svg代码与css代码互相转换,并压缩

    SVG是一种基于XML的矢量图像格式,它可以无限缩放而不失真,非常适合用于图标、徽标和其他图形元素。CSS3引入了内联SVG的支持,使得可以直接在CSS中使用SVG图形,从而简化了页面的结构和维护。另一方面,CSS可以用来...

Global site tag (gtag.js) - Google Analytics