如何在Java中调整BufferedImage的大小

时间:2014-02-26 22:03:05

标签: java bufferedimage

我正在寻找用Java调整BufferedImage大小的最简单(并且仍然没有问题)的方法。

在一个问题的答案中,用户coobird用他的话(我的意思略有改变)提出了以下解决方案:

**

Graphics对象有一种方法可以在执行调整大小操作的同时绘制Image

Graphics.drawImage(Image, int, int, int, int, ImageObserver) 方法可用于在绘图时指定位置以及图像的大小。

所以,我们可以使用这样的代码:

BufferedImage originalImage = // .. created somehow
BufferedImage newImage = new BufferedImage(SMALL_SIZE, SMALL_SIZE, BufferedImage.TYPE_INT_RGB);

Graphics g = newImage.createGraphics();
g.drawImage(originalImage, 0, 0, SMALL_SIZE, SMALL_SIZE, null);
g.dispose();

这将originalImage newImage,并在SMALL_SIZE的宽度和高度{{1}}上绘制。

**

这个解决方案看起来很简单。我有两个问题:

  • 如果我想将图片尺寸调整为更大的尺寸,不仅仅是更小的吗?>

  • 它是否也可以使用(使用完全相同的代码)?

  • 此解决方案有任何问题吗?

如果有更好的方法,请提出建议。

由于

2 个答案:

答案 0 :(得分:4)

单步缩放的主要问题是它们通常不会产生高质量的输出,因为它们专注于将原始和挤压缩小到一个较小的空间,通常是通过丢弃大量像素信息(不同的算法做不同的事情,所以我在推广)

drawGraphics是否会向上和向下扩展,是的,它会有效地生成还是产生高质量的输出?这些将归结为实现,一般来说,默认使用的大多数缩放算法都集中在速度上。您可以通过一些方式实现这些效果,但通常情况下,除非您缩小范围,否则质量通常会受到影响(根据我的经验)。

您可以查看The Perils of Image.getScaledInstance()了解有关该主题的更多详情和讨论。

一般来说,通常建议使用专用的库,例如imgscalr,从我玩过它的十分钟后,它可以很好地完成工作,也可以执行一个步调。

阶梯刻度基本上以2的幂向上或向下步进图像,直到达到所需的尺寸。请记住,向上扩展只不过是采用一个像素并将其放大一点,因此如果扩展到非常大的尺寸,质量将始终是一个问题。

例如......

请记住,任何缩放通常都是一项昂贵的操作(基于图像的原始尺寸和目标尺寸),因此通常最好尝试在绘制过程的大小和背景中尽可能地执行这些操作。 / p>

还有一个问题是您是否要保持图像的宽高比?根据您的示例,图像将以方形方式缩放(拉伸以满足目标大小的要求),这通常是不期望的。您可以将-1传递给width或height参数,基础算法将保持原始图像的纵横比,或者您可以简单地控制并更多地确定是否要将图像填充或拟合到目标区域,例如......

一般情况下,我大部分时间都避免使用drawImagegetScaledInstance(如果您的扩展只是在一个小范围内,或者想要做一个低质量,快速扩展,这些可以工作)并依赖更多关于适合/填充目标区域和逐步缩放的事情。使用我自己的方法的原因归结为并不总是被允许使用外部库。很高兴不必重新发明轮子

答案 1 :(得分:1)

如果您设置参数,它将放大原件。但是:你应该使用一些保留边缘的智能算法,因为简单地放大图像会使图像模糊并导致感知质量更差。

没问题。从理论上讲,这甚至可以在某些平台上进行硬件加速。