概述
要缩放图像,您需要创建一个新图像并将其绘制。 一种方法是使用此处建议的scaleBilinear()的AffineTransformOp.filter()方法。 这使您可以选择插值技术。
private static BufferedImage scale1(BufferedImage before, double scale) {
int w = before.getWidth();
int h = before.getHeight();
// Create a new image of the proper size
int w2 = (int) (w * scale);
int h2 = (int) (h * scale);
BufferedImage after = new BufferedImage(w2, h2, BufferedImage.TYPE_INT_ARGB);
AffineTransform scaleInstance = AffineTransform.getScaleInstance(scale, scale);
AffineTransformOp scaleOp
= new AffineTransformOp(scaleInstance, AffineTransformOp.TYPE_BILINEAR);
scaleOp.filter(before, after);
return after;
}
另一种方法是使用缩放操作进行缩放,将原始图像简单地绘制到新图像中。 此方法非常相似,但它也说明了如何在最终图像中绘制所需的任何内容。 (我在两个方法开始有所不同的空白行中输入。)
private static BufferedImage scale2(BufferedImage before, double scale) {
int w = before.getWidth();
int h = before.getHeight();
// Create a new image of the proper size
int w2 = (int) (w * scale);
int h2 = (int) (h * scale);
BufferedImage after = new BufferedImage(w2, h2, BufferedImage.TYPE_INT_ARGB);
AffineTransform scaleInstance = AffineTransform.getScaleInstance(scale, scale);
AffineTransformOp scaleOp
= new AffineTransformOp(scaleInstance, AffineTransformOp.TYPE_BILINEAR);
Graphics2D g2 = (Graphics2D) after.getGraphics();
// Here, you may draw anything you want into the new image, but we're
// drawing a scaled version of the original image.
g2.drawImage(before, scaleOp, 0, 0);
g2.dispose();
return after;
}
附录:结果
为了说明差异,我比较了以下五种方法的结果。 这是结果的样子,随性能数据一起向上和向下缩放。 (每次运行的性能各不相同,因此请仅将这些数字作为参考。)顶部图像为原始图像。 我将其缩放为两倍大小和一半大小。
如您所见,scaleBilinear()中使用的AffineTransformOp.filter()比scale2()中Graphics2D.drawImage()的标准绘图方法快。BiCubic插值是最慢的,但是在扩展图像时可以得到最佳结果。 (出于性能考虑,只能将其与scaleBilinear()和scaleNearest().进行比较。)Bilinear似乎更适合缩小图像,尽管这是一个艰难的选择。 而NearestNeighbor最快,结果最差。 双线性似乎是速度和质量之间的最佳折衷。 在questionable()方法中调用的Image.getScaledInstance()性能非常差,并且返回的质量与NearestNeighbor相同。 (性能编号仅用于扩展图像。)
public static BufferedImage scaleBilinear(BufferedImage before, double scale) {
final int interpolation = AffineTransformOp.TYPE_BILINEAR;
return scale(before, scale, interpolation);
}
public static BufferedImage scaleBicubic(BufferedImage before, double scale) {
final int interpolation = AffineTransformOp.TYPE_BICUBIC;
return scale(before, scale, interpolation);
}
public static BufferedImage scaleNearest(BufferedImage before, double scale) {
final int interpolation = AffineTransformOp.TYPE_NEAREST_NEIGHBOR;
return scale(before, scale, interpolation);
}
@NotNull
private static
BufferedImage scale(final BufferedImage before, final double scale, final int type) {
int w = before.getWidth();
int h = before.getHeight();
int w2 = (int) (w * scale);
int h2 = (int) (h * scale);
BufferedImage after = new BufferedImage(w2, h2, before.getType());
AffineTransform scaleInstance = AffineTransform.getScaleInstance(scale, scale);
AffineTransformOp scaleOp = new AffineTransformOp(scaleInstance, type);
scaleOp.filter(before, after);
return after;
}
/**
* This is a more generic solution. It produces the same result, but it shows how you
* can draw anything you want into the newly created image. It's slower
* than scaleBilinear().
* @param before The original image
* @param scale The scale factor
* @return A scaled version of the original image
*/
private static BufferedImage scale2(BufferedImage before, double scale) {
int w = before.getWidth();
int h = before.getHeight();
// Create a new image of the proper size
int w2 = (int) (w * scale);
int h2 = (int) (h * scale);
BufferedImage after = new BufferedImage(w2, h2, before.getType());
AffineTransform scaleInstance = AffineTransform.getScaleInstance(scale, scale);
AffineTransformOp scaleOp
= new AffineTransformOp(scaleInstance, AffineTransformOp.TYPE_BILINEAR);
Graphics2D g2 = (Graphics2D) after.getGraphics();
// Here, you may draw anything you want into the new image, but we're just drawing
// a scaled version of the original image. This is slower than
// calling scaleOp.filter().
g2.drawImage(before, scaleOp, 0, 0);
g2.dispose();
return after;
}
/**
* I call this one "questionable" because it uses the questionable getScaledImage()
* method. This method is no longer favored because it's slow, as my tests confirm.
* @param before The original image
* @param scale The scale factor
* @return The scaled image.
*/
private static Image questionable(final BufferedImage before, double scale) {
int w2 = (int) (before.getWidth() * scale);
int h2 = (int) (before.getHeight() * scale);
return before.getScaledInstance(w2, h2, Image.SCALE_FAST);
}
最后
以上就是冷傲鞋垫为你收集整理的java drawimage 缩放_java-如何缩放BufferedImage的全部内容,希望文章能够帮你解决java drawimage 缩放_java-如何缩放BufferedImage所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复