package com.ucmed.common.util; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.RenderedImage; import java.awt.image.WritableRaster; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Iterator; import javax.imageio.IIOImage; import javax.imageio.ImageIO; import javax.imageio.ImageReadParam; import javax.imageio.ImageReader; import javax.imageio.ImageWriteParam; import javax.imageio.ImageWriter; import javax.imageio.stream.MemoryCacheImageInputStream; import javax.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.FileCopyUtils; import org.springframework.web.multipart.commons.CommonsMultipartFile; public class ImageUtil { private static transient final Logger LOG = LoggerFactory .getLogger(ImageUtil.class); public static String getImageFormat(byte[] fileBuf) throws IOException { try { ByteArrayInputStream bais = new ByteArrayInputStream(fileBuf); MemoryCacheImageInputStream mcis = new MemoryCacheImageInputStream( bais); Iterator readers = ImageIO.getImageReaders(mcis); ImageReader reader = null; String format = null; if (readers.hasNext()) { reader = readers.next(); format = reader.getFormatName(); } return format; } catch (IOException ex) { LOG.error(ex.getLocalizedMessage()); throw ex; } } public static byte[] cut(ClipImage clipImage, HttpServletRequest request) throws IOException { if (clipImage == null || clipImage.getImage_path() == null || clipImage.getImage_path().isEmpty()) return null; String path = request.getSession().getServletContext() .getRealPath(clipImage.getImage_path()); @SuppressWarnings("resource") FileInputStream input = new FileInputStream(new File(path)); byte[] bs = new byte[input.available()]; input.read(bs); return cut(bs, clipImage.getImage_x1(), clipImage.getImage_y1(), clipImage.getImage_width(), clipImage.getImage_height()); } public static byte[] cut(byte[] srcBytes, int x, int y, int width, int height) throws IOException { try { String format = getImageFormat(srcBytes); if (!supportedFormat(format)) { LOG.info("不支持的图片格式 " + format); throw new IOException("不支持的图片格式" + format); } ByteArrayInputStream bais = new ByteArrayInputStream(srcBytes); MemoryCacheImageInputStream mcis = new MemoryCacheImageInputStream( bais); Iterator it = ImageIO .getImageReadersByFormatName(format); ImageReader reader = it.next(); reader.setInput(mcis, true); int srcWidth = reader.getWidth(0); int srcHeight = reader.getHeight(0); if ((x > srcWidth) || (y > srcHeight) || ((x + width) > srcWidth) || ((y + height) > srcHeight)) { LOG.info(String.format("裁剪超出图片限制 x:%s y:%s width:%s height:%s", x, y, width, height)); throw new IOException("裁剪超出图片限制"); } ImageReadParam param = reader.getDefaultReadParam(); Rectangle rect = new Rectangle(x, y, width, height); param.setSourceRegion(rect); BufferedImage bi = reader.read(0, param); ByteArrayOutputStream baos = new ByteArrayOutputStream( srcBytes.length); ImageIO.write(bi, format, baos); baos.flush(); baos.close(); byte[] targetBytes = baos.toByteArray(); return targetBytes; } catch (IOException ex) { LOG.error(ex.getLocalizedMessage()); throw ex; } } public static byte[] compress(byte[] srcBytes, float compressQuality) throws IOException { try { srcBytes = convertToJPG(srcBytes); String format = getImageFormat(srcBytes); ByteArrayInputStream is = new ByteArrayInputStream(srcBytes); ImageWriteParam imgWriteParams = new javax.imageio.plugins.jpeg.JPEGImageWriteParam( null); imgWriteParams.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); imgWriteParams.setCompressionQuality(compressQuality); imgWriteParams.setProgressiveMode(ImageWriteParam.MODE_DISABLED); ColorModel colorModel = ColorModel.getRGBdefault(); imgWriteParams .setDestinationType(new javax.imageio.ImageTypeSpecifier( colorModel, colorModel.createCompatibleSampleModel( 16, 16))); ImageWriter imgWrier = ImageIO.getImageWritersByFormatName(format) .next(); BufferedImage src = ImageIO.read(is); ByteArrayOutputStream out = new ByteArrayOutputStream( srcBytes.length); imgWrier.reset(); imgWrier.setOutput(ImageIO.createImageOutputStream(out)); imgWrier.write(null, new IIOImage(src, null, null), imgWriteParams); out.flush(); out.close(); is.close(); byte[] outBytes = out.toByteArray(); return outBytes; } catch (IOException ex) { LOG.error(ex.getLocalizedMessage()); throw ex; } } public static byte[] generateThumbnail(byte[] srcBytes, int targetwidth, int targetheight) throws IOException { try { srcBytes = convertToJPG(srcBytes); ByteArrayInputStream bais = new ByteArrayInputStream(srcBytes); MemoryCacheImageInputStream mcis = new MemoryCacheImageInputStream( bais); Image src = ImageIO.read(mcis); int originalWidth = src.getWidth(null); int originalHeight = src.getHeight(null); double sx = (double) targetwidth / originalWidth; double sy = (double) targetheight / originalHeight; if (sx > 1.0 || sy > 1.0) { LOG.info("图片实际长宽小于目标长宽, 返回原图?); return srcBytes; } if (sx > sy) { sx = sy; targetwidth = (int) (sx * originalWidth); } else { sy = sx; targetheight = (int) (sy * originalHeight); } BufferedImage tag = new BufferedImage(targetwidth, targetheight, BufferedImage.TYPE_INT_RGB); tag.getGraphics().drawImage(src, 0, 0, targetwidth, targetheight, null); ByteArrayOutputStream out = new ByteArrayOutputStream(); ImageIO.write(tag, "jpg", ImageIO.createImageOutputStream(out)); byte[] outBytes = out.toByteArray(); return outBytes; } catch (IOException ex) { LOG.error(ex.getLocalizedMessage()); throw ex; } } public static byte[] reSize(byte[] srcBytes, int width, int height) throws IOException { srcBytes = convertToJPG(srcBytes); ByteArrayInputStream bais = new ByteArrayInputStream(srcBytes); MemoryCacheImageInputStream mcis = new MemoryCacheImageInputStream(bais); BufferedImage srcBufImage = ImageIO.read(mcis); BufferedImage bufTarget = null; double sx = (double) width / srcBufImage.getWidth(); double sy = (double) height / srcBufImage.getHeight(); int type = srcBufImage.getType(); if (type == BufferedImage.TYPE_CUSTOM) { ColorModel cm = srcBufImage.getColorModel(); WritableRaster raster = cm.createCompatibleWritableRaster(width, height); boolean alphaPremultiplied = cm.isAlphaPremultiplied(); bufTarget = new BufferedImage(cm, raster, alphaPremultiplied, null); } else bufTarget = new BufferedImage(width, height, type); Graphics2D g = bufTarget.createGraphics(); g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); g.drawRenderedImage(srcBufImage, AffineTransform.getScaleInstance(sx, sy)); g.dispose(); ByteArrayOutputStream out = new ByteArrayOutputStream(); ImageIO.write(bufTarget, "jpg", ImageIO.createImageOutputStream(out)); byte[] outBytes = out.toByteArray(); return outBytes; } public static boolean supportedFormat(String format) { if (format == null) { return false; } return (format.equalsIgnoreCase("jpeg") || format.equalsIgnoreCase("png") || format.equalsIgnoreCase("gif") || format.equalsIgnoreCase("jpg") || format .equalsIgnoreCase("bmp")); } public static byte[] convertToJPG(byte[] srcBytes) throws IOException { try { String format = getImageFormat(srcBytes); if (!supportedFormat(format)) { LOG.info("不支持的图片格式 " + format); throw new IOException("不支持的图片格式" + format); } ByteArrayInputStream bais = new ByteArrayInputStream(srcBytes); MemoryCacheImageInputStream mcis = new MemoryCacheImageInputStream( bais); Image img = ImageIO.read(mcis); ByteArrayOutputStream out = new ByteArrayOutputStream(); if (format.equalsIgnoreCase("png") || format.equalsIgnoreCase("gif")) { BufferedImage pngImage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB); pngImage.getGraphics().drawImage(img, 0, 0, img.getWidth(null), img.getHeight(null), Color.WHITE, null); ImageIO.write(pngImage, "jpg", ImageIO.createImageOutputStream(out)); } else { ImageIO.write((RenderedImage) img, "jpg", ImageIO.createImageOutputStream(out)); } return out.toByteArray(); } catch (IOException ex) { LOG.error("图片转换失败 errorMsg? + ex.getMessage()); throw ex; } } public static String saveTempImage(CommonsMultipartFile file, HttpServletRequest request) { byte[] image = file.getBytes(); // 若图片太大则进行等比压缩处理 try { image = reSizeM(file.getInputStream(), 240, 240); } catch (IOException e) { LOG.error(e.getLocalizedMessage()); } return saveImage(image, file.getOriginalFilename() + ".jpg", request, TEMP_PATH); } public static String saveTempImage(CommonsMultipartFile file, HttpServletRequest request, int width, int height) { byte[] image = file.getBytes(); // 若图片太大则进行等比压缩处理 try { image = reSizeM(file.getInputStream(), width, height); } catch (IOException e) { LOG.error(e.getLocalizedMessage()); } return saveImage(image, file.getOriginalFilename() + ".jpg", request, TEMP_PATH); } public static byte[] reSizeM(InputStream image, int width, int height) throws IOException { byte[] bs = new byte[image.available()]; image.read(bs); byte[] bb = bs.clone(); BufferedImage bi = ImageIO.read(new ByteArrayInputStream(bb)); Integer h = bi.getHeight(); Integer w = bi.getWidth(); image.close(); float hr = h.floatValue() / height; float wr = w.floatValue() / width; if (h <= height && w <= width) { } else if (hr > wr) { bs = reSize(bs, (height * w) / h, height); } else { bs = reSize(bs, width, (width * h) / w); } return bs; } public static byte[] reSizeR(byte[] bs, int width, int height) throws IOException { byte[] bb = bs.clone(); BufferedImage bi = ImageIO.read(new ByteArrayInputStream(bb)); int h = bi.getHeight(); int w = bi.getWidth(); if (h > height && w > width) { bs = reSize(bs, width, height); } return bs; } public static final int TEMP_HEIGHT = 240; public static final int TEMP_WIDTH = 240; public static final String TEMP_PATH = "/images/upload/temp/"; public static String saveImage(byte[] image, String fileName, HttpServletRequest request, String _path) { String filePath = null; if (image != null && fileName != null && image.length > 0) { String path = request.getSession().getServletContext() .getRealPath(_path); File _file = new File(path); if (!_file.exists()) { _file.mkdirs(); } try { fileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf(".")); File uploadedFile = new File(path + "/" + fileName); FileCopyUtils.copy(image, uploadedFile); filePath = _path + fileName; } catch (IOException e) { LOG.error(e.getLocalizedMessage()); } } return filePath; } public static void cleanTempImage(HttpServletRequest request, String imagePath) { File tempFile = new File(request.getSession().getServletContext() .getRealPath(imagePath)); if (tempFile.exists()) tempFile.delete(); } public static final String DOBetterWayOR_BIG_SUFFIX = "_84_120.jpg"; public static final String DOBetterWayOR_SMALL_SUFFIX = "_42_60.jpg"; public static String getDoctorBigPhoto(String photo) { if (photo != null && photo.trim().length() > 0 && photo.indexOf(".") == -1) return photo + DOBetterWayOR_BIG_SUFFIX; return photo; } public static String getDoctorSmallPhoto(String photo) { if (photo != null && photo.trim().length() > 0 && photo.indexOf(".") == -1) return photo + DOBetterWayOR_SMALL_SUFFIX; return photo; } public static ClipImage getClipImageByRequest(HttpServletRequest request) { ClipImage img = new ClipImage(); try { img.setImage_height(Integer.parseInt(request .getParameter("image_height"))); img.setImage_width(Integer.parseInt(request .getParameter("image_width"))); img.setImage_x1(Integer.parseInt(request.getParameter("image_x1"))); img.setImage_y1(Integer.parseInt(request.getParameter("image_y1"))); img.setImage_path(request.getParameter("image_path")); } catch (Exception e) { return null; } return img; } }