import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.Image; import java.awt.geom.AffineTransform; import java.awt.image.AffineTransformOp; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.io.OutputStream; import javax.imageio.ImageIO; /** * 图片处理工具类, 图片水印,文字水印,缩放,补白等 * * @author hzp */ public final class ImageUtils { /** 图片格式:JPG */ private static final String PICTRUE_FORMATE_JPG = "jpg"; private ImageUtils() { } /** * 添加图片水印 * * @param originalImage * 目标图片路径,如:d://myPictrue//originalImage.jpg * @param watermarkImage * 水印图片路径,如:d://myPictrue//watermarkImage.png * @param resultImage * 加上水印后生产的图片路径,如:d://myPictrue//resultImage.jpg * @param x * 水印图片距离目标图片左侧的偏移量,如果x<0, 则在正中间 * @param y * 水印图片距离目标图片上侧的偏移量,如果y<0, 则在正中间 * @param alpha * 透明度(0.0 -- 1.0, 0.0为完全透明,1.0为完全不透明) */ public final static void watermarkImage(String originalImage, String watermarkImage, String resultImage, int x, int y, float alpha) { try { File fileOut = new File(resultImage); File fileIn = new File(originalImage); Image image = ImageIO.read(fileIn); int width = image.getWidth(null); int height = image.getHeight(null); BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g = bufferedImage.createGraphics(); g.drawImage(image, 0, 0, width, height, null); Image waterImage = ImageIO.read(new File(watermarkImage)); // 水印文件 int width_1 = waterImage.getWidth(null); int height_1 = waterImage.getHeight(null); g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha)); int widthDiff = width - width_1; int heightDiff = height - height_1; if (x < 0) { x = widthDiff / 2; } else if (x > widthDiff) { x = widthDiff; } if (y < 0) { y = heightDiff / 2; } else if (y > heightDiff) { y = heightDiff; } g.drawImage(waterImage, x, y, width_1, height_1, null); // 水印文件结束 g.dispose(); ImageIO.write(bufferedImage, PICTRUE_FORMATE_JPG, fileOut); } catch (IOException e) { e.printStackTrace(); } } /** * 添加图片水印 * * @param originalImage * 目标图片路径,如:C://myPictrue//originalImage.jpg * @param watermarkImage * 水印图片路径,如:C://myPictrue//watermarkImage.png * @param resultImage * 加上水印后生产的图片路径,如:C://myPictrue//resultImage.jpg * @param x * 水印图片距离目标图片左侧的偏移量,如果x<0, 则在正中间 * @param y * 水印图片距离目标图片上侧的偏移量,如果y<0, 则在正中间 * @param alpha * 透明度(0.0 -- 1.0, 0.0为完全透明,1.0为完全不透明) */ public final static BufferedImage watermarkImage(String originalImage, String watermarkImage, int x, int y, float alpha) { try { File fileIn = new File(originalImage); Image image = ImageIO.read(fileIn); int width = image.getWidth(null); int height = image.getHeight(null); BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g = bufferedImage.createGraphics(); g.drawImage(image, 0, 0, width, height, null); Image waterImage = ImageIO.read(new File(watermarkImage)); // 水印文件 int width_1 = waterImage.getWidth(null); int height_1 = waterImage.getHeight(null); g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha)); int widthDiff = width - width_1; int heightDiff = height - height_1; if (x < 0) { x = widthDiff / 2; } else if (x > widthDiff) { x = widthDiff; } if (y < 0) { y = heightDiff / 2; } else if (y > heightDiff) { y = heightDiff; } g.drawImage(waterImage, x, y, width_1, height_1, null); // 水印文件结束 g.dispose(); return bufferedImage; } catch (IOException e) { e.printStackTrace(); } return null; } /** * 添加文字水印 * * @param originalImagePath * 目标图片路径,如:C://myPictrue//1.jpg * @param watermarkText * 水印文字, 如:中国证券网 * @param fontName * 字体名称, 如:宋体 * @param fontStyle * 字体样式,如:粗体和斜体(Font.BOLD|Font.ITALIC) * @param fontSize * 字体大小,单位为像素 * @param color * 字体颜色 * @param x * 水印文字距离目标图片左侧的偏移量,如果x<0, 则在正中间 * @param y * 水印文字距离目标图片上侧的偏移量,如果y<0, 则在正中间 * @param alpha * 透明度(0.0 -- 1.0, 0.0为完全透明,1.0为完全不透明) */ public static void watermarkText(String originalImagePath, String watermarkText, String resultImagePath, String fontName, int fontStyle, int fontSize, Color color, int x, int y, float alpha) { try { File originalFile = new File(originalImagePath); File resultFile = new File(resultImagePath); Image image = ImageIO.read(originalFile); int width = image.getWidth(null); int height = image.getHeight(null); BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g = bufferedImage.createGraphics(); g.drawImage(image, 0, 0, width, height, null); g.setFont(new Font(fontName, fontStyle, fontSize)); g.setColor(color); g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha)); int width_1 = fontSize * getLength(watermarkText); int height_1 = fontSize; int widthDiff = width - width_1; int heightDiff = height - height_1; if (x < 0) { x = widthDiff / 2; } else if (x > widthDiff) { x = widthDiff; } if (y < 0) { y = heightDiff / 2; } else if (y > heightDiff) { y = heightDiff; } g.drawString(watermarkText, x, y + height_1); g.dispose(); ImageIO.write(bufferedImage, PICTRUE_FORMATE_JPG, resultFile); } catch (Exception e) { e.printStackTrace(); } } /** * 获取字符长度,一个汉字作为 1 个字符, 一个英文字母作为 0.5 个字符 * * @param text * 字符串文本 * @return 字符长度,如:text="中国",返回 2;text="test",返回 2;text="中国ABC",返回 4. */ private static int getLength(String text) { int textLength = text.length(); int length = textLength; for (int i = 0; i < textLength; i++) { if (String.valueOf(text.charAt(i)).getBytes().length > 1) { length++; } } return (length % 2 == 0) ? length / 2 : length / 2 + 1; } /** * 图片缩放 * * @param filePath * 图片路径 * @param targetWidth * 宽度 * @param targetHeight * 高度 * @param outputStream * 将在其中写入数据的 OutputStream * @throws IOException */ public static void resize(String filePath, int targetWidth, int targetHeight, OutputStream outputStream) throws IOException { resize(filePath, targetWidth, targetHeight, outputStream, false); } /** * 图片缩放 * * @param filePath * 图片路径 * @param targetWidth * 宽度 * @param targetHeight * 高度 * @param outputStream * 将在其中写入数据的 OutputStream * @param filler * 比例不对时是否需要补白 * @throws IOException */ public static void resize(String filePath, int targetWidth, int targetHeight, OutputStream outputStream, boolean filler) throws IOException { resize(filePath, targetWidth, targetHeight, outputStream, true, filler); } /** * 图片缩放 * * @param filePath * 图片路径 * @param targetWidth * 宽度 * @param targetHeight * 高度 * @param outputStream * 将在其中写入数据的 OutputStream * @param isZoomInRatio * 是否按比例缩放 * @param filler * 比例不对时是否需要补白 * @throws IOException */ public static void resize(String filePath, int targetWidth, int targetHeight, OutputStream outputStream, boolean isZoomInRatio, boolean filler) throws IOException { File file = new File(filePath); resize(file, targetWidth, targetHeight, outputStream, isZoomInRatio, filler); } /** * 图片缩放 * * @param file * 要缩放的图片文件 * @param targetWidth * 宽度 * @param targetHeight * 高度 * @param outputStream * 将在其中写入数据的 OutputStream * @throws IOException */ public static void resize(File file, int targetWidth, int targetHeight, OutputStream outputStream) throws IOException { resize(file, targetWidth, targetHeight, outputStream, false); } public static OutputStream os ; /** * 图片缩放 * * @param file * 要缩放的图片文件 * @param targetWidth * 宽度 * @param targetHeight * 高度 * @param outputStream * 将在其中写入数据的 OutputStream * @param isZoomInRatio * 是否按比例缩放 * @param filler * 比例不对时是否需要补白 * @throws IOException */ public static void resize(File file, int targetWidth, int targetHeight, OutputStream outputStream, boolean isZoomInRatio, boolean filler) throws IOException { BufferedImage buffer = resizeByAbsoluteSize(file, targetWidth, targetHeight, isZoomInRatio, filler); ImageIO.write(buffer, PICTRUE_FORMATE_JPG, outputStream); } /** * 图片缩放 * * @param file * 要缩放的图片文件 * @param targetWidth * 宽度 * @param targetHeight * 高度 * @param outputStream * 将在其中写入数据的 OutputStream * @param filler * 比例不对时是否需要补白 * @throws IOException */ public static void resize(File file, int targetWidth, int targetHeight, OutputStream outputStream, boolean filler) throws IOException { resize(file, targetWidth, targetHeight, outputStream, true, filler); } /** * 图片缩放 * * @param file * 要缩放的图片文件 * @param targetWidth * 宽度 * @param targetHeight * 高度 * @param isZoomInRatio * 是否按比例缩放 * @param filler * 比例不对时是否需要补白 * @return 一个处理后的缓存图片BufferedImage * @throws IOException */ public static BufferedImage resizeByAbsoluteSize(File file, int targetWidth, int targetHeight, boolean isZoomInRatio, boolean filler) throws IOException { BufferedImage originalPic = ImageIO.read(file); double xRatio = 1D; double yRatio = 1D; BufferedImage tagetImage = null; int originalWidth = originalPic.getWidth(); int originalHeight = originalPic.getHeight(); if (isZoomInRatio) { xRatio = calcZoomRatio(originalWidth, originalHeight, targetWidth, targetHeight); yRatio = xRatio; tagetImage = new BufferedImage( (new Double(originalWidth * xRatio)).intValue(), (new Double(originalHeight * yRatio)).intValue(), BufferedImage.TYPE_3BYTE_BGR); } else { xRatio = calcRatio(originalWidth, targetWidth); yRatio = calcRatio(originalHeight, targetHeight); tagetImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_3BYTE_BGR); } // 生成处理后的图片存储空间。 AffineTransformOp op = new AffineTransformOp( AffineTransform.getScaleInstance(xRatio, yRatio), null); BufferedImage buffer = op.filter(originalPic, tagetImage); // 是否需要补白 if (filler) { Graphics2D graphics = buffer.createGraphics(); graphics.setColor(Color.white); graphics.fillRect(0, 0, targetWidth, targetHeight); if (targetWidth == buffer.getWidth(null)) { graphics.drawImage(buffer, 0, (targetHeight - buffer.getHeight(null)) / 2, buffer.getWidth(null), buffer.getHeight(null), Color.white, null); } else { graphics.drawImage(buffer, (targetWidth - buffer.getWidth(null)) / 2, 0, buffer.getWidth(null), buffer.getHeight(null), Color.white, null); } graphics.dispose(); tagetImage = buffer; } return tagetImage; } /** * 图片缩放 * * @param file * 要缩放的图片文件 * @param targetWidth * 宽度 * @param targetHeight * 高度 * @param filler * 比例不对时是否需要补白 * @return 一个处理后的缓存图片BufferedImage * @throws IOException */ public static BufferedImage resizeByAbsoluteSize(File file, int targetWidth, int targetHeight, boolean filler) throws IOException { return resizeByAbsoluteSize(file, targetWidth, targetHeight, true, filler); } /** * 按比例缩放时,计算缩放比例。 * * @param originalWidth * 图片原始宽度 * @param originalHeigth * 图片原始高度 * @param targetWidth * 图片缩放后最大宽度 * @param targetHeight * 图片缩放后最大高度 * @return 图片缩放比例 */ private static double calcZoomRatio(int originalWidth, int originalHeigth, int targetWidth, int targetHeight) { double ratio = 1D; if ((originalHeigth > targetHeight) || (originalWidth > targetWidth)) { double xRate = calcRatio(originalWidth, targetWidth); double yRate = calcRatio(originalHeigth, targetHeight); ratio = xRate <= yRate ? xRate : yRate; } return ratio; } /** * 计算比率 * * @param original * 被除数 * @param target * 除数 * @return 比率 */ private static double calcRatio(int original, int target) { return (new Integer(target).doubleValue()) / original; } }