中作中由于需要对图片进行压缩和裁剪,因此参考网上的各种方法写了以下工具类
package com.qxgf.xyz0.utils;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.awt.image.Kernel;
import java.io.File;
import javax.imageio.ImageIO;
/**
* 图片处理工具类
* @author Administrator
*
*/
public class ImgUtil {
/**
* 图片压缩
* @param srcImgFile 原始图片文件
* @param toImgFile 压缩后保存的目标图片文件
*/
public static void compress(File srcImgFile, File toImgFile) {
try {
Image image = ImageIO.read(srcImgFile);
int imageWidth = image.getWidth(null);
int imageHeight = image.getHeight(null);
float scale = 1.0f;
if (imageWidth > 1280 || imageHeight > 1024) { //宽或高大于一定值,则进行尺寸上的压缩
scale = getRatio(imageWidth, imageHeight, 1280, 1024);
}
imageWidth = (int) (scale * imageWidth);
imageHeight = (int) (scale * imageHeight);
image = image.getScaledInstance(imageWidth, imageHeight,Image.SCALE_AREA_AVERAGING);
BufferedImage bufferedImage = new BufferedImage(imageWidth,imageHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = bufferedImage.createGraphics();
g2.drawImage(image, 0, 0, imageWidth, imageHeight, Color.white,null);
g2.dispose();
// 以下代码用于提高图片清晰度
float[] kernelData2 = { -0.125f, -0.125f, -0.125f, -0.125f, 2,-0.125f, -0.125f, -0.125f, -0.125f };
Kernel kernel = new Kernel(3, 3, kernelData2);
ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
bufferedImage = cOp.filter(bufferedImage, null);
ImageIO.write(bufferedImage, "jpeg", toImgFile);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("图片压缩失败....");
}
}
/**
* 获取压缩比率值
* @param currWidth
* @param currHeight
* @param afterWidth
* @param afterHeight
* @return
*/
private static float getRatio(int currWidth, int currHeight,int afterWidth, int afterHeight) {
float ratio = 1.0f;
float widthRatio = (float) afterWidth / currWidth;
float heightRatio = (float) afterHeight / currHeight;
if (widthRatio < 1.0 || heightRatio < 1.0) {
ratio = widthRatio <= heightRatio ? widthRatio : heightRatio;
}
return ratio;
}
/**
* 图片裁切
* @param srcImgFile 原始图片文件
* @param toImgFile 裁切后保存的目标文件
* @param imgCrop 裁剪参数对象实例
*/
public static void crop(File srcImgFile, File toImgFile, ImgCrop imgCrop) {
try {
BufferedImage srcBufferedImg = ImageIO.read(srcImgFile);
int srcWidth = srcBufferedImg.getWidth();
int srcHeight = srcBufferedImg.getHeight();
//由于比率精确度原因,允许20像素的误差
int cropImgTotalWidth = imgCrop.getX() + imgCrop.getWidth();
int cropImgTotalHeight = imgCrop.getY() + imgCrop.getHeight();
if (srcWidth >= cropImgTotalWidth-20 && srcHeight >= cropImgTotalHeight-20) {
ImageFilter cropFilter = null;
if(srcWidth < cropImgTotalWidth && srcHeight < cropImgTotalHeight) {//纠正X,Y误差
cropFilter = new CropImageFilter(imgCrop.getX(),imgCrop.getY(), srcWidth-imgCrop.getX(), srcHeight-imgCrop.getY());
}else if(srcWidth < cropImgTotalWidth) {//纠正X误差
cropFilter = new CropImageFilter(imgCrop.getX(),imgCrop.getY(), srcWidth-imgCrop.getX(), imgCrop.getHeight());
}else if(srcHeight < imgCrop.getHeight()) {//纠正Y误差
cropFilter = new CropImageFilter(imgCrop.getX(),imgCrop.getY(), imgCrop.getWidth(), srcHeight-imgCrop.getY());
}else {
cropFilter = new CropImageFilter(imgCrop.getX(),imgCrop.getY(), imgCrop.getWidth(), imgCrop.getHeight());
}
Image img = Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(srcBufferedImg.getSource(),cropFilter));
BufferedImage toBufferedImg = new BufferedImage(imgCrop.getWidth(), imgCrop.getHeight(),BufferedImage.TYPE_INT_RGB);
Graphics g = toBufferedImg.getGraphics();
g.drawImage(img, 0, 0, null);
g.dispose();
ImageIO.write(toBufferedImg,FunctionUtil.getFileSuffix(toImgFile.getName()),toImgFile);
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("图片裁剪失败....");
}
}
/**
* 图片裁剪信息包装类
* @author Administrator
*/
public static class ImgCrop {
private Integer x; //起点X坐标
private Integer y; //起点Y坐标
private Integer width;//宽度
private Integer height;//高度
private Float ratio = 1.0f; //参数比率(因为图片的裁剪可能并不是在原图大小上进行的)
public ImgCrop() {}
public ImgCrop(Integer x, Integer y, Integer width, Integer height, Float ratio) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.ratio = ratio == null ? this.ratio : ratio;
}
public Integer getX() {
//取最小整数,不可用四舍五入法,否则可能导致裁剪值超出范围
return Math.round(ratio*x - 0.5f);
}
public void setX(Integer x) {
this.x = x;
}
public Integer getY() {
//取最小整数,不可用四舍五入法,否则可能导致裁剪值超出范围
return Math.round(ratio*y - 0.5f);
}
public void setY(Integer y) {
this.y = y;
}
public Integer getWidth() {
//取最小整数,不可用四舍五入法,否则可能导致裁剪值超出范围
return Math.round(ratio*width - 0.5f);
}
public void setWidth(Integer width) {
this.width = width;
}
public Integer getHeight() {
//取最小整数,不可用四舍五入法,否则可能导致裁剪值超出范围
return Math.round(ratio*height - 0.5f);
}
public void setHeight(Integer height) {
this.height = height;
}
public Float getRatio() {
return ratio;
}
public void setRatio(Float ratio) {
this.ratio = ratio;
}
}
}