All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.dexcoder.commons.utils.ImageUtils Maven / Gradle / Ivy

The newest version!
package com.dexcoder.commons.utils;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.io.*;
import java.util.Iterator;

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import javax.swing.*;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

import com.dexcoder.commons.exceptions.CommonsAssistantException;

/**
 * 图片工具
 * 

* User: liyd * Date: 13-10-31 下午5:07 * version $Id: ImageTools.java, v 0.1 Exp $ */ public final class ImageUtils { /** * 默认图片格式 */ private static final String DEFAULT_IMAGE_FORMAT = "jpg"; /** * 给图片添加水印、可设置水印图片旋转角度 * * @param srcImage the src image * @param waterImage the water image * @param maxImgWidth the max img width * @param alpha the alpha * @param pointX the point x * @param pointY the point y * @param degree 水印图片旋转角度 * @param targetPath 目标图片路径 */ public static void resizeAddLogoSave(InputStream srcImage, InputStream waterImage, int maxImgWidth, float alpha, int pointX, int pointY, Integer degree, String targetPath) { try { BufferedImage srcImg = ImageIO.read(srcImage); ImageIcon imageIcon = new ImageIcon(srcImg); Image image = imageIcon.getImage(); int iWidth = image.getWidth(null); if (iWidth > maxImgWidth) { int iHeight = image.getHeight(null); if (iWidth > iHeight) { image = image.getScaledInstance(maxImgWidth, (maxImgWidth * iHeight) / iWidth, Image.SCALE_SMOOTH); } else { image = image.getScaledInstance((maxImgWidth * iWidth) / iHeight, maxImgWidth, Image.SCALE_SMOOTH); } } // This code ensures that all the pixels in the image are loaded. Image temp = new ImageIcon(image).getImage(); // Create the buffered image. BufferedImage bufferedImage = new BufferedImage(temp.getWidth(null), temp.getHeight(null), BufferedImage.TYPE_INT_RGB); // Copy image to buffered image. Graphics2D g1 = bufferedImage.createGraphics(); // Clear background and paint the image. g1.setColor(Color.white); g1.fillRect(0, 0, temp.getWidth(null), temp.getHeight(null)); g1.drawImage(temp, 0, 0, null); g1.dispose(); // Soften. float softenFactor = 0.05f; float[] softenArray = { 0, softenFactor, 0, softenFactor, 1 - (softenFactor * 4), softenFactor, 0, softenFactor, 0 }; Kernel kernel = new Kernel(3, 3, softenArray); ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null); bufferedImage = cOp.filter(bufferedImage, null); // //重设大小 此方法重设大小画质下降较大 // image = resize(image, maxImgWidth); // 创建画笔对象 Graphics2D g = bufferedImage.createGraphics(); // 设置对线段的锯齿状边缘处理 g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); g.drawImage(image.getScaledInstance(image.getWidth(null), image.getHeight(null), Image.SCALE_SMOOTH), 0, 0, null); // if (null != degree) { // 设置水印旋转 g.rotate(Math.toRadians(degree), (double) bufferedImage.getWidth() / 2, (double) bufferedImage.getHeight() / 2); } // 水印图象的路径 水印一般为gif或者png的,这样可设置透明度 ImageIcon imgIcon = new ImageIcon(ImageIO.read(waterImage)); // 得到Image对象。 Image img = imgIcon.getImage(); g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha)); // 表示水印图片的位置 g.drawImage(img, pointX, pointY, null); g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER)); g.dispose(); //转换出的文件 File fo = new File(targetPath); if (!fo.getParentFile().exists()) { fo.getParentFile().mkdirs(); } String suffix = fo.getName().substring(fo.getName().lastIndexOf(".") + 1); ImageIO.write(bufferedImage, suffix, fo); } catch (Exception e) { throw new CommonsAssistantException("给图片添加水印出现错误", e); } finally { IOUtils.closeQuietly(srcImage); IOUtils.closeQuietly(waterImage); } } /** * 给图片添加文字水印、可设置水印的旋转角度 * * @param logoText the logo text 水印文字 * @param fontColor the font color 水印文字颜色 * @param fontName the font name 水印字体 * @param fontSize the font size 水印字体大小 * @param alpha the alpha 水印字体透明度 * @param pointX the point x 水印字体X坐标 * @param pointY the point y 水印字体Y坐标 * @param degree the degree 水印字段旋转角度 * @param bufferedImage the buffered image 水印图片对象 * @return the buffered image */ public static BufferedImage watermarkText(String logoText, Color fontColor, String fontName, int fontSize, float alpha, int pointX, int pointY, Integer degree, BufferedImage bufferedImage) { try { // 得到画笔对象 Graphics2D g = bufferedImage.createGraphics(); // 设置对线段的锯齿状边缘处理 g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); g.drawImage(bufferedImage.getScaledInstance(bufferedImage.getWidth(null), bufferedImage.getHeight(null), Image.SCALE_SMOOTH), 0, 0, null); if (null != degree) { // 设置水印旋转 g.rotate(Math.toRadians(degree), (double) bufferedImage.getWidth() / 2, (double) bufferedImage.getHeight() / 2); } // 设置颜色 g.setColor(fontColor); // 设置 Font g.setFont(new Font(fontName, Font.PLAIN, fontSize)); g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha)); // 第一参数->设置的内容,后面两个参数->文字在图片上的坐标位置(x,y) . g.drawString(logoText, pointX, pointY); g.dispose(); return bufferedImage; } catch (Exception e) { throw new RuntimeException("给图片添加水印失败", e); } } /** * 重设图片文件大小并设置水印后保存 * * @param inputStream the input stream 图片文件流 * @param logoText the logo text 水印文字 * @param maxImgWidth the max img width 图片重设大小最大宽度 * @param fontColor the font color 水印文件颜色 * @param fontName the font name 水印文字字体 * @param fontSize the font size 水印文字大小 * @param alpha the alpha 水印文字透明度 * @param pointX the point x 水印文字x坐标 * @param pointY the point y 水印文字y坐标 * @param degree the degree 水印文字旋转角度 * @param targetPath the target path 加工后图片保存路径 */ public static void resizeAddLogoWrite(InputStream inputStream, String logoText, int maxImgWidth, Color fontColor, String fontName, int fontSize, float alpha, int pointX, int pointY, Integer degree, String targetPath) { // try { // BufferedImage bufferedImage = ImageIO.read(inputStream); // //重设大小 // BufferedImage resize = resize(bufferedImage, maxImgWidth); // //添加水印 // resize = watermarkText(logoText, fontColor, fontName, fontSize, alpha, pointX, pointY, // degree, resize); // //转换出的文件 // File fo = new File(targetPath); // if (!fo.getParentFile().exists()) { // fo.getParentFile().mkdirs(); // } // String suffix = fo.getName().substring(fo.getName().lastIndexOf(".") + 1); // ImageIO.write(resize, suffix, fo); // } catch (Exception e) { // LOG.warn("重设图片文件大小出现错误", e); // throw new RuntimeException(e); // } finally { // IOUtils.closeQuietly(inputStream); // } } /** * 获取图片的宽和高 * * @param imageFile 图片文件 * @return int[] { 宽, 高 } */ public static int[] getImageWH(File imageFile) { byte[] bytes = readFileToByte(imageFile); return getImageWH(bytes); } /** * 获取图片的宽和高 * * @param bytes 图片byte数组 * @return int[] { 宽, 高 } */ public static int[] getImageWH(byte[] bytes) { InputStream is = null; try { is = new ByteArrayInputStream(bytes); BufferedImage image = ImageIO.read(is); int width = image.getWidth(); int height = image.getHeight(); return new int[] { width, height }; } catch (Exception e) { throw new CommonsAssistantException("读取图片长宽出现异常", e); } finally { IOUtils.closeQuietly(is); } } /** * 按指定的最大值缩放,以Math.max(width,height)为准 * * @param bytes * @param maxSize * @param targetFile */ public static void resizeWriteByMaxSize(byte[] bytes, int maxSize, File targetFile) { BufferedImage bufferedImage = resizeImage(bytes, maxSize, 0, true); String suffix = targetFile.getName().substring(targetFile.getName().lastIndexOf(".") + 1); writeImage(bufferedImage, suffix, targetFile); } /** * 按指定的最大值缩放,以Math.max(width,height)为准 * * @param srcFile * @param maxSize * @param targetFile */ public static void resizeWriteByMaxSize(File srcFile, int maxSize, File targetFile) { byte[] bytes = readFileToByte(srcFile); BufferedImage bufferedImage = resizeImage(bytes, maxSize, 0, true); String suffix = targetFile.getName().substring(targetFile.getName().lastIndexOf(".") + 1); writeImage(bufferedImage, suffix, targetFile); } /** * 根据宽度按比例缩放 * * @param bytes * @param newWith * @param targetFile */ public static void resizeWriteImageByWidth(byte[] bytes, int newWith, File targetFile) { BufferedImage bufferedImage = resizeImage(bytes, newWith, 0, false); String suffix = targetFile.getName().substring(targetFile.getName().lastIndexOf(".") + 1); writeImage(bufferedImage, suffix, targetFile); } /** * 根据宽度按比例缩放 * * @param srcFile * @param newWith * @param targetFile */ public static void resizeWriteImageByWidth(File srcFile, int newWith, File targetFile) { byte[] bytes = readFileToByte(srcFile); BufferedImage bufferedImage = resizeImage(bytes, newWith, 0, false); String suffix = targetFile.getName().substring(targetFile.getName().lastIndexOf(".") + 1); writeImage(bufferedImage, suffix, targetFile); } /** * 按指定的宽度、高度重设图片大小后保存 * * @param bytes * @param newWidth * @param newHeight * @param targetFile */ public static void resizeWriteImage(byte[] bytes, int newWidth, int newHeight, File targetFile) { BufferedImage bufferedImage = resizeImage(bytes, newWidth, newHeight, false); String suffix = targetFile.getName().substring(targetFile.getName().lastIndexOf(".") + 1); writeImage(bufferedImage, suffix, targetFile); } /** * 按指定的宽度、高度重设图片大小后保存 * * @param srcFile * @param newWidth * @param newHeight * @param targetFile */ public static void resizeWriteImage(File srcFile, int newWidth, int newHeight, File targetFile) { byte[] bytes = readFileToByte(srcFile); BufferedImage bufferedImage = resizeImage(bytes, newWidth, newHeight, false); String suffix = targetFile.getName().substring(targetFile.getName().lastIndexOf(".") + 1); writeImage(bufferedImage, suffix, targetFile); } /** * 按指定的最大值缩放,以Math.max(width,height)为准 * * @param bytes the bytes * @param maxSize the max size * @return the byte [ ] */ public static byte[] resizeByMaxSize(byte[] bytes, int maxSize) { BufferedImage bufferedImage = resizeImage(bytes, maxSize, 0, true); return bufferedImageToByte(bufferedImage, DEFAULT_IMAGE_FORMAT); } /** * 按指定的最大值缩放,以Math.max(width,height)为准 * * @param srcFile the src file * @param maxSize the max size * @return the byte [ ] */ public static byte[] resizeByMaxSize(File srcFile, int maxSize) { byte[] bytes = readFileToByte(srcFile); BufferedImage bufferedImage = resizeImage(bytes, maxSize, 0, true); String suffix = srcFile.getName().substring(srcFile.getName().lastIndexOf(".") + 1); return bufferedImageToByte(bufferedImage, suffix); } /** * 根据宽度按比例缩放 * * @param bytes the bytes * @param newWith the new with * @return the byte [ ] */ public static byte[] resizeImageByWidth(byte[] bytes, int newWith) { BufferedImage bufferedImage = resizeImage(bytes, newWith, 0, false); return bufferedImageToByte(bufferedImage, DEFAULT_IMAGE_FORMAT); } /** * 根据宽度按比例缩放 * * @param srcFile the src file * @param newWith the new with * @return the byte [ ] */ public static byte[] resizeImageByWidth(File srcFile, int newWith) { byte[] bytes = readFileToByte(srcFile); BufferedImage bufferedImage = resizeImage(bytes, newWith, 0, false); String suffix = srcFile.getName().substring(srcFile.getName().lastIndexOf(".") + 1); return bufferedImageToByte(bufferedImage, suffix); } /** * 按指定的宽度、高度重设图片大小后保存 * * @param bytes the bytes * @param newWidth the new width * @param newHeight the new height * @return the byte [ ] */ public static byte[] resizeImage(byte[] bytes, int newWidth, int newHeight) { BufferedImage bufferedImage = resizeImage(bytes, newWidth, newHeight, false); return bufferedImageToByte(bufferedImage, DEFAULT_IMAGE_FORMAT); } /** * 按指定的宽度、高度重设图片大小后保存 * * @param srcFile the src file * @param newWidth the new width * @param newHeight the new height * @return the byte [ ] */ public static byte[] resizeImage(File srcFile, int newWidth, int newHeight) { byte[] bytes = readFileToByte(srcFile); BufferedImage bufferedImage = resizeImage(bytes, newWidth, newHeight, false); String suffix = srcFile.getName().substring(srcFile.getName().lastIndexOf(".") + 1); return bufferedImageToByte(bufferedImage, suffix); } /** * 缩放后按指定宽、高裁切图片 * * @param cutWidth * @param cutHeight * @return */ public static byte[] resizeCutImage(byte[] bytes, int cutWidth, int cutHeight) { BufferedImage bufferedImage = resizeCutImage(bytes, cutWidth, cutHeight, true); return bufferedImageToByte(bufferedImage, DEFAULT_IMAGE_FORMAT); } /** * 缩放后按指定宽、高裁切图片 * * @param srcFile * @param cutWidth * @param cutHeight * @return */ public static byte[] resizeCutImage(File srcFile, int cutWidth, int cutHeight) { byte[] bytes = readFileToByte(srcFile); BufferedImage bufferedImage = resizeCutImage(bytes, cutWidth, cutHeight, true); String suffix = srcFile.getName().substring(srcFile.getName().lastIndexOf(".") + 1); return bufferedImageToByte(bufferedImage, suffix); } /** * 按指定的宽度、高度重设图片大小后保存 * * @param srcFile * @param newWidth * @param newHeight * @param targetFile */ public static void resizeCutWriteImage(File srcFile, int newWidth, int newHeight, File targetFile) { byte[] bytes = readFileToByte(srcFile); BufferedImage bufferedImage = resizeCutImage(bytes, newWidth, newHeight, true); String suffix = targetFile.getName().substring(targetFile.getName().lastIndexOf(".") + 1); writeImage(bufferedImage, suffix, targetFile); } /** * 按指定的宽度、高度重设图片大小后保存 * * @param bytes * @param newWidth * @param newHeight * @param targetFile */ public static void resizeCutWriteImage(byte[] bytes, int newWidth, int newHeight, File targetFile) { BufferedImage bufferedImage = resizeCutImage(bytes, newWidth, newHeight, true); String suffix = targetFile.getName().substring(targetFile.getName().lastIndexOf(".") + 1); writeImage(bufferedImage, suffix, targetFile); } /** * 裁切图片 * * @param imageFile 图片文件 * @param x 起始x坐标 * @param y 起始y坐标 * @param cutWidth 裁切的宽度 * @param cutHeight 裁切的高度 * @return */ public static byte[] cutImage(File imageFile, int x, int y, int cutWidth, int cutHeight) { try { BufferedImage image = ImageIO.read(imageFile); image = image.getSubimage(x, y, cutWidth, cutHeight); String suffix = imageFile.getName().substring(imageFile.getName().lastIndexOf(".") + 1); return bufferedImageToByte(image, suffix); } catch (IOException e) { throw new CommonsAssistantException("读取图片失败", e); } } /** * 裁切图片 * * @param imageBytes 图片文件 * @param x 起始x坐标 * @param y 起始y坐标 * @param cutWidth 裁切的宽度 * @param cutHeight 裁切的高度 * @return */ public static byte[] cutImage(byte[] imageBytes, int x, int y, int cutWidth, int cutHeight) { BufferedImage image = readByteToBufferedImage(imageBytes); image = image.getSubimage(x, y, cutWidth, cutHeight); return bufferedImageToByte(image, DEFAULT_IMAGE_FORMAT); } /** * 将BufferedImage对象转换成byte数组 * * @param bufferedImage * @param imageFormat * @return */ private static byte[] bufferedImageToByte(BufferedImage bufferedImage, String imageFormat) { ByteArrayOutputStream bos = null; try { bos = new ByteArrayOutputStream(); ImageIO.write(bufferedImage, (StrUtils.isBlank(imageFormat) ? DEFAULT_IMAGE_FORMAT : imageFormat), bos); byte[] data = bos.toByteArray(); return data; } catch (IOException e) { throw new CommonsAssistantException("将BufferedImage转换成byte数组失败", e); } finally { IOUtils.closeQuietly(bos); } } /** * 将文件转换成byte数组 * * @param srcFile * @return */ private static byte[] readFileToByte(File srcFile) { try { byte[] bytes = FileUtils.readFileToByteArray(srcFile); return bytes; } catch (IOException e) { throw new CommonsAssistantException("将图片文件转换成byte数组失败", e); } } /** * 将byte数组转换成BufferedImage * * @param bytes * @return */ private static BufferedImage readByteToBufferedImage(byte[] bytes) { try { BufferedImage image = ImageIO.read(new ByteArrayInputStream(bytes)); return image; } catch (IOException e) { throw new CommonsAssistantException("将byte数组转换成BufferedImage对象失败", e); } } /** * 按指定格式将图片对象写入到指定文件 * * @param bufferedImage * @param formatName * @param targetFile */ private static void writeImage(BufferedImage bufferedImage, String formatName, File targetFile) { try { if (!targetFile.getParentFile().exists()) { targetFile.getParentFile().mkdirs(); } ImageIO.write(bufferedImage, formatName, targetFile); } catch (IOException e) { throw new CommonsAssistantException("图片写入失败", e); } } /** * 图片按指定宽、高缩放 * * @param bytes 图片byte数组 * @param newWidth 指定的缩放宽度 * @param newHeight 指定的缩放高度,0或小于0时将按比例缩放 * @param isDoHeight 最大宽度是否作用于高度(true时即高度不得超过指定的宽度,竖形长图片高度超过宽度时以高度为准) * @return 缩放后的图片 buffered image */ private static BufferedImage resizeImage(byte[] bytes, int newWidth, int newHeight, boolean isDoHeight) { BufferedImage srcImage = null; try { srcImage = ImageIO.read(new ByteArrayInputStream(bytes)); } catch (Exception e) { throw new RuntimeException("读取图片成BufferedImage失败", e); } // ImageIcon ii = new ImageIcon(bytes); // Image i = ii.getImage(); Image resizedImage = null; //指定高度,强制缩放成指定尺寸 if (newHeight > 0) { resizedImage = srcImage.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH); } else { //按比例缩放 int iWidth = srcImage.getWidth(null); int iHeight = srcImage.getHeight(null); if (iWidth < iHeight && isDoHeight) { resizedImage = srcImage.getScaledInstance((newWidth * iWidth) / iHeight, newWidth, Image.SCALE_SMOOTH); } else { resizedImage = srcImage.getScaledInstance(newWidth, (newWidth * iHeight) / iWidth, Image.SCALE_SMOOTH); } } // This code ensures that all the pixels in the image are loaded. Image temp = new ImageIcon(resizedImage).getImage(); // Create the buffered image. BufferedImage bufferedImage = new BufferedImage(temp.getWidth(null), temp.getHeight(null), BufferedImage.TYPE_INT_RGB); // Copy image to buffered image. Graphics g = bufferedImage.createGraphics(); // Clear background and paint the image. g.setColor(Color.white); g.fillRect(0, 0, temp.getWidth(null), temp.getHeight(null)); g.drawImage(temp, 0, 0, null); g.dispose(); // Soften. float softenFactor = 0.05f; float[] softenArray = { 0, softenFactor, 0, softenFactor, 1 - (softenFactor * 4), softenFactor, 0, softenFactor, 0 }; Kernel kernel = new Kernel(3, 3, softenArray); ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null); bufferedImage = cOp.filter(bufferedImage, null); return bufferedImage; } /** * 图片裁切截取 * * @param bytes 图片对象 * @param cutWidth 裁切截取的宽度 * @param cutHeight 裁切截取的高度 * @param isZoom 是否缩放后截取 * @return 裁切后的图片对象 */ private static BufferedImage resizeCutImage(byte[] bytes, int cutWidth, int cutHeight, boolean isZoom) { BufferedImage image = readByteToBufferedImage(bytes); //是否缩放后截取 if (isZoom) { //获取图片原宽、高 int imageWidth = image.getWidth(); int imageHeight = image.getHeight(); //算出缩放的比例,宽、高以小的为准缩放截取,防止留白 double scale; if (imageWidth < imageHeight) { scale = imageWidth / (double) cutWidth; } else { scale = imageHeight / (double) cutHeight; } //算出新的宽、高后缩放 int newImageWidth = (int) (imageWidth / scale); int newImageHeight = (int) (imageHeight / scale); image = resizeImage(bytes, Math.max(newImageWidth, cutWidth), Math.max(newImageHeight, cutHeight), false); } // This code ensures that all the pixels in the image are loaded. Image temp = new ImageIcon(image).getImage(); // Create the buffered image. BufferedImage bufferedImage = new BufferedImage(cutWidth, cutHeight, BufferedImage.TYPE_INT_RGB); // Copy image to buffered image. Graphics g = bufferedImage.createGraphics(); // Clear background and paint the image. g.setColor(Color.white); g.fillRect(0, 0, cutWidth, cutHeight); g.drawImage(temp, 0, 0, null); g.dispose(); // Soften. float softenFactor = 0.05f; float[] softenArray = { 0, softenFactor, 0, softenFactor, 1 - (softenFactor * 4), softenFactor, 0, softenFactor, 0 }; Kernel kernel = new Kernel(3, 3, softenArray); ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null); bufferedImage = cOp.filter(bufferedImage, null); return bufferedImage; } /** * 获取图片格式 * * @param image * @return */ public static String getImageFormat(File image) { byte[] bytes = readFileToByte(image); return getImageFormat(bytes); } /** * 获取图片格式 * * @param image * @return */ public static String getImageFormat(byte[] image) { ImageInputStream iis = null; try { // Create an image input stream on the image iis = ImageIO.createImageInputStream(new ByteArrayInputStream(image)); // Find all image readers that recognize the image format Iterator iter = ImageIO.getImageReaders(iis); // Use the first reader ImageReader reader = iter.next(); // Return the format name return reader.getFormatName(); } catch (IOException e) { throw new CommonsAssistantException("获取图片格式失败", e); } finally { try { iis.close(); } catch (IOException e) { //ignore } } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy