You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

395 lines
13 KiB

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<ImageReader> 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<ImageReader> 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("图片实际长宽小于目标长宽, 返回原图<EFBFBD><EFBFBD>?);
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<EFBFBD><EFBFBD>? + 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;
}
}