package com.chenb.test;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import javax.imageio.ImageIO;
import org.springframework.web.multipart.MultipartFile;
//图片工具类
public class ImageUtils {
// 图片服务器的访问路径
private static String IMG_SERVICE_URL = "127.0.0.1:9099";
// 也可以从配置文件中读取
// private String IMG_SERVICE_URL= Global.getConfig("server.imgserver.url");
// 本地存储的相对地址(图片服务器的访问地址)
private static String IMG_SAVE_PATH = "C:\\imgserver\\upload";
// 也可以从配置文件中读取
// private String IMG_SAVE_PATH=Global.getConfig("service.saveImg.path");
// 图片剪切(可以压缩、旋转、剪切)
// srcImage:要剪切的图片
// 压缩到的图片大小,imgW宽,imgH高
// 要剪切的开始坐标(x,y)
// 要剪切的长和高(width,height)
// 旋转角度
public static BufferedImage shearImage(BufferedImage srcImage, Integer imgW, Integer imgH, Integer x, Integer y,
Integer width, Integer height, Integer angel) {
if (imgW == null) {
imgW = srcImage.getWidth();
}
if (imgH == null) {
imgH = srcImage.getHeight();
}
// 压缩图片
Image image = scaledImage(srcImage, imgW, imgH);
// 旋转图片
BufferedImage bufferedImage = rotateImage(image, angel);
// 剪切图片
Image image2 = cropImage(bufferedImage, x, y, width, height);
BufferedImage shearBufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics2d = (Graphics2D) shearBufferedImage.getGraphics();
graphics2d.drawImage(image2, 0, 0, null);
graphics2d.dispose();
// return bufferedImage;
return shearBufferedImage;
}
// 剪切图片
public static Image cropImage(BufferedImage bufferedImage, Integer x, Integer y, Integer width, Integer height) {
// CropImageFilter:用于裁剪图像的 ImageFilter 类
// x - 要提取的矩形顶部的 x 位置
// y - 要提取的矩形顶部的 y 位置
// w - 要提取的矩形宽度
// h - 要提取的矩形高度
CropImageFilter cropImageFilter = new CropImageFilter(x, y, width, height);
// FilteredImageSource:使用现有的图像和过滤器对象作为参数,并使用它们为原图像的新过滤版本产生图像数据。
// FilteredImageSource(ImageProducer orig, ImageFilter imgf)
FilteredImageSource filteredImageSource = new FilteredImageSource(bufferedImage.getSource(), cropImageFilter);
// createImage(ImageProducer producer):使用指定的图像生成器创建一幅图像。
return Toolkit.getDefaultToolkit().createImage(filteredImageSource);
}
// 压缩图片
public static Image scaledImage(BufferedImage srcImage, Integer imgW, Integer imgH) {
// getScaledInstance(int width, int height, int hints):创建此图像的缩放版本。
// hints- 指示用于图像重新取样的算法类型的标志
return srcImage.getScaledInstance(imgW, imgH, Image.SCALE_SMOOTH);
}
// 旋转图片
public static BufferedImage rotateImage(Image src, int angel) {
int src_width = src.getWidth(null);
int src_height = src.getHeight(null);
Rectangle rect_des = calcRotatedSize(new Rectangle(new Dimension(src_width, src_height)), angel);
BufferedImage bufferedImage = new BufferedImage(rect_des.width, rect_des.height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = bufferedImage.createGraphics();
// 平移
g2.translate((rect_des.width - src_width) / 2, (rect_des.height - src_height) / 2);
// 旋转变换
g2.rotate(Math.toRadians(angel), src_width / 2, src_height / 2);
g2.drawImage(src, null, null);
g2.dispose();
return bufferedImage;
}
// 计算旋转后的图片大小
private static Rectangle calcRotatedSize(Rectangle src, int angel) {
// 如果旋转的角度大于90度,需要进行转换
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));
int len_dalta_height = (int) (len * Math.cos(Math.PI - angel_alpha - angel_dalta_height));
int des_width = src.width + len_dalta_width * 2;
int des_height = src.height + len_dalta_height * 2;
return new Rectangle(new Dimension(des_width, des_height));
}
// 图片上传
// file:图片文件。需要引入spring-web包
// type:图片所属分类(用于创建分类路径分开存储图片)如:新闻、头像
public static Map uploadImg(MultipartFile file, String type) {
Map<String, Object> map = new HashMap<String, Object>();
if (file != null) {
// 文件名
String fileName = file.getOriginalFilename();
// 文件后缀名
String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);
// 图片保存文件夹
String imgDir = createSavePath();
// 图片保存路径
String imgSavePath = IMG_SAVE_PATH + File.separator + type + File.separator + imgDir;
File imgFilePath = new File(imgSavePath);
// 如果路径不存在,创建路径
if (!imgFilePath.exists()) {
imgFilePath.mkdirs();
}
// 新的文件名(随机图片名,不会重复)
String imgName = createFileName() + "." + fileType;
// 图片访问路径
String imgUrl = "/" + type + "/" + imgDir + "/" + imgName;
// 图片文件
File imgFile = new File(imgFilePath, imgName);
// 保存文件
FileOutputStream outputStream;
try {
outputStream = new FileOutputStream(imgFile);
outputStream.write(file.getBytes());
outputStream.flush();
if (outputStream != null) {
outputStream.close();
}
map.put("status", 200);
map.put("serviceURL", IMG_SERVICE_URL);
map.put("imgURL", imgUrl);
map.put("imgSize", file.getSize());
return map;
} catch (Exception e) {
e.printStackTrace();
map.put("status", 500);
map.put("msg", "图片上传失败");
return map;
}
}
map.put("status", 501);
map.put("msg", "图片不能为空");
return map;
}
// 创建随机文件名
private static String createFileName() {
Random random = new Random();
int rannum = (int) (random.nextDouble() * (99999 - 10000 + 1)) + 10000;
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
String timeStr = sdf.format(new Date());
String newFileName = timeStr + "_" + rannum;
return newFileName;
}
// 创建保存文件路径
private static String createSavePath() {
Random random = new Random();
int rannum = (int) (random.nextDouble() * (99999 - 10000 + 1)) + 10000;
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
String datePath = sdf.format(new Date());
return datePath;
}
public static void main(String[] args) throws IOException {
// 测试来源图片
String pathname = System.getProperty("user.home") + File.separator + "Desktop" + File.separator + "testmm.jpg";
File file = new File(pathname);
// 测试生成图片
String testPath = System.getProperty("user.home") + File.separator + "Desktop" + File.separator + "test.jpg";
File outFile = new File(testPath);
// 上传图片测试(因为不是表单提交所以没有成功测试)需要引入spring-web包
MultipartFile multipartFile = null;
Map map = uploadImg(multipartFile, "test");
System.out.println(map.toString());
// 旋转图片测试
Image image = ImageIO.read(file);
BufferedImage bufferedImage = rotateImage(image, 60);
// ImageIO.write(bufferedImage, "png", outFile);
// 压缩图片测试
BufferedImage image2 = ImageIO.read(file);
Image image3 = scaledImage(ImageIO.read(file), image2.getWidth() / 2, image2.getHeight() / 2);
BufferedImage bufferedImage3 = new BufferedImage(image3.getWidth(null), image3.getHeight(null),
BufferedImage.TYPE_INT_RGB);
bufferedImage3.getGraphics().drawImage(image3, 0, 0, null);
// ImageIO.write(bufferedImage3, "png", outFile);
// 剪切图片测试
BufferedImage image4 = ImageIO.read(file);
Image image5 = cropImage(image4, 0, 0, 200, 200);
BufferedImage bufferedImage4 = new BufferedImage(image5.getWidth(null), image5.getHeight(null),
BufferedImage.TYPE_INT_RGB);
bufferedImage4.getGraphics().drawImage(image5, 0, 0, null);
// ImageIO.write(bufferedImage4, "png", outFile);
// 图片剪切测试(包括压缩、旋转、剪切)
BufferedImage bufferedImage2 = shearImage(ImageIO.read(file), image.getWidth(null), image.getHeight(null), 100,
100, 200, 200, 60);
ImageIO.write(bufferedImage2, "png", outFile);
}
}
原图:
旋转图片测试后:
压缩图片测试后:
剪切图片测试后:
图片剪切测试(包括压缩、旋转、剪切)