package org.springrain.frame.util;@b@@b@import org.slf4j.Logger;@b@import org.slf4j.LoggerFactory;@b@@b@import javax.imageio.ImageIO;@b@import javax.imageio.ImageReadParam;@b@import javax.imageio.ImageReader;@b@import javax.imageio.stream.ImageInputStream;@b@import java.awt.*;@b@import java.awt.geom.AffineTransform;@b@import java.awt.image.AffineTransformOp;@b@import java.awt.image.BufferedImage;@b@import java.io.File;@b@import java.io.FileInputStream;@b@import java.io.IOException;@b@import java.util.Iterator;@b@@b@/**@b@ * 图片工具类@b@ * 使用图片水印时需要注意Linux服务器是否有中文字体,不然出现中文乱码.参考: https://blog.csdn.net/liuwenbiao1203/article/details/100096031@b@ *@b@ * @author caomei@b@ */@b@public final class ImageUtils {@b@@b@ private static final Logger logger = LoggerFactory.getLogger(ImageUtils.class);@b@@b@ private ImageUtils() {@b@ throw new IllegalAccessError("工具类不能实例化");@b@ }@b@@b@ /**@b@ * 图片水印@b@ *@b@ * @param pressImg 水印图片@b@ * @param targetImg 目标图片@b@ * @param x 修正值 默认在中间@b@ * @param y 修正值 默认在中间@b@ * @param alpha 透明度@b@ */@b@ public static void pressImage(String pressImg, String targetImg, int x, int y, float alpha) {@b@ try {@b@ File img = new File(targetImg);@b@ Image src = ImageIO.read(img);@b@ int wideth = src.getWidth(null);@b@ int height = src.getHeight(null);@b@ BufferedImage image = new BufferedImage(wideth, height, BufferedImage.TYPE_INT_RGB);@b@ Graphics2D g = image.createGraphics();@b@ g.drawImage(src, 0, 0, wideth, height, null);@b@ // 水印文件@b@ Image src_biao = ImageIO.read(new File(pressImg));@b@ int wideth_biao = src_biao.getWidth(null);@b@ int height_biao = src_biao.getHeight(null);@b@ g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));@b@ //g.drawImage(src_biao, (wideth - wideth_biao) / 2, (height - height_biao) / 2, wideth_biao, height_biao, null);@b@ g.drawImage(src_biao, x, y, wideth_biao, height_biao, null);@b@@b@@b@ // 水印文件结束@b@ g.dispose();@b@ ImageIO.write(image, "jpg", img);@b@ } catch (Exception e) {@b@ logger.error(e.getMessage(), e);@b@ }@b@ }@b@@b@ /**@b@ * 文字水印@b@ *@b@ * @param pressText 水印文字@b@ * @param targetImg 目标图片@b@ * @param fontName 字体名称@b@ * @param fontStyle 字体样式@b@ * @param color 字体颜色@b@ * @param fontSize 字体大小@b@ * @param x 修正值@b@ * @param y 修正值@b@ * @param alpha 透明度@b@ */@b@ public static void pressText(String pressText, String targetImg, String fontName, int fontStyle, Color color,@b@ int fontSize, int x, int y, float alpha) {@b@ try {@b@ File img = new File(targetImg);@b@ Image src = ImageIO.read(img);@b@ int width = src.getWidth(null);@b@ int height = src.getHeight(null);@b@ BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);@b@ Graphics2D g = image.createGraphics();@b@ g.drawImage(src, 0, 0, width, height, null);@b@ g.setColor(color);@b@ g.setFont(new Font(fontName, fontStyle, fontSize));@b@ //消除锯齿@b@ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);@b@ g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));@b@ // g.drawString(pressText, (width - (getLength(pressText) * fontSize)) / 2 + x, (height - fontSize) / 2 + y);@b@ g.drawString(pressText, x, y);@b@ g.dispose();@b@ ImageIO.write(image, "jpg", img);@b@ } catch (Exception e) {@b@ logger.error(e.getMessage(), e);@b@ }@b@ }@b@@b@ /**@b@ * 缩放@b@ *@b@ * @param filePath 图片路径@b@ * @param height 高度@b@ * @param width 宽度@b@ * @param bb 比例不对时是否需要补白@b@ */@b@ @SuppressWarnings("static-access")@b@ public static void resize(String filePath, int height, int width, boolean bb) {@b@ File f = new File(filePath);@b@ resize(f, height, width, bb);@b@ }@b@@b@ /**@b@ * 根据图片宽度压缩等比压缩图片@b@ *@b@ * @param f 图片文件@b@ * @param width 图片宽度@b@ * @param bb 比例不对时是否需要补白@b@ */@b@ public static void resize(File f, int width, boolean bb) {@b@@b@ try {@b@ BufferedImage bi = ImageIO.read(f);@b@@b@ int w = bi.getWidth();@b@ int h = bi.getHeight();@b@ int height = width;@b@ // 如果图片的宽度大于等于1000像素,就按宽度1000,高度是根据图片宽度比例计算出来进行压缩@b@ if (w >= width) {@b@ height = (width * h) / w;@b@ } else {@b@ // 如果图片宽度小于1000像素,就按图片的宽度和高度进行压缩(防止图片变形)@b@ width = w;@b@ height = h;@b@ }@b@@b@ if (height <= 0) {@b@ return;@b@ }@b@@b@ ImageUtils.resize(f, height, width, bb);@b@ } catch (IOException e) {@b@ logger.error(e.getMessage(), e);@b@ }@b@@b@ }@b@@b@ /**@b@ * 缩放@b@ *@b@ * @param f 图片路径@b@ * @param height 高度@b@ * @param width 宽度@b@ * @param bb 比例不对时是否需要补白@b@ */@b@ @SuppressWarnings("static-access")@b@ public static void resize(File f, int height, int width, boolean bb) {@b@ try {@b@ double ratio = 0.0; // 缩放比例@b@ // 获取图片后缀@b@ String fileName = f.getName();@b@ String prefix = f.getName().substring(fileName.lastIndexOf(".") + 1);@b@@b@ BufferedImage bi = ImageIO.read(f);@b@ Image itemp = bi.getScaledInstance(width, height, bi.SCALE_SMOOTH);@b@ // 计算比例@b@ if ((bi.getHeight() > height) || (bi.getWidth() > width)) {@b@ if (bi.getHeight() > bi.getWidth()) {@b@ ratio = Integer.valueOf(height).doubleValue() / bi.getHeight();@b@ } else {@b@ ratio = Integer.valueOf(width).doubleValue() / bi.getWidth();@b@ }@b@ AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(ratio, ratio), null);@b@ itemp = op.filter(bi, null);@b@ }@b@ if (bb) {@b@ BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_USHORT_555_RGB);@b@ Graphics2D g = image.createGraphics();@b@ g.setColor(Color.white);@b@ g.fillRect(0, 0, width, height);@b@ if (width == itemp.getWidth(null)) {@b@ g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2, itemp.getWidth(null),@b@ itemp.getHeight(null), Color.white, null);@b@ } else {@b@ g.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0, itemp.getWidth(null),@b@ itemp.getHeight(null), Color.white, null);@b@ }@b@ g.dispose();@b@ itemp = image;@b@ }@b@ // ImageIO.write((BufferedImage) itemp, "jpg", f);@b@ ImageIO.write((BufferedImage) itemp, prefix, f);@b@ } catch (IOException e) {@b@ logger.error(e.getMessage(), e);@b@ }@b@@b@ }@b@@b@@b@ public static int getLength(String text) {@b@ int length = 0;@b@ for (int i = 0; i < text.length(); i++) {@b@ if (String.valueOf(text.charAt(i)).getBytes().length > 1) {@b@ length += 2;@b@ } else {@b@ length += 1;@b@ }@b@ }@b@ return length / 2;@b@ }@b@@b@ /**@b@ * 图片裁切@b@ *@b@ * @param x1 选择区域左上角的x坐标@b@ * @param y1 选择区域左上角的y坐标@b@ * @param width 选择区域的宽度@b@ * @param height 选择区域的高度@b@ * @param sourcePath 源图片路径@b@ * @param descpath 裁切后图片的保存路径@b@ */@b@ public static void cut(int x1, int y1, int width, int height, String sourcePath, String descpath) {@b@ FileInputStream is = null;@b@ ImageInputStream iis = null;@b@ try {@b@ is = new FileInputStream(GlobalStatic.rootDir + sourcePath);@b@ String fileSuffix = sourcePath.substring(sourcePath.lastIndexOf(".") + 1);@b@ Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName(fileSuffix);@b@ ImageReader reader = it.next();@b@ iis = ImageIO.createImageInputStream(is);@b@ reader.setInput(iis, true);@b@ ImageReadParam param = reader.getDefaultReadParam();@b@ Rectangle rect = new Rectangle(x1, y1, width, height);@b@ param.setSourceRegion(rect);@b@ BufferedImage bi = reader.read(0, param);@b@ ImageIO.write(bi, fileSuffix, new File(GlobalStatic.rootDir + descpath));@b@ } catch (Exception ex) {@b@ logger.error(ex.getMessage(), ex);@b@ } finally {@b@ if (is != null) {@b@ try {@b@ is.close();@b@ } catch (IOException e) {@b@ logger.error(e.getMessage(), e);@b@ }@b@ is = null;@b@ }@b@ if (iis != null) {@b@ try {@b@ iis.close();@b@ } catch (IOException e) {@b@ logger.error(e.getMessage(), e);@b@ }@b@ iis = null;@b@ }@b@ }@b@ }@b@@b@@b@ /*@b@ public static void main(String[] args) throws IOException {@b@ // pressImage("G:\\imgtest\\sy.jpg", "G:\\imgtest\\test1.jpg", 0, 0, 0.5f);@b@ // pressText("我是文字水印", "D:/error.jpg", "黑体", 36, Color.white, 80, -10, 0,@b@ // 0.3f);@b@ // resize("G:\\imgtest\\test1.jpg", 500, 500, true);@b@@b@@b@ //int top=102; int left=175; int width=100; int height=50; cut(left, top, width, height, "g:/1.jpg", "g:/100.jpg");@b@@b@ }@b@ */@b@@b@}