¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. |
| | | * |
| | | * Redistribution and use in source and binary forms, with or without |
| | | * modification, are permitted provided that the following conditions are met: |
| | | * |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | * this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright |
| | | * notice, this list of conditions and the following disclaimer in the |
| | | * documentation and/or other materials provided with the distribution. |
| | | * Neither the name of the dreamlu.net developer nor the names of its |
| | | * contributors may be used to endorse or promote products derived from |
| | | * this software without specific prior written permission. |
| | | * Author: Chill åºéª (smallchill@163.com) |
| | | */ |
| | | package org.springblade.core.tool.utils; |
| | | |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springblade.core.tool.support.IMultiOutputStream; |
| | | import org.springblade.core.tool.support.ImagePosition; |
| | | |
| | | import javax.imageio.ImageIO; |
| | | import java.awt.*; |
| | | import java.awt.color.ColorSpace; |
| | | import java.awt.geom.AffineTransform; |
| | | import java.awt.image.*; |
| | | import java.io.*; |
| | | import java.net.URL; |
| | | |
| | | /** |
| | | * å¾çå·¥å
·ç±» |
| | | * |
| | | * @author Chill |
| | | */ |
| | | public final class ImageUtil { |
| | | |
| | | /** |
| | | * Logger for this class |
| | | */ |
| | | private static Logger LOGGER = LoggerFactory.getLogger(ImageUtil.class); |
| | | |
| | | /** |
| | | * é»è®¤è¾åºå¾çç±»å |
| | | */ |
| | | public static final String DEFAULT_IMG_TYPE = "JPEG"; |
| | | |
| | | private ImageUtil() { |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 转æ¢è¾å
¥æµå°byte |
| | | * |
| | | * @param src æº |
| | | * @param type ç±»å |
| | | * @return byte[] |
| | | * @throws IOException å¼å¸¸ |
| | | */ |
| | | public static byte[] toByteArray(BufferedImage src, String type) throws IOException { |
| | | ByteArrayOutputStream os = new ByteArrayOutputStream(); |
| | | ImageIO.write(src, defaultString(type, DEFAULT_IMG_TYPE), os); |
| | | return os.toByteArray(); |
| | | } |
| | | |
| | | /** |
| | | * è·åå¾åå
容 |
| | | * |
| | | * @param srcImageFile æä»¶è·¯å¾ |
| | | * @return BufferedImage |
| | | */ |
| | | public static BufferedImage readImage(String srcImageFile) { |
| | | try { |
| | | return ImageIO.read(new File(srcImageFile)); |
| | | } catch (IOException e) { |
| | | LOGGER.error("Error readImage", e); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * è·åå¾åå
容 |
| | | * |
| | | * @param srcImageFile æä»¶ |
| | | * @return BufferedImage |
| | | */ |
| | | public static BufferedImage readImage(File srcImageFile) { |
| | | try { |
| | | return ImageIO.read(srcImageFile); |
| | | } catch (IOException e) { |
| | | LOGGER.error("Error readImage", e); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * è·åå¾åå
容 |
| | | * |
| | | * @param srcInputStream è¾å
¥æµ |
| | | * @return BufferedImage |
| | | */ |
| | | public static BufferedImage readImage(InputStream srcInputStream) { |
| | | try { |
| | | return ImageIO.read(srcInputStream); |
| | | } catch (IOException e) { |
| | | LOGGER.error("Error readImage", e); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * è·åå¾åå
容 |
| | | * |
| | | * @param url URLå°å |
| | | * @return BufferedImage |
| | | */ |
| | | public static BufferedImage readImage(URL url) { |
| | | try { |
| | | return ImageIO.read(url); |
| | | } catch (IOException e) { |
| | | LOGGER.error("Error readImage", e); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 缩æ¾å¾åï¼ææ¯ä¾ç¼©æ¾ï¼ |
| | | * |
| | | * @param src æºå¾å |
| | | * @param output è¾åºæµ |
| | | * @param type ç±»å |
| | | * @param scale ç¼©æ¾æ¯ä¾ |
| | | * @param flag 缩æ¾éæ©:true æ¾å¤§; false 缩å°; |
| | | */ |
| | | public final static void zoomScale(BufferedImage src, OutputStream output, String type, double scale, boolean flag) { |
| | | try { |
| | | // å¾å°æºå¾å®½ |
| | | int width = src.getWidth(); |
| | | // å¾å°æºå¾é¿ |
| | | int height = src.getHeight(); |
| | | if (flag) { |
| | | // æ¾å¤§ |
| | | width = Long.valueOf(Math.round(width * scale)).intValue(); |
| | | height = Long.valueOf(Math.round(height * scale)).intValue(); |
| | | } else { |
| | | // ç¼©å° |
| | | width = Long.valueOf(Math.round(width / scale)).intValue(); |
| | | height = Long.valueOf(Math.round(height / scale)).intValue(); |
| | | } |
| | | Image image = src.getScaledInstance(width, height, Image.SCALE_DEFAULT); |
| | | BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); |
| | | Graphics g = tag.getGraphics(); |
| | | |
| | | g.drawImage(image, 0, 0, null); |
| | | g.dispose(); |
| | | |
| | | ImageIO.write(tag, defaultString(type, DEFAULT_IMG_TYPE), output); |
| | | |
| | | output.close(); |
| | | } catch (IOException e) { |
| | | LOGGER.error("Error in zoom image", e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 缩æ¾å¾åï¼æé«åº¦å宽度缩æ¾ï¼ |
| | | * |
| | | * @param src æºå¾å |
| | | * @param output è¾åºæµ |
| | | * @param type ç±»å |
| | | * @param height 缩æ¾åçé«åº¦ |
| | | * @param width 缩æ¾åç宽度 |
| | | * @param bb æ¯ä¾ä¸å¯¹æ¶æ¯å¦éè¦è¡¥ç½ï¼true为补ç½; false为ä¸è¡¥ç½; |
| | | * @param fillColor å¡«å
è²ï¼nullæ¶ä¸ºColor.WHITE |
| | | */ |
| | | public final static void zoomFixed(BufferedImage src, OutputStream output, String type, int height, int width, boolean bb, Color fillColor) { |
| | | try { |
| | | double ratio = 0.0; |
| | | Image itemp = src.getScaledInstance(width, height, BufferedImage.SCALE_SMOOTH); |
| | | // è®¡ç®æ¯ä¾ |
| | | if (src.getHeight() > src.getWidth()) { |
| | | ratio = Integer.valueOf(height).doubleValue() / src.getHeight(); |
| | | } else { |
| | | ratio = Integer.valueOf(width).doubleValue() / src.getWidth(); |
| | | } |
| | | AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(ratio, ratio), null); |
| | | itemp = op.filter(src, null); |
| | | |
| | | if (bb) { |
| | | //è¡¥ç½ |
| | | BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); |
| | | Graphics2D g = image.createGraphics(); |
| | | Color fill = fillColor == null ? Color.white : fillColor; |
| | | g.setColor(fill); |
| | | g.fillRect(0, 0, width, height); |
| | | if (width == itemp.getWidth(null)) { |
| | | g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2, itemp.getWidth(null), itemp.getHeight(null), fill, null); |
| | | } else { |
| | | g.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0, itemp.getWidth(null), itemp.getHeight(null), fill, null); |
| | | } |
| | | g.dispose(); |
| | | itemp = image; |
| | | } |
| | | // è¾åºä¸ºæä»¶ |
| | | ImageIO.write((BufferedImage) itemp, defaultString(type, DEFAULT_IMG_TYPE), output); |
| | | // å
³éæµ |
| | | output.close(); |
| | | } catch (IOException e) { |
| | | LOGGER.error("Error in zoom image", e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å¾åè£åª(ææå®èµ·ç¹åæ å宽é«åå²) |
| | | * |
| | | * @param src æºå¾å |
| | | * @param output åçåçå¾åå°å |
| | | * @param type ç±»å |
| | | * @param x ç®æ åçèµ·ç¹åæ X |
| | | * @param y ç®æ åçèµ·ç¹åæ Y |
| | | * @param width ç®æ åç宽度 |
| | | * @param height ç®æ åçé«åº¦ |
| | | */ |
| | | public final static void crop(BufferedImage src, OutputStream output, String type, int x, int y, int width, int height) { |
| | | try { |
| | | // æºå¾å®½åº¦ |
| | | int srcWidth = src.getWidth(); |
| | | // æºå¾é«åº¦ |
| | | int srcHeight = src.getHeight(); |
| | | if (srcWidth > 0 && srcHeight > 0) { |
| | | Image image = src.getScaledInstance(srcWidth, srcHeight, Image.SCALE_DEFAULT); |
| | | // åä¸ªåæ°åå«ä¸ºå¾åèµ·ç¹åæ åå®½é« |
| | | ImageFilter cropFilter = new CropImageFilter(x, y, width, height); |
| | | Image img = Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(image.getSource(), cropFilter)); |
| | | BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); |
| | | Graphics g = tag.getGraphics(); |
| | | g.drawImage(img, 0, 0, width, height, null); |
| | | g.dispose(); |
| | | // è¾åºä¸ºæä»¶ |
| | | ImageIO.write(tag, defaultString(type, DEFAULT_IMG_TYPE), output); |
| | | // å
³éæµ |
| | | output.close(); |
| | | } |
| | | } catch (Exception e) { |
| | | LOGGER.error("Error in cut image", e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å¾ååå²ï¼æå®åççè¡æ°ååæ°ï¼ |
| | | * |
| | | * @param src æºå¾åå°å |
| | | * @param mos åçç®æ æä»¶å¤¹ |
| | | * @param type ç±»å |
| | | * @param prows ç®æ åçè¡æ°ãé»è®¤2ï¼å¿
é¡»æ¯èå´ [1, 20] ä¹å
|
| | | * @param pcols ç®æ åçåæ°ãé»è®¤2ï¼å¿
é¡»æ¯èå´ [1, 20] ä¹å
|
| | | */ |
| | | public final static void sliceWithNumber(BufferedImage src, IMultiOutputStream mos, String type, int prows, int pcols) { |
| | | try { |
| | | int rows = prows <= 0 || prows > 20 ? 2 : prows; |
| | | int cols = pcols <= 0 || pcols > 20 ? 2 : pcols; |
| | | // æºå¾å®½åº¦ |
| | | int srcWidth = src.getWidth(); |
| | | // æºå¾é«åº¦ |
| | | int srcHeight = src.getHeight(); |
| | | if (srcWidth > 0 && srcHeight > 0) { |
| | | Image img; |
| | | ImageFilter cropFilter; |
| | | Image image = src.getScaledInstance(srcWidth, srcHeight, Image.SCALE_DEFAULT); |
| | | // æ¯å¼ åçç宽度 |
| | | int destWidth = (srcWidth % cols == 0) ? (srcWidth / cols) : (srcWidth / cols + 1); |
| | | // æ¯å¼ åççé«åº¦ |
| | | int destHeight = (srcHeight % rows == 0) ? (srcHeight / rows) : (srcHeight / rows + 1); |
| | | // 循ç¯å»ºç«åç |
| | | // æ¹è¿çæ³æ³:æ¯å¦å¯ç¨å¤çº¿ç¨å å¿«åå²é度 |
| | | for (int i = 0; i < rows; i++) { |
| | | for (int j = 0; j < cols; j++) { |
| | | // åä¸ªåæ°åå«ä¸ºå¾åèµ·ç¹åæ åå®½é« |
| | | 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, defaultString(type, DEFAULT_IMG_TYPE), mos.buildOutputStream(i, j)); |
| | | } |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | LOGGER.error("Error in slice image", e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å¾ååå²ï¼æå®åçç宽度åé«åº¦ï¼ |
| | | * |
| | | * @param src æºå¾åå°å |
| | | * @param mos åçç®æ æä»¶å¤¹ |
| | | * @param type ç±»å |
| | | * @param pdestWidth ç®æ åç宽度ãé»è®¤200 |
| | | * @param pdestHeight ç®æ åçé«åº¦ãé»è®¤150 |
| | | */ |
| | | public final static void sliceWithSize(BufferedImage src, IMultiOutputStream mos, String type, int pdestWidth, int pdestHeight) { |
| | | try { |
| | | int destWidth = pdestWidth <= 0 ? 200 : pdestWidth; |
| | | int destHeight = pdestHeight <= 0 ? 150 : pdestHeight; |
| | | // æºå¾å®½åº¦ |
| | | int srcWidth = src.getWidth(); |
| | | // æºå¾é«åº¦ |
| | | int srcHeight = src.getHeight(); |
| | | if (srcWidth > destWidth && srcHeight > destHeight) { |
| | | Image img; |
| | | ImageFilter cropFilter; |
| | | Image image = src.getScaledInstance(srcWidth, srcHeight, Image.SCALE_DEFAULT); |
| | | // åçæ¨ªåæ°é |
| | | int cols = (srcWidth % destWidth == 0) ? (srcWidth / destWidth) : (srcWidth / destWidth + 1); |
| | | // åççºµåæ°é |
| | | int rows = (srcHeight % destHeight == 0) ? (srcHeight / destHeight) : (srcHeight / destHeight + 1); |
| | | // 循ç¯å»ºç«åç |
| | | // æ¹è¿çæ³æ³:æ¯å¦å¯ç¨å¤çº¿ç¨å å¿«åå²é度 |
| | | for (int i = 0; i < rows; i++) { |
| | | for (int j = 0; j < cols; j++) { |
| | | // åä¸ªåæ°åå«ä¸ºå¾åèµ·ç¹åæ åå®½é« |
| | | 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, defaultString(type, DEFAULT_IMG_TYPE), mos.buildOutputStream(i, j)); |
| | | } |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | LOGGER.error("Error in slice image", e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å¾åç±»å转æ¢ï¼GIF-JPGãGIF-PNGãPNG-JPGãPNG-GIF(X)ãBMP-PNG |
| | | * |
| | | * @param src æºå¾åå°å |
| | | * @param formatName å
嫿 ¼å¼éæ£å¼åç§°ç Stringï¼å¦JPGãJPEGãGIFç |
| | | * @param output ç®æ å¾åå°å |
| | | */ |
| | | public final static void convert(BufferedImage src, OutputStream output, String formatName) { |
| | | try { |
| | | // è¾åºä¸ºæä»¶ |
| | | ImageIO.write(src, formatName, output); |
| | | // å
³éæµ |
| | | output.close(); |
| | | } catch (Exception e) { |
| | | LOGGER.error("Error in convert image", e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 彩è²è½¬ä¸ºé»ç½ |
| | | * |
| | | * @param src æºå¾åå°å |
| | | * @param output ç®æ å¾åå°å |
| | | * @param type ç±»å |
| | | */ |
| | | public final static void gray(BufferedImage src, OutputStream output, String type) { |
| | | try { |
| | | ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY); |
| | | ColorConvertOp op = new ColorConvertOp(cs, null); |
| | | src = op.filter(src, null); |
| | | // è¾åºä¸ºæä»¶ |
| | | ImageIO.write(src, defaultString(type, DEFAULT_IMG_TYPE), output); |
| | | // å
³éæµ |
| | | output.close(); |
| | | } catch (IOException e) { |
| | | LOGGER.error("Error in gray image", e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * ç»å¾çæ·»å æåæ°´å° |
| | | * |
| | | * @param src æºå¾å |
| | | * @param output è¾åºæµ |
| | | * @param type ç±»å |
| | | * @param text æ°´å°æå |
| | | * @param font æ°´å°çåä½ |
| | | * @param color æ°´å°çåä½é¢è² |
| | | * @param position æ°´å°ä½ç½® {@link ImagePosition} |
| | | * @param x ä¿®æ£å¼ |
| | | * @param y ä¿®æ£å¼ |
| | | * @param alpha éæåº¦ï¼alpha å¿
é¡»æ¯èå´ [0.0, 1.0] ä¹å
ï¼å
å«è¾¹çå¼ï¼çä¸ä¸ªæµ®ç¹æ°å |
| | | */ |
| | | public final static void textStamp(BufferedImage src, OutputStream output, String type, String text, Font font, Color color |
| | | , int position, int x, int y, float alpha) { |
| | | try { |
| | | int width = src.getWidth(null); |
| | | int height = src.getHeight(null); |
| | | BufferedImage image = new BufferedImage(width, height, |
| | | BufferedImage.TYPE_INT_RGB); |
| | | Graphics2D g = image.createGraphics(); |
| | | g.drawImage(src, 0, 0, width, height, null); |
| | | g.setColor(color); |
| | | g.setFont(font); |
| | | g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha)); |
| | | // 卿å®åæ ç»å¶æ°´å°æå |
| | | ImagePosition boxPos = new ImagePosition(width, height, calcTextWidth(text) * font.getSize(), font.getSize(), position); |
| | | g.drawString(text, boxPos.getX(x), boxPos.getY(y)); |
| | | g.dispose(); |
| | | // è¾åºä¸ºæä»¶ |
| | | ImageIO.write((BufferedImage) image, defaultString(type, DEFAULT_IMG_TYPE), output); |
| | | // å
³éæµ |
| | | output.close(); |
| | | } catch (Exception e) { |
| | | LOGGER.error("Error in textStamp image", e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * ç»å¾çæ·»å å¾çæ°´å° |
| | | * |
| | | * @param src æºå¾å |
| | | * @param output è¾åºæµ |
| | | * @param type ç±»å |
| | | * @param stamp æ°´å°å¾ç |
| | | * @param position æ°´å°ä½ç½® {@link ImagePosition} |
| | | * @param x ä¿®æ£å¼ |
| | | * @param y ä¿®æ£å¼ |
| | | * @param alpha éæåº¦ï¼alpha å¿
é¡»æ¯èå´ [0.0, 1.0] ä¹å
ï¼å
å«è¾¹çå¼ï¼çä¸ä¸ªæµ®ç¹æ°å |
| | | */ |
| | | public final static void imageStamp(BufferedImage src, OutputStream output, String type, BufferedImage stamp |
| | | , int position, int x, int y, float alpha) { |
| | | try { |
| | | int width = src.getWidth(); |
| | | int height = src.getHeight(); |
| | | BufferedImage image = new BufferedImage(width, height, |
| | | BufferedImage.TYPE_INT_RGB); |
| | | Graphics2D g = image.createGraphics(); |
| | | g.drawImage(src, 0, 0, width, height, null); |
| | | // æ°´å°æä»¶ |
| | | int stampWidth = stamp.getWidth(); |
| | | int stampHeight = stamp.getHeight(); |
| | | g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha)); |
| | | ImagePosition boxPos = new ImagePosition(width, height, stampWidth, stampHeight, position); |
| | | g.drawImage(stamp, boxPos.getX(x), boxPos.getY(y), stampWidth, stampHeight, null); |
| | | // æ°´å°æä»¶ç»æ |
| | | g.dispose(); |
| | | // è¾åºä¸ºæä»¶ |
| | | ImageIO.write((BufferedImage) image, defaultString(type, DEFAULT_IMG_TYPE), output); |
| | | // å
³éæµ |
| | | output.close(); |
| | | } catch (Exception e) { |
| | | LOGGER.error("Error imageStamp", e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 计ç®textçé¿åº¦ï¼ä¸ä¸ªä¸æç®ä¸¤ä¸ªåç¬¦ï¼ |
| | | * |
| | | * @param text text |
| | | * @return int |
| | | */ |
| | | public final static int calcTextWidth(String text) { |
| | | int length = 0; |
| | | for (int i = 0; i < text.length(); i++) { |
| | | if (new String(text.charAt(i) + "").getBytes().length > 1) { |
| | | length += 2; |
| | | } else { |
| | | length += 1; |
| | | } |
| | | } |
| | | return length / 2; |
| | | } |
| | | |
| | | /** |
| | | * é»è®¤å符串 |
| | | * @param str å符串 |
| | | * @param defaultStr é»è®¤å¼ |
| | | * @return |
| | | */ |
| | | public static String defaultString(String str, String defaultStr) { |
| | | return ((str == null) ? defaultStr : str); |
| | | } |
| | | |
| | | } |