java drawimage 缩放_java-如何缩放BufferedImage

要缩放图像,您需要创建一个新图像并将其绘制。 一种方法是使用此处建议的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相同。 (性能编号仅用于扩展图像。)

Rg5m4.png

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);

}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值