在使用Java2D旋转图片时,如果旋转的角度不是45度的倍数,图片边缘会产生非常明显的锯齿。
旋转的代码如下:
public static BufferedImage rotate(BufferedImage image, double angle) {
double sin = Math.abs(Math.sin(angle)), cos = Math.abs(Math.cos(angle));
int w = image.getWidth(), h = image.getHeight();
int neww = (int) Math.floor(w * cos + h * sin), newh = (int) Math.floor(h * cos + w * sin);
BufferedImage result = new BufferedImage(neww, newh, BufferedImage.TYPE_INT_ARGB_PRE);
Graphics2D g = result.createGraphics();
g.addRenderingHints(RENDER_HINT);
g.translate((neww - w) / 2, (newh - h) / 2);
g.rotate(angle, w / 2, h / 2);
g.drawRenderedImage(image, null);
g.dispose();
return result;
}
其中已经加上了相应的RenderingHints
:
private static HashMap<Object, Object> RENDER_HINT = new HashMap<Object, Object>();
static{
RENDER_HINT.put(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
RENDER_HINT.put(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
RENDER_HINT.put(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
RENDER_HINT.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
RENDER_HINT.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
}
现在对下面这张图片旋转-10度
BufferedImage logo = ImageIO.read(new File("logo.png"));
BufferedImage rotated = rotate(logo, Math.toRadians(-10));
旋转后的图片如下,图片边缘的锯齿惨不忍睹
这里有个取巧的方法可以产生出效果比较好的图片,那就是在旋转前先处理一下图片,给图片加上1-3个像素的透明边框:
public static BufferedImage prerotate(BufferedImage image) {
BufferedImage temp =
new BufferedImage(image.getWidth() + 2, image.getHeight() + 2,
BufferedImage.TYPE_INT_ARGB_PRE);
Graphics2D g = temp.createGraphics();
g.addRenderingHints(RENDER_HINT);
g.drawImage(image, 1, 1, null);
g.dispose();
return temp;
}
先调用一下prerotate
再rotate
,产生的图片效果就好很多了: