前言:
本文提供可以任意角度(最小精度1度),旋转图片的Java工具类,旋转后的图片不会失真或丢失边角,根据角度参数,重新绘制图片,达到无损旋转的目的。
一.图片工具类
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* 旋转图片工具类
* @author 大脑补丁
*
*/
public class RotateImageUtil {
/**
*
* @param bufferedImage
* 图片
* @param angel
* 旋转角度
* @return
*/
public static BufferedImage rotateImage(BufferedImage bufferedImage, int angel) {
if (bufferedImage == null) {
return null;
}
if (angel < 0) {
// 将负数角度,纠正为正数角度
angel = angel + 360;
}
int imageWidth = bufferedImage.getWidth(null);
int imageHeight = bufferedImage.getHeight(null);
// 计算重新绘制图片的尺寸
Rectangle rectangle = calculatorRotatedSize(new Rectangle(new Dimension(imageWidth, imageHeight)), angel);
// 获取原始图片的透明度
int type = bufferedImage.getColorModel().getTransparency();
BufferedImage newImage = null;
newImage = new BufferedImage(rectangle.width, rectangle.height, type);
Graphics2D graphics = newImage.createGraphics();
// 平移位置
graphics.translate((rectangle.width - imageWidth) / 2, (rectangle.height - imageHeight) / 2);
// 旋转角度
graphics.rotate(Math.toRadians(angel), imageWidth / 2, imageHeight / 2);
// 绘图
graphics.drawImage(bufferedImage, null, null);
return newImage;
}
/**
* 旋转图片
*
* @param image
* 图片
* @param angel
* 旋转角度
* @return
*/
public static BufferedImage rotateImage(Image image, int angel) {
if (image == null) {
return null;
}
if (angel < 0) {
// 将负数角度,纠正为正数角度
angel = angel + 360;
}
int imageWidth = image.getWidth(null);
int imageHeight = image.getHeight(null);
Rectangle rectangle = calculatorRotatedSize(new Rectangle(new Dimension(imageWidth, imageHeight)), angel);
BufferedImage newImage = null;
newImage = new BufferedImage(rectangle.width, rectangle.height, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = newImage.createGraphics();
// transform
graphics.translate((rectangle.width - imageWidth) / 2, (rectangle.height - imageHeight) / 2);
graphics.rotate(Math.toRadians(angel), imageWidth / 2, imageHeight / 2);
graphics.drawImage(image, null, null);
return newImage;
}
/**
* 计算旋转后的尺寸
*
* @param src
* @param angel
* @return
*/
private static Rectangle calculatorRotatedSize(Rectangle src, int angel) {
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 java.awt.Rectangle(new Dimension(des_width, des_height));
}
/**
* 获取网络图片流(附加)
*
* @param url
* @return
*/
public static InputStream getImageStream(String url) {
try {
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setReadTimeout(5000);
connection.setConnectTimeout(5000);
connection.setRequestMethod("GET");
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
InputStream inputStream = connection.getInputStream();
return inputStream;
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
二.使用示例:
我们来用此工具类,旋转百度翻译的Logo图片,并保存到本地:
图片地址:https://fanyi.bdstatic.com/static/translation/img/header/logo_cbfea26.png
1.将获取网络图片
参考:《Java获取网络图片转化为输入流》,提供Java获取网络图片的方法getImageStream(String url)
。
2.旋转图片
public static void main(String[] args) {
String url = "https://fanyi.bdstatic.com/static/translation/img/header/logo_cbfea26.png";
// 将网络图片转为BufferedImage
try {
BufferedImage bufferedImage = ImageIO.read(RotateImageUtil.getImageStream(url));
// 调用图片旋转工具类,旋转图片
BufferedImage rotateImage = RotateImageUtil.rotateImage(bufferedImage, 45);
// 截取URL中的图片名称和后缀
String fileName = url.substring(url.lastIndexOf("/") + 1, url.length());
// 截取图片后缀名(.png),以保持图片格式不变
String imgSuffix = url.substring(url.lastIndexOf(".") + 1, url.length());
// 将旋转后的图片保存到D盘根目录下
File file = new File("D:\\", fileName);
ImageIO.write(rotateImage, imgSuffix, file);
} catch (IOException e) {
e.printStackTrace();
}
}
###3.旋转前后对比