图片操作工具 package cn.reinforce.plugin.util;import java.awt.AlphaComposite;import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.Image;import java.awt.Rectangle;import java.aw
package cn.reinforce.plugin.util; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.color.ColorSpace; import java.awt.image.BufferedImage; import java.awt.image.ColorConvertOp; import java.awt.image.CropImageFilter; import java.awt.image.FilteredImageSource; import java.awt.image.ImageFilter; import java.io.File; import java.io.IOException; import java.util.Iterator; import javax.imageio.ImageIO; import javax.imageio.ImageReadParam; import javax.imageio.ImageReader; import javax.imageio.stream.ImageInputStream; import org.apache.log4j.Logger; import com.mortennobel.imagescaling.ResampleOp; /** * 图片处理工具类: * 功能:缩放图像、切割图像、图像类型转换、彩色转黑白、文字水印、图片水印等 * * 依赖: ** * * @author 幻幻Fate * @create 2016-09-06 * @since 1.0.0 * */ public class ImageUtil { private static final Logger log = Logger.getLogger(ImageUtil.class); /** * 几种常见的图片格式 */ public static final String IMAGE_TYPE_GIF = "gif";// 图形交换格式 public static final String IMAGE_TYPE_JPG = "jpg";// 联合照片专家组 public static final String IMAGE_TYPE_JPEG = "jpeg";// 联合照片专家组 public static final String IMAGE_TYPE_BMP = "bmp";// 英文Bitmap(位图)的简写,它是Windows操作系统中的标准图像文件格式 public static final String IMAGE_TYPE_PNG = "png";// 可移植网络图形 public static final String IMAGE_TYPE_PSD = "psd";// Photoshop的专用格式Photoshop private ImageUtil() { super(); } /** * 按文件名判断是否是图片 * @param type * @return */ public static boolean isImage(String type){ return IMAGE_TYPE_BMP.equals(type)||IMAGE_TYPE_JPG.equals(type)||IMAGE_TYPE_JPEG.equals(type)||IMAGE_TYPE_GIF.equals(type)||IMAGE_TYPE_PNG.equals(type); } /** * 重新设置图片大小 * @param originalFile * @param resizedFile * @param newWidth * @param newHeight * @param quality */ public static void resize(File originalFile, File resizedFile, int newWidth, int newHeight, float quality) { try { BufferedImage inputBufImage = ImageIO.read(originalFile); ResampleOp resampleOp = new ResampleOp(newWidth, newHeight);// 转换 BufferedImage rescaledTomato = resampleOp.filter(inputBufImage, null); ImageIO.write(rescaledTomato, IMAGE_TYPE_PNG, resizedFile); } catch (IOException e) { log.error("图片操作失败", e); } } /** * 图像切割(按指定起点坐标和宽高切割) * * @param srcImageFile * 源图像地址 * @param result * 切片后的图像地址 * @param x * 目标切片起点坐标X * @param y * 目标切片起点坐标Y * @param width * 目标切片宽度 * @param height * 目标切片高度 * @throws IOException */ public static void cut(File srcImageFile, File result, int x, int y, int width, int height) { ImageInputStream iis = null; try { iis = ImageIO.createImageInputStream(srcImageFile); Iteratorcom.mortennobel * java-image-scaling *0.8.6 *iterator = ImageIO.getImageReaders(iis); ImageReader reader = (ImageReader) iterator.next(); reader.setInput(iis, true); ImageReadParam param = reader.getDefaultReadParam(); Rectangle rectangle = new Rectangle(x, y, width, height); param.setSourceRegion(rectangle); BufferedImage bi = reader.read(0, param); ImageIO.write(bi, IMAGE_TYPE_PNG, result); } catch (Exception e) { log.error("图片操作失败", e); } finally { if (iis != null) { try { iis.close(); } catch (IOException e) { log.error("文件关闭失败", e); } } } } /** * 图像切割(指定切片的宽度和高度) * * @param srcImageFile * 源图像地址 * @param descDir * 切片目标文件夹 * @param destWidth * 目标切片宽度。默认200 * @param destHeight * 目标切片高度。默认150 */ public static void cut(String srcImageFile, String descDir, int destWidth, int destHeight) { try { if (destWidth <= 0) destWidth = 200; // 切片宽度 if (destHeight <= 0) destHeight = 150; // 切片高度 // 读取源图像 BufferedImage bi = ImageIO.read(new File(srcImageFile)); int srcWidth = bi.getHeight(); // 源图宽度 int srcHeight = bi.getWidth(); // 源图高度 if (srcWidth > destWidth && srcHeight > destHeight) { Image img; ImageFilter cropFilter; Image image = bi.getScaledInstance(srcWidth, srcHeight, Image.SCALE_DEFAULT); int cols = 0; // 切片横向数量 int rows = 0; // 切片纵向数量 // 计算切片的横向和纵向数量 if (srcWidth % destWidth == 0) { cols = srcWidth / destWidth; } else { cols = srcWidth / destWidth + 1; } if (srcHeight % destHeight == 0) { rows = srcHeight / destHeight; } else { rows = srcHeight / destHeight + 1; } // 循环建立切片,改进的想法:是否可用多线程加快切割速度 for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { // 四个参数分别为图像起点坐标和宽高,即: CropImageFilter(int x,int y,int width,int height) cropFilter = new CropImageFilter(j * destWidth, i * destHeight, destWidth, destHeight); img = Toolkit.getDefaultToolkit().createImage( new FilteredImageSource(image.getSource(), cropFilter)); BufferedImage tag = new BufferedImage(destWidth, destHeight, BufferedImage.TYPE_INT_RGB); Graphics g = tag.getGraphics(); g.drawImage(img, 0, 0, null); // 绘制缩小后的图 g.dispose(); // 输出为文件 ImageIO.write(tag, "JPEG", new File(descDir + "_r" + i + "_c" + j + ".jpg")); } } } } catch (Exception e) { log.error("图片操作失败", e); } } /** * 图像类型转换:GIF->JPG、GIF->PNG、PNG->JPG、PNG->GIF(X)、BMP->PNG * * @param srcImageFile * 源图像地址 * @param formatName * 包含格式非正式名称的 String:如JPG、JPEG、GIF等 * @param destImageFile * 目标图像地址 */ public static void convert(String srcImageFile, String formatName, String destImageFile) { try { File f = new File(srcImageFile); f.canRead(); f.canWrite(); BufferedImage src = ImageIO.read(f); ImageIO.write(src, formatName, new File(destImageFile)); } catch (Exception e) { log.error("图片操作失败", e); } } /** * 彩色转为黑白 * * @param srcImageFile * 源图像地址 * @param destImageFile * 目标图像地址 */ public static void gray(String srcImageFile, String destImageFile) { try { BufferedImage src = ImageIO.read(new File(srcImageFile)); ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY); ColorConvertOp op = new ColorConvertOp(cs, null); src = op.filter(src, null); ImageIO.write(src, "JPEG", new File(destImageFile)); } catch (IOException e) { log.error("图片操作失败", e); } } /** * 添加文字水印 * * @param targetImg * 目标图片路径,如:C://myPictrue//1.jpg * @param pressText * 水印文字, 如:中国证券网 * @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 pressText(String targetImg, String pressText, String fontName, int fontStyle, int fontSize, Color color, int x, int y, float alpha) { try { File file = new File(targetImg); Image image = ImageIO.read(file); 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(pressText); 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(pressText, x, y + height_1); g.dispose(); ImageIO.write(bufferedImage, IMAGE_TYPE_JPG, file); } catch (Exception e) { log.error("图片操作失败", e); } } /** * 添加图片水印 * * @param targetImg * 目标图片路径,如:C://myPictrue//1.jpg * @param waterImg * 水印图片路径,如:C://myPictrue//logo.png * @param x * 水印图片距离目标图片左侧的偏移量,如果x<0, 则在正中间 * @param y * 水印图片距离目标图片上侧的偏移量,如果y<0, 则在正中间 * @param alpha * 透明度(0.0 -- 1.0, 0.0为完全透明,1.0为完全不透明) */ public static void pressImage(String targetImg, String waterImg, int x, int y, float alpha) { try { File file = new File(targetImg); Image image = ImageIO.read(file); 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(waterImg)); // 水印文件 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, IMAGE_TYPE_JPG, file); } catch (IOException e) { log.error("图片操作失败", e); } } /** * 获取字符长度,一个汉字作为 1 个字符, 一个英文字母作为 0.5 个字符 * * @param text * @return 字符长度,如:text="中国",返回 2;text="test",返回 2;text="中国ABC",返回 4. */ public 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; } }