Java Graphics2D 插值似乎不适用于调整大小的图像
Java Graphics2D interpolation doesn't seem to work on resized images
我想将图像调整为适合缩略图的较小尺寸并导出。问题是结果图像看起来非常糟糕,有很多可见的锯齿,就好像它使用的算法非常简单。
我读过很多关于此的文章,建议使用渲染提示来启用质量渲染和双三次插值,但它们似乎不会影响任何东西,就像它们不适用于最终图像一样。我也试过抗锯齿提示(也没有用),但我想它们是为了绘图。
为了简单起见,我将只显示执行调整大小和写入的代码,并且我将为结果图像放置硬编码尺寸。
final BufferedImage imageOriginal = ImageIO.read(new File("/some-path/arch3.jpg"));
int newWidth = 267, newHeight = 400;
BufferedImage imageResized = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = (Graphics2D) imageResized.getGraphics();
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g2d.drawImage(imageOriginal, 0, 0, imageResized.getWidth(), imageResized.getHeight(), 0, 0, imageOriginal.getWidth(), imageOriginal.getHeight(), null);
try {
ImageIO.write(imageResized, "jpg", new File("/some-path/arch3_converted.jpg"));
} catch (Exception ioException) {
System.out.println(ioException.toString());
}
这是原图:https://drive.google.com/open?id=1qsZFQWWneBlHAahV2s5CwlxlCYvnHiU8 (4480×6720)
这是转换后的结果:https://drive.google.com/open?id=1WEcYb7QRlurOK-_dHr_BAk1HrLxPkdIl (267x400)
正如您在结果中看到的(尤其是在线条上),它似乎不正确。
使用"image.getScaledInstance"
String imgOriginalPath= "arch3.jpg";
String imgTargetPath= "arch3_resize.jpg";
String imgFormat = "jpg";
int newWidth = 200;
int newHeight = 300;
try{
Image image = ImageIO.read(new File(imgOriginalPath));
Image resizeImage = image.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH);
BufferedImage newImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
Graphics g = newImage.getGraphics();
g.drawImage(resizeImage, 0, 0, null);
g.dispose();
ImageIO.write(newImage, imgFormat, new File(imgTargetPath));
}catch (Exception e){e.printStackTrace();}
我测试了一下,非常棒。我希望你也喜欢它。 :)
我想将图像调整为适合缩略图的较小尺寸并导出。问题是结果图像看起来非常糟糕,有很多可见的锯齿,就好像它使用的算法非常简单。
我读过很多关于此的文章,建议使用渲染提示来启用质量渲染和双三次插值,但它们似乎不会影响任何东西,就像它们不适用于最终图像一样。我也试过抗锯齿提示(也没有用),但我想它们是为了绘图。
为了简单起见,我将只显示执行调整大小和写入的代码,并且我将为结果图像放置硬编码尺寸。
final BufferedImage imageOriginal = ImageIO.read(new File("/some-path/arch3.jpg"));
int newWidth = 267, newHeight = 400;
BufferedImage imageResized = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = (Graphics2D) imageResized.getGraphics();
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g2d.drawImage(imageOriginal, 0, 0, imageResized.getWidth(), imageResized.getHeight(), 0, 0, imageOriginal.getWidth(), imageOriginal.getHeight(), null);
try {
ImageIO.write(imageResized, "jpg", new File("/some-path/arch3_converted.jpg"));
} catch (Exception ioException) {
System.out.println(ioException.toString());
}
这是原图:https://drive.google.com/open?id=1qsZFQWWneBlHAahV2s5CwlxlCYvnHiU8 (4480×6720) 这是转换后的结果:https://drive.google.com/open?id=1WEcYb7QRlurOK-_dHr_BAk1HrLxPkdIl (267x400) 正如您在结果中看到的(尤其是在线条上),它似乎不正确。
使用"image.getScaledInstance"
String imgOriginalPath= "arch3.jpg";
String imgTargetPath= "arch3_resize.jpg";
String imgFormat = "jpg";
int newWidth = 200;
int newHeight = 300;
try{
Image image = ImageIO.read(new File(imgOriginalPath));
Image resizeImage = image.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH);
BufferedImage newImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
Graphics g = newImage.getGraphics();
g.drawImage(resizeImage, 0, 0, null);
g.dispose();
ImageIO.write(newImage, imgFormat, new File(imgTargetPath));
}catch (Exception e){e.printStackTrace();}
我测试了一下,非常棒。我希望你也喜欢它。 :)