1、图片按比例压缩
/**
* 根据缩放后图片的宽和高计算缩放的比例
* @param imgInputStream 图片的文件流
* @param picWidth 缩放后图片的宽
* @param picHeight 缩放后的图片的高度
* @return 返回缩放后的图片的缓存
*/
public static Map<String,Object> equalScale(InputStream imgInputStream, int picWidth, int picHeight){
Map<String,Object> map = new HashMap<String,Object>();
try {
BufferedImage buffer = ImageIO.read(imgInputStream);
map.put("buffer", buffer);
int width = buffer.getWidth(null); //图片原宽度
int height = buffer.getHeight(null); //图片原高度
int newwidth = 0;// 最终宽度
int newheight = 0;// 最终高度
//逻辑判断
if (width>height) {// 宽大于高。
if (width > picWidth) {
int _temp_height = (height * picWidth / width);
newwidth=picWidth;
newheight=_temp_height;
if(_temp_height>picHeight){
int _temp_width = (picWidth * picHeight / _temp_height);
newwidth=_temp_width;
newheight=picHeight;
}
} else {
newwidth=width;
newheight=height;
}
} else {
if (height > picHeight) {
int _temp_width = (width * picHeight / height);
newwidth=_temp_width;
newheight=picHeight;
if(_temp_width>picWidth){
int _temp_height = (height * picWidth / picWidth);
newwidth=picWidth;
newheight=_temp_height;
}
} else {
newwidth=width;
newheight=height;
}
}
map.put("width", newwidth) ;
map.put("height", newheight);
return map;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
*
* @Description: 保留图片本身格式的压缩
* @param imgInputStream 文件输入流
* @param imgOutputStream 文件输出流
* @param w 宽
* @param h 高
* @param ext 扩展名
*/
public static void scaleImage1(InputStream imgInputStream,OutputStream imgOutputStream, int w,int h,String ext)
{
try
{
Map<String,Object> map = equalScale(imgInputStream,w,h);
int width = map.get("width")==null?w:Integer.valueOf(map.get("width").toString());
int height = map.get("height")==null?h:Integer.valueOf(map.get("height").toString());
Image src = (BufferedImage) map.get("buffer");
BufferedImage bufferedImage = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
// Soften.
float softenFactor = 0.05f;
float[] softenArray = { 0, softenFactor, 0, softenFactor, 1 - (softenFactor * 4), softenFactor, 0, softenFactor, 0 };
Kernel kernel = new Kernel(3, 3, softenArray);
ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
bufferedImage = cOp.filter(bufferedImage, null);
bufferedImage.getGraphics().drawImage(
src.getScaledInstance(width, height, Image.SCALE_SMOOTH),
0 , 0 , null );
ImageIO.write(bufferedImage, ext, imgOutputStream);
}
catch (IOException e)
{
e.printStackTrace();
}
finally{
if(imgInputStream !=null)
try {
imgInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
if(imgOutputStream !=null)
try {
imgOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2、图片按坐标及高宽裁剪
/**
*
* 对图片裁剪,并把裁剪完蛋新图片保存 。
* @param is 要裁剪的文件流
* @param x x坐标
* @param y y坐标
* @param width 宽
* @param height 高
* @param thumbOutstream 新图片的输出流
* @param ext 裁剪格式
*/
public static void cut(InputStream is,int x,int y,int width,int height, OutputStream thumbOutstream,String ext) throws IOException {
// FileInputStream is = null;
ImageInputStream iis = null;
try {
// 读取图片文件
// is = new FileInputStream(srcpath);
/**
*
* 返回包含所有当前已注册 ImageReader 的 Iterator,这些 ImageReader
*
* 声称能够解码指定格式。 参数:formatName - 包含非正式格式名称 .
*
* (例如 "jpeg" 或 "tiff")等 。
*/
Iterator<ImageReader> it = ImageIO
.getImageReadersByFormatName(ext);
ImageReader reader = it.next();
// 获取图片流
iis = ImageIO.createImageInputStream(is);
/**
*
* <p>
* iis:读取源。true:只向前搜索
* </p>
* .将它标记为 ‘只向前搜索’。
*
* 此设置意味着包含在输入源中的图像将只按顺序读取,可能允许 reader
*
* 避免缓存包含与以前已经读取的图像关联的数据的那些输入部分。
*/
reader.setInput(iis, true);
/**
*
* <p>
* 描述如何对流进行解码的类
* <p>
* .用于指定如何在输入时从 Java Image I/O
*
* 框架的上下文中的流转换一幅图像或一组图像。用于特定图像格式的插件
*
* 将从其 ImageReader 实现的 getDefaultReadParam 方法中返回
*
* ImageReadParam 的实例。
*/
ImageReadParam param = reader.getDefaultReadParam();
/**
*
* 图片裁剪区域。Rectangle 指定了坐标空间中的一个区域,通过 Rectangle 对象
*
* 的左上顶点的坐标(x,y)、宽度和高度可以定义这个区域。
*/
Rectangle rect = new Rectangle(x, y, width, height);
// 提供一个 BufferedImage,将其用作解码像素数据的目标。
param.setSourceRegion(rect);
/**
*
* 使用所提供的 ImageReadParam 读取通过索引 imageIndex 指定的对象,并将
*
* 它作为一个完整的 BufferedImage 返回。
*/
BufferedImage bi = reader.read(0, param);
// 保存新图片
ImageIO.write(bi, ext, thumbOutstream);
} finally {
if (is != null)
is.close();
if (iis != null)
iis.close();
}
}
注:获取图片真实的文件格式通过
BufferedInputStream is = new BufferedInputStream(file.getInputStream());
String type = URLConnection.guessContentTypeFromStream(is);
if(type == null) {
throw new IOException("can't get mime type of image");
}
is.close();
获取;不能通过String type =file.getContentType(); 或 通过源文件名的扩展名,不然用户随意更改文件的扩展名,会导致裁剪不成功。
String ext = type.substring(type.indexOf("/")+1, type.length());