package com.jeecms.common.image; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import org.apache.commons.io.FileUtils; import com.jeecms.common.image.ImageUtils.Position; /** * 图片缩小类。使用方型区域颜色平均算法 */ public class AverageImageScale { /** * 缩小图片 * * @param srcFile * 原图片 * @param destFile * 目标图片 * @param boxWidth * 缩略图最大宽度 * @param boxHeight * 缩略图最大高度 * @throws IOException */ public static void resizeFix(File srcFile, File destFile, int boxWidth, int boxHeight) throws IOException { BufferedImage srcImgBuff = ImageIO.read(srcFile); int width = srcImgBuff.getWidth(); int height = srcImgBuff.getHeight(); if (width <= boxWidth && height <= boxHeight) { FileUtils.copyFile(srcFile, destFile); return; } int zoomWidth; int zoomHeight; if ((float) width / height > (float) boxWidth / boxHeight) { zoomWidth = boxWidth; zoomHeight = Math.round((float) boxWidth * height / width); } else { zoomWidth = Math.round((float) boxHeight * width / height); zoomHeight = boxHeight; } BufferedImage imgBuff = scaleImage(srcImgBuff, width, height, zoomWidth, zoomHeight); writeFile(imgBuff, destFile); } /** * 裁剪并压缩 * * @param srcFile * 原文件 * @param destFile * 目标文件 * @param boxWidth * 缩略图最大宽度 * @param boxHeight * 缩略图最大高度 * @param cutTop * 裁剪TOP * @param cutLeft * 裁剪LEFT * @param cutWidth * 裁剪宽度 * @param catHeight * 裁剪高度 * @throws IOException */ public static void resizeFix(File srcFile, File destFile, int boxWidth, int boxHeight, int cutTop, int cutLeft, int cutWidth, int catHeight) throws IOException { BufferedImage srcImgBuff = ImageIO.read(srcFile); srcImgBuff = srcImgBuff.getSubimage(cutTop, cutLeft, cutWidth, catHeight); int width = srcImgBuff.getWidth(); int height = srcImgBuff.getHeight(); if (width <= boxWidth && height <= boxHeight) { writeFile(srcImgBuff, destFile); return; } int zoomWidth; int zoomHeight; if ((float) width / height > (float) boxWidth / boxHeight) { zoomWidth = boxWidth; zoomHeight = Math.round((float) boxWidth * height / width); } else { zoomWidth = Math.round((float) boxHeight * width / height); zoomHeight = boxHeight; } BufferedImage imgBuff = scaleImage(srcImgBuff, width, height, zoomWidth, zoomHeight); writeFile(imgBuff, destFile); } public static void writeFile(BufferedImage imgBuf, File destFile) throws IOException { File parent = destFile.getParentFile(); if (!parent.exists()) { parent.mkdirs(); } ImageIO.write(imgBuf, "jpeg", destFile); } /** * 添加文字水印 * * @param srcFile * 源图片文件。需要加水印的图片文件。 * @param destFile * 目标图片。加水印后保存的文件。如果和源图片文件一致,则覆盖源图片文件。 * @param minWidth * 需要加水印的最小宽度,如果源图片宽度小于该宽度,则不加水印。 * @param minHeight * 需要加水印的最小高度,如果源图片高度小于该高度,则不加水印。 * @param pos * 加水印的位置。 * @param offsetX * 加水印的位置的偏移量x。 * @param offsetY * 加水印的位置的偏移量y。 * @param text * 水印文字 * @param color * 水印颜色 * @param size * 水印字体大小 * @param alpha * 透明度 * @throws IOException */ public static void imageMark(File srcFile, File destFile, int minWidth, int minHeight, int pos, int offsetX, int offsetY, String text, Color color, int size, int alpha) throws IOException { BufferedImage imgBuff = ImageIO.read(srcFile); int width = imgBuff.getWidth(); int height = imgBuff.getHeight(); if (width <= minWidth || height <= minHeight) { imgBuff = null; if (!srcFile.equals(destFile)) { FileUtils.copyFile(srcFile, destFile); } } else { imageMark(imgBuff, width, height, pos, offsetX, offsetY, text, color, size, alpha); writeFile(imgBuff, destFile); imgBuff = null; } } /** * 添加图片水印 * * @param srcFile * 源图片文件。需要加水印的图片文件。 * @param destFile * 目标图片。加水印后保存的文件。如果和源图片文件一致,则覆盖源图片文件。 * @param minWidth * 需要加水印的最小宽度,如果源图片宽度小于该宽度,则不加水印。 * @param minHeight * 需要加水印的最小高度,如果源图片高度小于该高度,则不加水印。 * @param pos * 加水印的位置。 * @param offsetX * 加水印的位置的偏移量x。 * @param offsetY * 加水印的位置的偏移量y。 * @param markFile * 水印图片 * @throws IOException */ public static void imageMark(File srcFile, File destFile, int minWidth, int minHeight, int pos, int offsetX, int offsetY, File markFile) throws IOException { BufferedImage imgBuff = ImageIO.read(srcFile); int width = imgBuff.getWidth(); int height = imgBuff.getHeight(); if (width <= minWidth || height <= minHeight) { imgBuff = null; if (!srcFile.equals(destFile)) { FileUtils.copyFile(srcFile, destFile); } } else { imageMark(imgBuff, width, height, pos, offsetX, offsetY, markFile); writeFile(imgBuff, destFile); imgBuff = null; } } /** * 添加文字水印 * * @param imgBuff * 原图片 * @param width * 原图宽度 * @param height * 原图高度 * @param pos * 位置。1:左上;2:右上;3左下;4右下;5:中央;0或其他:随机。 * @param offsetX * 水平偏移量。 * @param offsetY * 垂直偏移量。 * @param text * 水印内容 * @param color * 水印颜色 * @param size * 文字大小 * @param alpha * 透明度。0-100。越小越透明。 * @throws IOException */ private static void imageMark(BufferedImage imgBuff, int width, int height, int pos, int offsetX, int offsetY, String text, Color color, int size, int alpha) throws IOException { Position p = ImageUtils.markPosition(width, height, pos, offsetX, offsetY); Graphics2D g = imgBuff.createGraphics(); g.setColor(color); g.setFont(new Font(null, Font.PLAIN, size)); AlphaComposite a = AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, (float) alpha / 100); g.setComposite(a); g.drawString(text, p.getX(), p.getY()); g.dispose(); } private static void imageMark(BufferedImage imgBuff, int width, int height, int pos, int offsetX, int offsetY, File markFile) throws IOException { Position p = ImageUtils.markPosition(width, height, pos, offsetX, offsetY); Graphics2D g = imgBuff.createGraphics(); AlphaComposite a = AlphaComposite.getInstance(AlphaComposite.SRC_ATOP); g.setComposite(a); g.drawImage(ImageIO.read(markFile), p.getX(), p.getY(), null); g.dispose(); } private static BufferedImage scaleImage(BufferedImage srcImgBuff, int width, int height, int zoomWidth, int zoomHeight) { int[] colorArray = srcImgBuff.getRGB(0, 0, width, height, null, 0, width); BufferedImage outBuff = new BufferedImage(zoomWidth, zoomHeight, BufferedImage.TYPE_INT_RGB); // 宽缩小的倍数 float wScale = (float) width / zoomWidth; int wScaleInt = (int) (wScale + 0.5); // 高缩小的倍数 float hScale = (float) height / zoomHeight; int hScaleInt = (int) (hScale + 0.5); int area = wScaleInt * hScaleInt; int x0, x1, y0, y1; int color; long red, green, blue; int x, y, i, j; for (y = 0; y < zoomHeight; y++) { // 得到原图高的Y坐标 y0 = (int) (y * hScale); y1 = y0 + hScaleInt; for (x = 0; x < zoomWidth; x++) { x0 = (int) (x * wScale); x1 = x0 + wScaleInt; red = green = blue = 0; for (i = x0; i < x1; i++) { for (j = y0; j < y1; j++) { color = colorArray[width * j + i]; red += getRedValue(color); green += getGreenValue(color); blue += getBlueValue(color); } } outBuff.setRGB(x, y, comRGB((int) (red / area), (int) (green / area), (int) (blue / area))); } } return outBuff; } private static int getRedValue(int rgbValue) { return (rgbValue & 0x00ff0000) >> 16; } private static int getGreenValue(int rgbValue) { return (rgbValue & 0x0000ff00) >> 8; } private static int getBlueValue(int rgbValue) { return rgbValue & 0x000000ff; } private static int comRGB(int redValue, int greenValue, int blueValue) { return (redValue << 16) + (greenValue << 8) + blueValue; } public static void main(String[] args) throws Exception { long time = System.currentTimeMillis(); AverageImageScale.resizeFix(new File("D:\file\ssh.png"),new File("D:\file\ssh.png"), 500, 500); /*AverageImageScale.resizeFix(new File( "D:\file\ssh.png"), new File( "D:\file\ss.png"), 500, 310, 50, 50, 320, 320);*/ /*AverageImageScale.imageMark(new File( "D:\file\ssh.png"), new File( "D:\file\ss.png"), 12, 12, 1, 20, 20, "jeecms", Color.red, 40, 100); time = System.currentTimeMillis() - time;*/ System.out.println("resize2 img in " + time + "ms"); } }
package com.jeecms.common.image; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 图片辅助类 */ public abstract class ImageUtils { /** * 图片的后缀 */ public static final String[] IMAGE_EXT = new String[] { "jpg", "jpeg", "gif", "png", "bmp" }; /** * 是否是图片 * * @param ext * @return "jpg", "jpeg", "gif", "png", "bmp" 为文件后缀名者为图片 */ public static boolean isValidImageExt(String ext) { ext = ext.toLowerCase(Locale.ENGLISH); for (String s : IMAGE_EXT) { if (s.equalsIgnoreCase(ext)) { return true; } } return false; } /** * Checks if the underlying input stream contains an image. * * @param in * input stream of an image * @return <code>true</code> if the underlying input stream contains an * image, else <code>false</code> */ public static boolean isImage(final InputStream in) { ImageInfo ii = new ImageInfo(); ii.setInput(in); return ii.check(); } /** * 获得水印位置 * * @param width * 原图宽度 * @param height * 原图高度 * @param p * 水印位置 1-5,其他值为随机。1:左上;2:右上;3:左下;4:右下;5:中央。 * @param offsetx * 水平偏移。 * @param offsety * 垂直偏移。 * @return 水印位置 */ public static Position markPosition(int width, int height, int p, int offsetx, int offsety) { if (p < 1 || p > 5) { p = (int) (Math.random() * 5) + 1; } int x, y; switch (p) { // 左上 case 1: x = offsetx; y = offsety; break; // 右上 case 2: x = width + offsetx; y = offsety; break; // 左下 case 3: x = offsetx; y = height + offsety; break; // 右下 case 4: x = width + offsetx; y = height + offsety; break; // 中央 case 5: x = (width / 2) + offsetx; y = (height / 2) + offsety; break; default: throw new RuntimeException("never reach ..."); } return new Position(x, y); } /** * 水印位置 * * 包含左边偏移量,右边偏移量。 */ public static class Position { private int x; private int y; public Position(int x, int y) { this.x = x; this.y = y; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } } public static List<String> getImageSrc(String htmlCode) { List<String> imageSrcList = new ArrayList<String>(); String regular="<img(.*?)src="(.*?)""; String img_pre="(?i)<img(.*?)src=""; String img_sub="""; Pattern p=Pattern.compile(regular,Pattern.CASE_INSENSITIVE); Matcher m = p.matcher(htmlCode); String src = null; while (m.find()) { src=m.group(); src=src.replaceAll(img_pre, "").replaceAll(img_sub, "").trim(); imageSrcList.add(src); } return imageSrcList; } }
图片的处理,欢迎留言...