纯JAVA实现的图片处理工具类

张军 3702 0
/**
 * @Description  TestImageUtil.java
 * @author 张军
 * @date 2017年6月16日 下午6:10:01
 * @version V1.0
 */
package zj.image;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.Collection;

import javax.imageio.ImageIO;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;

import zj.check.util.CheckUtil;
import zj.common.exception.ServiceException;
import zj.io.util.FileUtil;
import zj.java.util.JavaUtil;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/**
 * 纯JAVA实现的图片处理工具类
 * @see 1、多个图片合成
 * @see 2、裁剪图片
 * @see 3、图片压缩
 * @see 4、制作圆角
 * @see 5、重调图片尺寸
 * @see 6、获取图片尺寸
 * @see 7、图片缩放
 * @see 8、导入网络图片到缓冲区
 * @version 1.00 (2014.09.15)
 * @author SHNKCS 张军 {@link  <a target=_blank href="http://www.zhangjunbk.com">张军个人网站</a>&nbsp;&nbsp;&nbsp;&nbsp;<a target=_blank href="http://user.qzone.qq.com/360901061/">张军QQ空间</a>}
 */
public class ImageUtil {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(ImageUtil.class);

	/**
	 * 导入网络图片到缓冲区
	 * 
	 * @param imgUrl
	 *            网络路径
	 * @author 张军
	 * @date 2015-11-03 21:59:00
	 * @modifiyNote
	 * @version 1.0
	 * @return 图片缓冲区
	 */
	public static BufferedImage loadImageUrl(String imgUrl) {
		try {
			// 获取网络地址
			URL url = new URL(imgUrl);
			// 返回网络图片缓冲区
			return ImageIO.read(url);
		} catch (Exception e) {
			logger.error("导入网络图片到缓冲区", e);
		}
		return null;
	}

	/**
	 * 图片缩放
	 * 
	 * @see #resize(String, String, int, int)
	 * @param src
	 *            源文件路径
	 * @param dest
	 *            目标文件路径
	 * @param width
	 *            宽度
	 * @param height
	 *            高度
	 */
	@Deprecated
	public static void zoomImage(String src, String dest, int width, int height) {
		try {
			double wr = 0, hr = 0;
			File srcFile = new File(src);
			File destFile = new File(dest);
			File targetDir = destFile.getParentFile();
			if (targetDir != null && !targetDir.exists()) {
				// 创建目标文件目录
				targetDir.mkdirs();
			}
			BufferedImage bufImg = ImageIO.read(srcFile);
			Image Itemp = bufImg.getScaledInstance(width, height, BufferedImage.SCALE_SMOOTH);
			wr = width * 1.0 / bufImg.getWidth();
			hr = height * 1.0 / bufImg.getHeight();
			AffineTransformOp ato = new AffineTransformOp(AffineTransform.getScaleInstance(wr, hr), null);
			Itemp = ato.filter(bufImg, null);
			ImageIO.write((BufferedImage) Itemp, dest.substring(dest.lastIndexOf(".") + 1), destFile);
		} catch (Exception e) {
			throw new ServiceException(e);
		}
	}

	/**
	 * 压缩图片
	 * 
	 * @see #resize(String, String, int, int)
	 * @param src
	 *            源文件路径
	 * @param dest
	 *            目标文件路径
	 * @param width
	 *            宽度
	 * @param height
	 *            高度
	 * @author 张军
	 * @date 2015-11-03 21:59:00
	 * @modifiyNote
	 * @version 1.0
	 */
	@Deprecated
	public static void imageScale(String src, String dest, int width, int height) {
		BufferedOutputStream output = null;
		try {
			File srcFile = new File(src);
			File destFile = new File(dest);
			File targetDir = destFile.getParentFile();
			if (targetDir != null && !targetDir.exists()) {
				// 创建目标文件目录
				targetDir.mkdirs();
			}
			Image image = javax.imageio.ImageIO.read(srcFile);
			image = image.getScaledInstance(width, height, Image.SCALE_AREA_AVERAGING);
			// Make a BufferedImage from the Image.
			BufferedImage mBufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
			Graphics2D g2 = mBufferedImage.createGraphics();
			g2.drawImage(image, 0, 0, width, height, 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);
			mBufferedImage = cOp.filter(mBufferedImage, null);
			output = new BufferedOutputStream(new FileOutputStream(destFile));
			JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(output);
			encoder.encode(mBufferedImage);
		} catch (Exception e) {
			throw new ServiceException(e);
		} finally {
			IOUtils.closeQuietly(output);
		}
	}

	/**
	 * 获取图片尺寸(宽,高)
	 * 
	 * @param filePath
	 *            文件路径
	 * @author 张军
	 * @date 2015-11-03 21:59:00
	 * @modifiyNote
	 * @version 1.0
	 * @return [width,height]
	 */
	public static int[] getSizeInfo(String filePath) {
		try {
			// 获取图片文件
			File file = new File(filePath);
			// 获取缓冲区
			Image image = ImageIO.read(file);
			// 返回宽度
			int width = image.getWidth(null);
			// 返回高度
			int height = image.getHeight(null);
			return new int[] { width, height };
		} catch (Exception e) {
			throw new ServiceException(e);
		}
	}

	/**
	 * 重调图片尺寸
	 * 
	 * @param srcFile
	 *            源文件
	 * @param destFile
	 *            目标文件
	 * @param width
	 *            新的宽度,小于1则忽略,按原图比例缩放
	 * @param height
	 *            新的高度,小于1则忽略,按原图比例缩放
	 * @param maxWidth
	 *            最大宽度,限制目标图片宽度,小于1则忽略此设置
	 * @param maxHeight
	 *            最大高度,限制目标图片高度,小于1则忽略此设置
	 * @author 张军
	 * @date 2015-11-03 21:59:00
	 * @modifiyNote
	 * @version 1.0
	 */
	public static void resize(File srcFile, File destFile, int width, int height, int maxWidth, int maxHeight) {
		InputStream input = null;
		OutputStream output = null;
		try {
			FileUtil.fileMkdir(destFile);
			// 获取文件输入流
			input = new BufferedInputStream(new FileInputStream(srcFile));
			// 获取文件输出流
			output = new BufferedOutputStream(new FileOutputStream(destFile));
			if (width < 1 && height < 1 && maxWidth < 1 && maxHeight < 1) {
				// 如果全部小于1尺寸
				IOUtils.copy(input, output);
			}
			// 获取源图片缓冲区
			BufferedImage img = ImageIO.read(input);
			// 源图片宽度
			double tempWidth = img.getWidth(null);
			// 源图片高度
			double tempHeight = img.getHeight(null);
			// 目标图片宽度
			int toWidth = -1;
			// 目标图片高度
			int toHeight = -1;
			// 源图片宽高比例
			double rate = tempWidth / tempHeight;
			if (width > 0 && height > 0) {
				// 如果输出的宽高大于0,比例设置为宽高比
				rate = ((double) width) / ((double) height);
				// 设置目标图片宽高为输出的宽高
				toWidth = width;
				toHeight = height;
			} else if (width > 0) {
				// 如果输出的宽大于0
				// 设置目标图片宽为输出的宽
				toWidth = width;
				// 设置目标图片高为输出的宽比上源图片宽高比
				toHeight = (int) (toWidth / rate);
			} else if (height > 0) {
				// 如果输出的高大于0
				// 设置目标图片高为输出的高
				toHeight = height;
				// 设置目标图片宽为输出的高比上源图片宽高比
				toWidth = (int) (toHeight * rate);
			} else {
				// 否则设置源图片宽
				toWidth = ((Number) tempWidth).intValue();
				// 否则设置源图片高
				toHeight = ((Number) tempHeight).intValue();
			}
			if (maxWidth > 0 && toWidth > maxWidth) {
				// 如果最大宽高大于 0并且输出的宽大于最大宽度
				// 设置输出的宽为最大宽度
				toWidth = maxWidth;
				// 设置输出的高为输出的宽比上源图片宽高比
				toHeight = (int) (toWidth / rate);
			}
			if (maxHeight > 0 && toHeight > maxHeight) {
				// 如果最大高高大于 0并且输出的高大于最大高度
				// 设置输出的高为最大高度
				toHeight = maxHeight;
				// 设置输出的宽为输出的高比上源图片宽高比
				toWidth = (int) (toHeight * rate);
			}
			// 判断透明色
			boolean hasNotAlpha = img.getColorModel().hasAlpha();
			// 获取透明色
			int typeInt = hasNotAlpha ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB;
			// 创建一个带透明色的BufferedImage对象:BufferedImage.TYPE_INT_ARGB
			// 创建一个不带透明色的BufferedImage对象:BufferedImage.TYPE_INT_RGB
			// 源图片缓冲区
			BufferedImage tag = new BufferedImage(toWidth, toHeight, typeInt);
			// Image.SCALE_SMOOTH 的缩略算法 生成缩略图片的平滑度的 优先级比速度高 生成的图片质量比较好 但速度慢
			tag.getGraphics().drawImage(img.getScaledInstance(toWidth, toHeight, Image.SCALE_SMOOTH), 0, 0, null);
			// 获取源文件扩展名
			String srcExtName = FilenameUtils.getExtension(srcFile.getName());
			// 输出源图片缓冲区到输出的文件中
			ImageIO.write(tag, srcExtName, output);
		} catch (Exception e) {
			throw new ServiceException(e);
		} finally {
			IOUtils.closeQuietly(input);
			IOUtils.closeQuietly(output);
		}
	}

	/**
	 * 重调图片尺寸(此方法图片更清楚)
	 * 
	 * @param src
	 *            源文件路径
	 * @param dest
	 *            目标文件路径
	 * @param width
	 *            新的宽度,小于1则忽略,按原图比例缩放
	 * @param height
	 *            新的高度,小于1则忽略,按原图比例缩放
	 * @param maxWidth
	 *            新的最大宽度,限制目标图片宽度,按原图比例缩放
	 * @param maxHeight
	 *            新的最大高度,限制目标图片高度,按原图比例缩放
	 * @author 张军
	 * @date 2015-11-03 21:59:00
	 * @modifiyNote
	 * @version 1.0
	 */
	public static void resize(String src, String dest, int width, int height, int maxWidth, int maxHeight) {
		resize(new File(src), new File(dest), width, height, maxWidth, maxHeight);
	}

	/**
	 * 重调图片尺寸(此方法图片更清楚)
	 * 
	 * @param srcFile
	 *            源文件
	 * @param destFile
	 *            目标文件
	 * @param width
	 *            新的宽度,小于1则忽略,按原图比例缩放
	 * @param height
	 *            新的高度,小于1则忽略,按原图比例缩放
	 * @author 张军
	 * @date 2015-11-03 21:59:00
	 * @modifiyNote
	 * @version 1.0
	 */
	public static void resize(File srcFile, File destFile, int width, int height) {
		resize(srcFile, destFile, width, height, -1, -1);
	}

	/**
	 * 重调图片尺寸(此方法图片更清楚)
	 * 
	 * @param src
	 *            源文件路径
	 * @param dest
	 *            目标文件路径
	 * @param width
	 *            新的宽度,小于1则忽略,按原图比例缩放
	 * @param height
	 *            新的高度,小于1则忽略,按原图比例缩放
	 * @author 张军
	 * @date 2015-11-03 21:59:00
	 * @modifiyNote
	 * @version 1.0
	 */
	public static void resize(String src, String dest, int width, int height) {
		resize(new File(src), new File(dest), width, height);
	}

	/**
	 * 裁剪图片
	 * 
	 * @param srcFile
	 *            源文件
	 * @param destFile
	 *            目标文件
	 * @param x
	 *            x坐标
	 * @param y
	 *            y坐标
	 * @param width
	 *            裁剪宽度
	 * @param height
	 *            裁剪高度
	 * @author 张军
	 * @date 2015-11-03 21:59:00
	 * @modifiyNote
	 * @version 1.0
	 */
	public static void crop(File srcFile, File destFile, int x, int y, int width, int height) {
		OutputStream output = null;
		InputStream input = null;
		try {
			// 获取源图片输入流
			input = new BufferedInputStream(new FileInputStream(srcFile));
			// 获取目标图片输入流
			output = new BufferedOutputStream(new FileOutputStream(destFile));
			// 获取源图片缓冲区
			BufferedImage srcImg = ImageIO.read(input);
			// 获取源图片宽度
			int srcWidth = srcImg.getWidth();
			// 获取源图片高度
			int srcHeight = srcImg.getHeight();
			// 计算临时x轴
			int tempX = Math.min(srcWidth - 1, x);
			// 计算临时y轴
			int tempY = Math.min(srcHeight - 1, y);
			// 输出的临时宽度
			int tempWidth = width;
			if (tempX + width > srcWidth) {
				// 临时的x轴+输出的宽度大于源文件宽度
				// 临时宽度设置源图片的宽度-临时x轴与1相比的最大值
				tempWidth = Math.max(1, srcWidth - tempX);
			}
			// 输出的临时高度
			int tempHeight = height;
			if (tempY + height > srcHeight) {
				// 临时的y轴+输出的高度大于源文件高度
				// 临时高度设置源图片的高度-临时y轴与1相比的最大值
				tempHeight = Math.max(1, srcHeight - tempY);
			}
			// 通过源图片的缓冲区获取目标文件缓冲区
			BufferedImage dest = srcImg.getSubimage(tempX, tempY, tempWidth, tempHeight);
			// 判断透明色
			boolean hasNotAlpha = srcImg.getColorModel().hasAlpha();
			// 获取透明色
			int typeInt = hasNotAlpha ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB;
			// 创建一个带透明色的BufferedImage对象:BufferedImage.TYPE_INT_ARGB
			// 创建一个不带透明色的BufferedImage对象:BufferedImage.TYPE_INT_RGB
			// 源图片缓冲区
			BufferedImage tag = new BufferedImage(width, height, typeInt);
			// 开始裁剪
			tag.getGraphics().drawImage(dest, 0, 0, null);
			// 获取源文件扩展名
			String srcExtName = FilenameUtils.getExtension(srcFile.getName());
			// 输出源图片缓冲区到输出的文件中
			ImageIO.write(tag, srcExtName, output);
		} catch (Exception e) {
			throw new ServiceException(e);
		} finally {
			IOUtils.closeQuietly(input);
			IOUtils.closeQuietly(output);
		}
	}

	/**
	 * 裁剪图片
	 * 
	 * @param src
	 *            源文件路径
	 * @param dest
	 *            目标文件路径
	 * @param x
	 *            x坐标
	 * @param y
	 *            y坐标
	 * @param width
	 *            裁剪宽度
	 * @param height
	 *            裁剪高度
	 * @author 张军
	 * @date 2015-11-03 21:59:00
	 * @modifiyNote
	 * @version 1.0
	 */
	public static void crop(String src, String dest, int x, int y, int width, int height) throws Exception {
		crop(new File(src), new File(dest), x, y, width, height);
	}

	/**
	 * 制作圆角
	 * 
	 * @param srcFile
	 *            源文件
	 * @param destFile
	 *            目标文件
	 * @param cornerRadius
	 *            角度
	 * @author 张军
	 * @date 2015-11-03 21:59:00
	 * @modifiyNote
	 * @version 1.0
	 */
	public static void makeRoundedCorner(File srcFile, File destFile, int cornerRadius) {
		InputStream input = null;
		OutputStream output = null;
		try {
			// 获取源图片输入流
			input = new BufferedInputStream(new FileInputStream(srcFile));
			// 获取目标图片输入流
			output = new BufferedOutputStream(new FileOutputStream(destFile));
			// 获取源图片缓冲区
			BufferedImage srcImg = ImageIO.read(input);
			// 获取源图片宽度
			int srcWidth = srcImg.getWidth();
			// 获取源图片高度
			int srcHeight = srcImg.getHeight();
			cornerRadius = cornerRadius < 1 ? srcWidth / 4 : cornerRadius;
			// 创建一个带透明色的BufferedImage对象:BufferedImage.TYPE_INT_ARGB
			// 创建一个不带透明色的BufferedImage对象:BufferedImage.TYPE_INT_RGB
			// 源图片缓冲区
			BufferedImage tag = new BufferedImage(srcWidth, srcHeight, BufferedImage.TYPE_INT_ARGB);
			// Graphics2D ,Graphics 类,提供了对几何形状、坐标转换、颜色管理和文本布局更为复杂的控制。
			// 它是用于在 Java(tm) 平台上呈现二维形状、文本和图像的基础类。验证码生成可以用到此类。
			// public abstract class Graphics2Dextends Graphics 此 Graphics2D 类扩展了 Graphics 类,
			// 提供了对几何形状、坐标转换、颜色管理和文本布局更为复杂的控制。
			Graphics2D g2 = tag.createGraphics();
			// This is what we want, but it only does hard-clipping, i.e.
			// aliasing
			// g2.setClip(new RoundRectangle2D ...)
			// so instead fake soft-clipping by first drawing the desired clip
			// shape
			// in fully opaque white with antialiasing enabled...
			// Java 2D允许分配透明(alpha)值,以便底层的图形可以显示出来。通常我们会创建一个java.awt.AlphaComposite对象,然后传入 setComposite()方法的实现。
			g2.setComposite(AlphaComposite.Src);
			// 其他渲染hints适用在不同的环境下。如缩放图片时,为KEY_INTERPOLATION使用 VALUE_INTERPOLATION_BILINEAR。请查阅本类的Javadoc,详细了解各个选项所适用的环境。
			g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
			// 设置颜色
			g2.setColor(Color.WHITE);
			// 开始制作
			// 前两个指定矩形的左上角的坐标
			// 第3,4个指定矩形的宽度和高度
			// 最后两个指定圆角弧形的宽度和高度
			g2.fill(new RoundRectangle2D.Float(0, 0, srcWidth, srcHeight, cornerRadius, cornerRadius));
			// ... then compositing the image on top,
			// using the white shape from above as alpha source
			// Java 2D允许分配透明(alpha)值,以便底层的图形可以显示出来。通常我们会创建一个java.awt.AlphaComposite对象,然后传入 setComposite()方法的实现。
			g2.setComposite(AlphaComposite.SrcAtop);
			// 开始画图片
			g2.drawImage(srcImg, 0, 0, null);
			// 释放资源
			g2.dispose();
			// 输出源图片缓冲区到输出的文件中(圆角只能是png)
			ImageIO.write(tag, "png", output);
		} catch (Exception e) {
			throw new ServiceException(e);
		} finally {
			IOUtils.closeQuietly(output);
			IOUtils.closeQuietly(input);
		}
	}

	/**
	 * 制作圆角
	 * 
	 * @param srcFile
	 *            源文件
	 * @param destFile
	 *            目标文件
	 * @param cornerRadius
	 *            角度
	 * @author 张军
	 * @date 2015-11-03 21:59:00
	 * @modifiyNote
	 * @version 1.0
	 */
	public static void makeRoundedCorner(String src, String dest, int cornerRadius) {
		makeRoundedCorner(new File(src), new File(dest), cornerRadius);
	}

	/**
	 * 修改图片,返回修改后的图片缓冲区(只输出一行文本)
	 * 
	 * @param srcFile
	 *            源文件
	 * @param destFile
	 *            目标文件
	 * @param font
	 *            字体
	 * @param fontColor
	 *            字体颜色
	 * @param fontSize
	 *            字体大小
	 * @param x
	 *            x坐标
	 * @param y
	 *            y坐标
	 * @param onlyLine
	 *            是否一行输出文本,默认false:多行输出
	 * @author 张军
	 * @date 2015-11-03 21:59:00
	 * @modifiyNote
	 * @version 1.0
	 */
	@SuppressWarnings("unchecked")
	public static void writeImageString(File srcFile, File destFile, Font font, Color fontColor, int fontSize, Object content, int x, int y, boolean onlyLine) {
		InputStream input = null;
		OutputStream output = null;
		try {
			// 获取源图片输入流
			input = new BufferedInputStream(new FileInputStream(srcFile));
			// 获取文件输出流
			output = new BufferedOutputStream(new FileOutputStream(destFile));
			// 获取源图片缓冲区
			BufferedImage srcImg = ImageIO.read(input);
			// 获取源图片宽度
			int srcWidth = srcImg.getWidth();
			// 获取源图片高度
			int srcHeight = srcImg.getHeight();
			// Graphics2D ,Graphics 类,提供了对几何形状、坐标转换、颜色管理和文本布局更为复杂的控制。
			// 它是用于在 Java(tm) 平台上呈现二维形状、文本和图像的基础类。验证码生成可以用到此类。
			// public abstract class Graphics2Dextends Graphics 此 Graphics2D 类扩展了 Graphics 类,
			// 提供了对几何形状、坐标转换、颜色管理和文本布局更为复杂的控制。
			Graphics2D g = srcImg.createGraphics();
			// 设置背景为白色
			g.setBackground(Color.WHITE);
			if (fontColor == null) {
				// 设置字体颜色为蓝色
				fontColor = Color.BLUE;
			}
			// 设置字体颜色为蓝色
			g.setColor(fontColor);
			// ont是JAVA中的字体类,PLAIN是Font类中的静态常量( static final ) ,
			// 表示是:普通样式常量。其他可用样式为:BOLD :粗体样式常量 ,ITALIC: 斜体样式常量.如可以如下初始化对象:
			// Font textFont = new Font("宋体" , Font.BOLD , 23);该字体表示23磅粗体的宋体字。
			if (font == null) {
				// 设置字体
				font = new Font("微软雅黑", Font.PLAIN, fontSize);
			}
			// 设置字体
			g.setFont(font);
			// 字体大小
			// 计算临时x轴
			int tempX = x;
			// 计算临时y轴
			int tempY = y;
			// 验证输出位置的纵坐标和横坐标
			if (x >= srcHeight || y >= srcWidth) {
				// 临时x轴为源图片高度-文字大小+2
				tempX = srcHeight - fontSize + 2;
				// 临时y轴为源图片宽度
				tempY = srcWidth;
			}
			if (content instanceof Collection) {
				Collection<String> contentColl = (Collection<String>) content;
				int contentLength = contentColl.size();
				if (onlyLine) {
					boolean first = true;
					for (String scontent : contentColl) {
						if (first) {
							if (x < 0) {
								// 写到右下角
								tempX = srcWidth - scontent.length() * contentLength - fontSize - 50;
							}
							if (y < 0) {
								// 写到右下角
								tempY = srcHeight - fontSize - 10;
							}
							first = false;
						}
						g.drawString(scontent, tempX, tempY);
						tempX += scontent.length() * fontSize / 2 + 5;// 重新计算文本输出位置
					}
				} else {
					boolean first = true;
					for (String scontent : contentColl) {
						if (first) {
							if (x < 0) {
								// 写到右下角
								tempX = srcWidth - scontent.length() - fontSize - 50;
							}
							if (y < 0) {
								// 写到右下角
								tempY = srcHeight - fontSize * contentLength - 10;
							}
							first = false;
						}
						g.drawString(scontent, tempX, tempY);
						tempY += fontSize + 2;// 重新计算文本输出位置
					}
				}
			} else {
				String scontent = JavaUtil.objToStr(content);
				if (CheckUtil.isNotNull(scontent)) {
					if (x < 0) {
						// 写到右下角
						tempX = srcWidth - scontent.length() - fontSize - 30;
					}
					if (y < 0) {
						// 写到右下角
						tempY = srcHeight - fontSize - 10;
					}
					// 在图片上写文字
					g.drawString(scontent, tempX, tempY);
				}
			}
			// 释放资源
			g.dispose();
			// 获取源文件扩展名
			String srcExtName = FilenameUtils.getExtension(srcFile.getName());
			// 输出源图片缓冲区到输出的文件中
			ImageIO.write(srcImg, srcExtName, output);
		} catch (Exception e) {
			throw new ServiceException(e);
		} finally {
			IOUtils.closeQuietly(input);
			IOUtils.closeQuietly(output);
		}

	}

	/**
	 * 修改图片,返回修改后的图片缓冲区(只输出一行文本)
	 * 
	 * @param srcFile
	 *            源文件
	 * @param destFile
	 *            目标文件
	 * @param fontColor
	 *            字体颜色
	 * @param fontSize
	 *            字体大小
	 * @param x
	 *            x坐标
	 * @param y
	 *            y坐标
	 * @author 张军
	 * @date 2015-11-03 21:59:00
	 * @modifiyNote
	 * @version 1.0
	 */
	public static void writeImageString(File srcFile, File destFile, Color fontColor, int fontSize, Object content, int x, int y) {
		writeImageString(srcFile, destFile, null, fontColor, fontSize, content, x, y, false);
	}

	/**
	 * 修改图片,返回修改后的图片缓冲区(只输出一行文本)
	 * 
	 * @param src
	 *            源文件路径
	 * @param dest
	 *            目标文件路径
	 * @param fontColor
	 *            字体颜色
	 * @param fontSize
	 *            字体大小
	 * @param x
	 *            x坐标
	 * @param y
	 *            y坐标
	 * @author 张军
	 * @date 2015-11-03 21:59:00
	 * @modifiyNote
	 * @version 1.0
	 */
	public static void writeImageString(String src, String dest, Color fontColor, int fontSize, Object content, int x, int y) {
		writeImageString(new File(src), new File(dest), fontColor, fontSize, content, x, y);
	}

	/**
	 * 修改图片,返回修改后的图片缓冲区(只输出一行文本)
	 * 
	 * @param srcFile
	 *            源文件
	 * @param destFile
	 *            目标文件
	 * @param x
	 *            x坐标
	 * @param y
	 *            y坐标
	 * @author 张军
	 * @date 2015-11-03 21:59:00
	 * @modifiyNote
	 * @version 1.0
	 */
	public static void writeImageString(File srcFile, File destFile, Object content, int x, int y) {
		writeImageString(srcFile, destFile, null, 20, content, x, y);
	}

	/**
	 * 修改图片,返回修改后的图片缓冲区(只输出一行文本)
	 * 
	 * @param src
	 *            源文件路径
	 * @param dest
	 *            目标文件路径
	 * @param x
	 *            x坐标
	 * @param y
	 *            y坐标
	 * @author 张军
	 * @date 2015-11-03 21:59:00
	 * @modifiyNote
	 * @version 1.0
	 */
	public static void writeImageString(String src, String dest, Object content, int x, int y) {
		writeImageString(new File(src), new File(dest), content, x, y);
	}

	/**
	 * 将两张图片合并后输出图片
	 * 
	 * @param fromFile
	 *            合并来自文件
	 * @param toFile
	 *            合并到文件
	 * @param destFile
	 *            目标文件
	 * @param x
	 *            x坐标,默认合并到左上角,当x<0时,合并到右下角
	 * @param y
	 *            y坐标,默认合并到左上角,当y<0时,合并到右下角
	 * @author 张军
	 * @date 2015-11-03 21:59:00
	 * @modifiyNote
	 * @version 1.0
	 */
	public static void writeImageMerge(File fromFile, File toFile, File destFile, int x, int y) {
		InputStream frominput = null;
		InputStream toinput = null;
		OutputStream output = null;
		try {
			// 获取源图片输入流from
			frominput = new BufferedInputStream(new FileInputStream(fromFile));
			// 获取源图片输入流to
			toinput = new BufferedInputStream(new FileInputStream(toFile));
			// 获取文件输出流
			output = new BufferedOutputStream(new FileOutputStream(destFile));
			// 获取from图片缓冲区
			BufferedImage fromImg = ImageIO.read(frominput);
			// 获取to图片缓冲区
			BufferedImage toImg = ImageIO.read(toinput);
			// 获取from图片宽度
			int fromWidth = fromImg.getWidth();
			// 获取from图片高度
			int fromHeight = fromImg.getHeight();
			// 获取to图片宽度
			int toWidth = toImg.getWidth();
			// 获取to图片高度
			int toHeight = toImg.getHeight();
			// Graphics2D ,Graphics 类,提供了对几何形状、坐标转换、颜色管理和文本布局更为复杂的控制。
			// 它是用于在 Java(tm) 平台上呈现二维形状、文本和图像的基础类。验证码生成可以用到此类。
			// public abstract class Graphics2Dextends Graphics 此 Graphics2D 类扩展了 Graphics 类,
			// 提供了对几何形状、坐标转换、颜色管理和文本布局更为复杂的控制。
			Graphics2D g = toImg.createGraphics();
			// 合并图片
			if (x < 0) {
				// 合并到右下角
				x = toWidth - fromWidth;
			}
			if (y < 0) {
				// 合并到右下角
				y = toHeight - fromHeight;
			}
			g.drawImage(fromImg, x, y, fromWidth, fromHeight, null);
			// 释放资源
			g.dispose();
			// 获取to文件扩展名
			String toExtName = FilenameUtils.getExtension(toFile.getName());
			// 输出to图片缓冲区到输出的文件中
			ImageIO.write(toImg, toExtName, output);
		} catch (Exception e) {
			throw new ServiceException(e);
		} finally {
			IOUtils.closeQuietly(frominput);
			IOUtils.closeQuietly(toinput);
			IOUtils.closeQuietly(output);
		}
	}

	/**
	 * 将两张图片合并后输出图片
	 * 
	 * @param fromFile
	 *            合并来自文件
	 * @param toFile
	 *            合并到文件
	 * @param destFile
	 *            目标文件
	 * @author 张军
	 * @date 2015-11-03 21:59:00
	 * @modifiyNote
	 * @version 1.0
	 */
	public static void writeImageMerge(File fromFile, File toFile, File destFile) {
		writeImageMerge(fromFile, toFile, destFile, 0, 0);
	}

	/**
	 * 将两张图片合并后输出图片
	 * 
	 * @param from
	 *            合并来自文件路径
	 * @param to
	 *            合并到文件路径
	 * @param dest
	 *            目标文件路径
	 * @param x
	 *            x坐标,默认合并到左上角,当x<0时,合并到右下角
	 * @param y
	 *            y坐标,默认合并到左上角,当y<0时,合并到右下角
	 * @author 张军
	 * @date 2015-11-03 21:59:00
	 * @modifiyNote
	 * @version 1.0
	 */
	public static void writeImageMerge(String from, String to, String dest, int x, int y) {
		writeImageMerge(new File(from), new File(to), new File(dest), x, y);
	}

	/**
	 * 将两张图片合并后输出图片
	 * 
	 * @param from
	 *            合并来自文件路径
	 * @param to
	 *            合并到文件路径
	 * @param dest
	 *            目标文件路径
	 * @author 张军
	 * @date 2015-11-03 21:59:00
	 * @modifiyNote
	 * @version 1.0
	 */
	public static void writeImageMerge(String from, String to, String dest) {
		writeImageMerge(new File(from), new File(to), new File(dest), 0, 0);
	}
}



更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论