欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

图片处理工具类(图片压缩与图片裁剪)

程序员文章站 2022-06-07 11:31:57
...
中作中由于需要对图片进行压缩和裁剪,因此参考网上的各种方法写了以下工具类

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;
		}

	}

}