java图片处理主要是读取网络图片或本地图片,通过jdk的Graphics2D画笔,进行旋转、缩放、剪切、翻转、合并后写到新的本地文件或用response写回浏览器。(注:有些网络图片不能直接访问)参考:https://blog.csdn.net/shenjianxz/article/details/51849188
/**
* 图像处理工具类.
*
* @author jwolf
*/
public class ImageHandleUtil {
/**
* 缩放(存本地)
*
* @param oriImg
* @param width
* @param height
* @param tempFilename
* @return
* @throws Exception
*/
public static String zoom2localfile(String oriImg, int width, int height, String tempFilename) throws Exception {
BufferedImage bi = ImageIO.read(new URL(oriImg));// 读取该图片
Image zoomImage = doZoom(width, height, bi);
String suffix = getImgSuffix(oriImg);
File sf = new File(tempFilename + "." + suffix);
ImageIO.write((RenderedImage) zoomImage, suffix, sf); // 保存图片
return suffix;
}
private static Image doZoom(double width, double height, BufferedImage bi) {
// 计算x轴y轴缩放比例--如需等比例缩放,在调用之前确保参数width和height是等比例变化的
double sx = width / bi.getWidth();
double sy = height / bi.getHeight();
AffineTransformOp op = new AffineTransformOp(
AffineTransform.getScaleInstance(sx, sy), null);
return op.filter(bi, null);
}
/**
* 缩放(写回浏览器)
*
* @param oriImg
* @param width
* @param height
* @param
* @return
* @throws Exception
*/
public static String zoom2browser(String oriImg, int width, int height, HttpServletResponse response) throws Exception {
BufferedImage bi = ImageIO.read(new URL(oriImg));// 读取该图片
// 计算x轴y轴缩放比例--如需等比例缩放,在调用之前确保参数width和height是等比例变化的
Image zoomImage = doZoom(width, height, bi);
String suffix = getImgSuffix(oriImg);
ImageIO.write((RenderedImage) zoomImage, suffix, response.getOutputStream()); // 写回浏览器
return suffix;
}
/**
* 无损旋转(写回浏览器)
*
* @param degree 旋转角度
* @throws Exception
*/
public static void rotate2browser(int degree, String oriImg, HttpServletResponse response) throws Exception {
BufferedImage bi = ImageIO.read(new URL(oriImg)); // 读取该图片
BufferedImage rotateImage = doRotate(bi, degree);//旋转图片
String suffix = getImgSuffix(oriImg);
ImageIO.write(rotateImage, suffix, response.getOutputStream()); // 写回浏览器
}
/**
* 无损旋转(保存到本地)
*
* @param degree 旋转角度
* @throws Exception
*/
public static String rotate2localfile(int degree, String oriImg, String tempFilename) throws Exception {
BufferedImage bi = ImageIO.read(new URL(oriImg)); // 读取图片
BufferedImage rotateImage = doRotate(bi, degree);//旋转图片
String suffix = getImgSuffix(oriImg);
File sf = new File(tempFilename + "." + suffix);
ImageIO.write(rotateImage, suffix, sf); // 保存图片
return suffix;
}
/**
* 旋转
* @param src 图片源
* @param degree 顺时针角度
* @return
*/
private static BufferedImage doRotate(Image src, double degree) {
int src_width = src.getWidth(null);
int src_height = src.getHeight(null);
// calculate the new image size
Rectangle rect_des = CalcRotatedSize(new Rectangle(new Dimension(
src_width, src_height)), degree);
BufferedImage res = null;
res = new BufferedImage(rect_des.width, rect_des.height,
BufferedImage.TYPE_3BYTE_BGR);
Graphics2D g2 = res.createGraphics();
g2.setColor(Color.white); //旋转后的露出的背景色
g2.fillRect(0, 0, rect_des.width, rect_des.height);
// transform
g2.translate((rect_des.width - src_width) / 2,
(rect_des.height - src_height) / 2);
g2.rotate(Math.toRadians(degree), src_width / 2, src_height / 2);
g2.drawImage(src, null, null);
return res;
}
/*计算*/
private static Rectangle CalcRotatedSize(Rectangle src, double angel) {
// if angel is greater than 90 degree, we need to do some conversion
if (angel >= 90) {
if (angel / 90 % 2 == 1) {
int temp = src.height;
src.height = src.width;
src.width = temp;
}
angel = angel % 90;
}
double r = Math.sqrt(src.height * src.height + src.width * src.width) / 2;
double len = 2 * Math.sin(Math.toRadians(angel) / 2) * r;
double angel_alpha = (Math.PI - Math.toRadians(angel)) / 2;
double angel_dalta_width = Math.atan((double) src.height / src.width);
double angel_dalta_height = Math.atan((double) src.width / src.height);
int len_dalta_width = (int) (len * Math.cos(Math.PI - angel_alpha
- angel_dalta_width));
len_dalta_width = len_dalta_width > 0 ? len_dalta_width : -len_dalta_width;
int len_dalta_height = (int) (len * Math.cos(Math.PI - angel_alpha
- angel_dalta_height));
len_dalta_height = len_dalta_height > 0 ? len_dalta_height : -len_dalta_height;
int des_width = src.width + len_dalta_width * 2;
int des_height = src.height + len_dalta_height * 2;
des_width = des_width > 0 ? des_width : -des_width;
des_height = des_height > 0 ? des_height : -des_height;
return new Rectangle(new Dimension(des_width, des_height));
}
/**
* @param oriImg 原图片
* @param startX 开始点横坐标
* @param startY 开始点纵坐标
* @param endX 结束点横坐标
* @param endY 结束点纵坐标
* @throws IOException
* @throws IOException
*/
public static void cut2localfile(String oriImg, int startX, int startY, int endX, int endY, String tempFilename) throws IOException {
BufferedImage bi = ImageIO.read(new URL(oriImg)); // 读取该图片
BufferedImage cutImage = doCut(startX, startY, endX, endY, bi);
String suffix = getImgSuffix(oriImg);
File sf = new File(tempFilename + "." + suffix);
ImageIO.write(cutImage, suffix, sf); // 保存图片
}
/**
* 裁剪图片写回浏览器
*
* @param oriImg 原图片
* @param startX 开始点横坐标
* @param startY 开始点纵坐标
* @param endX 结束点横坐标
* @param endY 结束点纵坐标
* @param response
* @throws IOException
*/
public static void cut2browser(String oriImg, int startX, int startY, int endX, int endY, HttpServletResponse response) throws IOException {
BufferedImage bi = ImageIO.read(new URL(oriImg)); // 读取该图片
BufferedImage cutImage = doCut(startX, startY, endX, endY, bi);
String suffix = getImgSuffix(oriImg);
ImageIO.write(cutImage, suffix, response.getOutputStream()); // 保存图片
}
private static BufferedImage doCut(int startX, int startY, int endX, int endY, BufferedImage bi) {
int width = bi.getWidth();
int height = bi.getHeight();
if (startX <= -1) {
startX = 0;
}
if (startY <= -1) {
startY = 0;
}
if (endX <= -1) {
endX = width - 1;
}
if (endY <= -1) {
endY = height - 1;
}
if (endX > width || startX > width) {
throw new CommonException(CommonConstant.FAILED, "您指定的开始点或结束点已超过图片宽度:" + width);
}
if (endY > height || startY > height) {
throw new CommonException(CommonConstant.FAILED, "您指定的开始点或结束点已超过图片高度:" + height);
}
BufferedImage cutImage = new BufferedImage(endX, endY, bi.getType());
for (int y = startY; y < endY + startY; y++) {
for (int x = startX; x < endX + startX; x++) {
int rgb = bi.getRGB(x, y);
cutImage.setRGB(x - startX, y - startY, rgb);
}
}
return cutImage;
}
/**
* 获取图片后缀
*
* @param oriImg
* @return
*/
private static String getImgSuffix(String oriImg) {
String suffix = null;
if (oriImg.indexOf("png") > 0) {
suffix = "png";
} else if (oriImg.indexOf("jpeg") > 0) {
suffix = "jpeg";
} else if (oriImg.indexOf("bmp") > 0) {
suffix = "bmp";
} else if (oriImg.indexOf("tif") > 0) {
suffix = "tif";
} else if (oriImg.indexOf("gif") > 0) {
suffix = "gif";
}else {
suffix="jpg";
}
return suffix;
}
public static void main(String[] args) throws Exception {
String oriImg = "https://avatar.csdn.net/B/8/8/3_beiguoshaoxia.jpg";
ImageHandleUtil.rotate2localfile(44, oriImg, "rotate");
ImageHandleUtil.zoom2localfile(oriImg, 100, 100, "zoom");
ImageHandleUtil.cut2localfile(oriImg, 0, 0, 44, 44, "cut");
}
}