Java图片处理工具类:裁剪与压缩图片方法详解与测试
JAVA 裁剪 压缩图片 工具类

这是一个工具类,直接上代码吧。
package demo01;
import javax.imageio.ImageIO;
引入 com.sun.image.codec.jpeg 包中的 JPEGCodec 类。
引入 com.sun.image.codec.jpeg 包中的 JPEGEncodeParam 类。
引入 com.sun.image.codec.jpeg 包中的 JPEGImageEncoder 类。
import java.awt.Graphics;
导入 Java 的 awt 图像包中的 BufferedImage 类。
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.io.File;
引入 Java 的输入流类 `FileInputStream` 。
import java.io.IOException;
import java.io.InputStream;
Java 语言中,需要导入 java.io.FileOutputStream 类。
import java.util.Map;
/**
* 压缩 图片工具类
* @author yangnuo
*
*/
public class ResizeImg {
/**
* 裁剪图片
* @param image
* @param w
* @param h
* @throws IOException
*/
公共的 void 方法 cutImage,它接收一个 File 类型的图像参数 image 以及两个整数类型的参数 w 和 h,在该方法中会抛出 IOException 异常。
// 判断参数是否合法
如果图像为空或者宽度为 0 或者高度为 0 。
new Exception ("哎呀,截图出错!!!");
}
创建了一个输入流对象 inputStream,该对象是通过使用 FileInputStream 类来读取指定的文件 image 而创建的。
// 用ImageIO读取字节流
通过 ImageIO 读取输入流 inputStream 后得到一个 BufferedImage 图像对象 bufferedImage 。
BufferedImage distin = null;
// 返回源图片的宽度。
获取的 bufferedImage 的宽度赋值给变量 srcW 。
// 返回源图片的高度。
获取的缓冲图像的高度被赋值给变量 srcH 。 缓冲图像的高度通过 getHeight() 方法获取。 变量 srcH 被赋予了缓冲图像的高度值。 缓冲图像的高度被获取并赋值给 srcH 。 从缓冲图像中获取到的高度被存储在 srcH 中。 缓冲图像的高度经由 getHeight() 操作后赋值给 srcH 。 缓冲图像的高度通过特定方法获取并赋值给 srcH 。 缓冲图像的高度被获取后被放置在 srcH 中。 缓冲图像的高度被获取并传递给 srcH 。 缓冲图像的高度被获取并设定为 srcH 的值。
int x = 0, y = 0;
// 使截图区域居中
x = srcW / 2 - w / 2;
y = srcH / 2 - h / 2;
srcW = srcW / 2 + w / 2;
srcH = srcH / 2 + h / 2;
// 生成图片
创建一个新的 BufferedImage 对象,宽度为 w,高度为 h,图像类型为 BufferedImage.TYPE_INT_RGB,该对象被赋值给 distin 变量。
Graphics 是从 distin 获取到的。
g 绘制图像,将 bufferedImage 绘制在坐标 (0, 0) 处,宽度为 w,高度为 h,源图像的坐标为 (x, y),宽度为 srcW,高度为 srcH,最后一个参数为 null。
创建了一个输入流对象 inputStream,这个输入流对象是通过 new FileInputStream(image) 创建的,即通过文件路径 image 创建了一个用于读取文件的输入流。
// 用ImageIO读取字节流
BufferedImage bufferedImage = ImageIO.read(inputStream);
BufferedImage distin = null;
// 返回源图片的宽度。
int srcW = bufferedImage.getWidth();
// 返回源图片的高度。
获取的缓冲图像的高度被赋值给变量 srcH 。
System.out 把 srcW 和 srcH 进行打印。
// 生成图片
distin = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics g = distin.getGraphics();
g 绘制图像,图像为 bufferedImage,起始坐标为 srcW 的三分之一和 srcH 的三分之一,后续参数为 null
g 绘制图像,图像为 bufferedImage,起始坐标为 0,0,宽度为 srcW/3,高度为 srcH/3,截取区域的起始坐标为 srcW/3,srcH/3,截取区域的宽度为 srcW,高度为 srcH,最后一个参数为 null
ImageIO 将 distin 写入为 "jpg" 格式。新的文件路径为 "E:/"+(int)(Math.random()*1000)+image.getName()。即创建了一个新的文件,并将 distin 以 "jpg" 格式写入该文件中。
}
/**
* @param im 原始图像
需要缩小的倍数是 resizeTimes,缩小 2 倍时为原来的 1/2 ,此数值越大,返回的图片就越小。
返回经过处理后的图像。
*/
公共的 BufferedImage 对传入的 BufferedImage im 进行调整大小操作,通过指定的浮点数 resizeTimes 来确定调整的倍数。
/*原始图像的宽度和高度*/
int width = im.getWidth();
int height = im.getHeight();
/*调整后的图片的宽度和高度*/
最后将除法运算的结果转换为整数,这个整数就是缩放后的宽度值。
将高度值转换为整数,先将高度值转换为字符串,再将字符串转换为浮点数,接着用该浮点数除以缩放倍数,最后将结果转换为整数,即得到转换后的高度值。
/*新生成结果图片*/
创建了一个 BufferedImage 对象,其名称为 result,该对象的宽度为 toWidth,高度为 toHeight,类型为 BufferedImage.TYPE_INT_RGB。
result 获取图形对象,然后调用该图形对象的 drawImage 方法。将 im 进行缩放,缩放后的实例宽度为 toWidth,高度为 toHeight,采用 java.awt.Image.SCALE_SMOOTH 平滑缩放方式。接着在坐标 (0, 0) 处绘制该缩放后的图像,最后一个参数为 null。
return result;
}
/**
* @param im 原始图像
参数 resizeTimes 表示倍数,例如 0.5 意味着缩小一半,还有 0.98 等,其类型为 double 。
* @return 返回处理后的图像
*/
通过特定的方式对传入的 BufferedImage 进行缩放以获得一个新的 BufferedImage。
/*调整后的图片的宽度和高度*/
int toWidth=64;
int toHeight=64;
/*原始图像的宽度和高度 百分比缩略*/
toHeight = im.getHeight()/50;
toWidth = im.getWidth()/50;
/*新生成结果图片*/
BufferedImage result = new BufferedImage(toWidth, toHeight, BufferedImage.TYPE_INT_RGB);
result.getGraphics().drawImage(im.getScaledInstance(toWidth, toHeight, java.awt.Image.SCALE_SMOOTH), 0, 0, null);
return result;
}
/**
@param path 为要进行转化的图像所在的文件夹,也就是存放图像的文件夹的路径。
* @param type 图片的后缀名组成的数组
* @return
*/
public List获取图像列表(String 类型的路径,String 数组类型的类型),并抛出 IOException 异常。
Map map = new HashMap();
for(String s : type) {
map.put(s,true);
}
List result = new ArrayList();
创建一个 File 数组 fileList ,它是通过对指定路径 path 的目录进行遍历得到的文件列表,即通过 new File(path).listFiles() 方法获取到的文件数组。
for (File f : fileList) {
if(f.length() == 0)
continue;
如果 map 中获取到的以 getExtension(f.getName()) 为键的值为 null 。
continue;
result 会添加通过 javax.imageio.ImageIO.read(f) 读取到的内容。
}
return result;
}
获取指定路径的图像并返回一个 BufferedImage 对象。如果在获取过程中出现 IOException 异常,则抛出该异常。具体来说,就是通过传入一个字符串路径作为参数,调用相应的方法来获取图像,并将其封装在 BufferedImage 中进行返回。如果获取图像的过程中发生了错误,就会触发 IOException 异常并将其抛出。
通过 javax.imageio.ImageIO 的 read 方法读取一个新的 File 对象,该 File 对象的路径为指定的 path 。
}
/**
* 把图片写到磁盘上
* @param im
@param path ,例如:C://home// ,这是图片写入的文件夹地址。
参数 fileName 为 DCM1987.jpg ,这是写入图片的名字。
* @return
*/
是否能将 BufferedImage 写入磁盘,需要指定路径和文件名。如果传入了 BufferedImage 实例 im、路径 path 和文件名 fileName,就可以尝试进行写入操作。如果写入成功,返回 true;如果写入失败,返回 false。
创建一个名为 f 的 File 对象,这个对象的路径是 path 与 fileName 拼接后的结果。
获取文件名的扩展名,将其赋值给字符串变量 fileType 。
if (fileType == null)
return false;
try {
ImageIO 把图像 im 按照文件类型 fileType 写入到文件 f 中。
im.flush();
return true;
} catch (IOException e) {
return false;
}
}
公共的是否能写入高质量的(BufferedImage im,字符串 fileFullPath)。 首先需要判断文件路径是否合法。 然后尝试将 BufferedImage 写入到指定路径的文件中。 如果写入过程中没有出现错误,就返回 true,表示写入成功;如果出现错误,就返回 false,表示写入失败。
try {
/*输出到文件流*/
创建一个 FileOutputStream 对象,名为 newimage,该对象用于输出到指定的文件路径 fileFullPath 上。
创建了一个 JPEGImageEncoder 编码器,该编码器是通过 JPEGCodec 创建的,用于对 newimage 进行 JPEG 编码操作。
JPEGEncodeParam jep 等于 JPEGCodec 获取到的默认 JPEGEncodeParam(im);
/* 压缩质量 */
jep.setQuality(1f, true);
encoder.encode(im, jep);
/*近JPEG编码*/
newimage.close();
return true;
} catch (Exception e) {
return false;
}
}
/**
* 返回文件的文件后缀名
* @param fileName
* @return
*/
如果给定一个文件名,那么可以获取该文件名的扩展名。
try {
获取文件名的扩展名部分。首先对文件名进行分割操作,通过“\.”作为分隔符将文件名分割成数组。然后获取分割后的数组的长度。最后返回数组中最后一个元素,即文件名的扩展名部分。
} catch (Exception e) {
return null;
}
}
/**
* 测试方法
* @param args
* @throws Exception
*/
公共静态的 void 方法 main,它的参数是 String 类型的数组 args,并且会抛出 Exception 异常。
ResizeImg r=new ResizeImg();
String filepath="E:\\";
String filename="001.jpg";
//裁剪图片
r 对一个文件进行裁剪操作,该文件路径为 filepath 加上 filename,裁剪尺寸为 1000 乘以 1000,即 r.cutImage(new File(filepath + filename), 1000, 1000);
//压缩图片
BufferedImage 是通过 r 获取的图像,其路径为 filepath 加上 filename ,即 BufferedImage im = r.getImage(filepath + filename) ;
r.zoomImage(im),然后将其写入高质量的文件;接着将写入的文件路径设置为 filepath+"s_"+filename,这样做是为了防止覆盖原图片,通过加 s_来区分是压缩以后的图片。
}
}
其中,cutImage()方法的作用是裁剪图片。这里我提供了两种裁剪方式,一种是自定义的(已被注释),另一种是截取图片大致中间的部分。其余的是压缩图片的方法,在zoomImage()方法中可以设定压缩图片的大小。并且给出了测试方法,位于工具类的最底部。