gpt4 book ai didi

java - 在保持比例的同时调整为最大可能的图像

转载 作者:行者123 更新时间:2023-12-01 09:49:22 24 4
gpt4 key购买 nike

有时我的图像太大,我会收到此错误:

Exception in thread "main" java.lang.NegativeArraySizeException at java.awt.image.DataBufferByte.(Unknown Source) at java.awt.image.Raster.createInterleavedRaster(Unknown Source) at java.awt.image.BufferedImage.(Unknown Source)

每当我收到这个消息时,我都想将图像调整到尽可能大的尺寸,同时保持比例。

我最终得到了以下公式:

    if ( targetWidth * targetHeight >= Integer.MAX_VALUE || targetWidth * targetHeight < 0 ) {
System.out.println( "Target image too big... Size will be adjusted!" );
if ( targetWidth > targetHeight ) {
targetWidth = (int)Math.sqrt( ( Integer.MAX_VALUE ) * (float)( targetWidth / targetHeight ) );
targetHeight = ( Integer.MAX_VALUE ) / targetWidth;
} else {
targetHeight = (int)Math.sqrt( ( Integer.MAX_VALUE ) * (float)( targetHeight / targetWidth ) );
targetWidth = ( Integer.MAX_VALUE ) / targetHeight;
}
}

我还是遇到同样的问题,而且我的条件已经满足了。我猜是这样的

WIDTH * HEIGHT < Integer.MAX_VALUE

显然不是我正在寻找的情况有什么帮助吗?

编辑:经过一番讨论,我认为这个问题的真正问题是:为了不出现 NegativeArraySizeException,我可以传递给 BufferedImage 构造函数的最大可能大小是多少:

at java.awt.image.DataBufferByte.(Unknown Source)

最佳答案

BufferedImage限制与 byte[Integer.MAX_VALUE] 的限制相同由于 Raster 中的限制类( ref )。您还需要承担与平台和实现相关的 header 开销。这就是为什么我建议使用 long 长度的安全缓冲区。 .

(Integer.MAX_VALUE - 8) / 4应该是一个很好的安全限制。

注意:您必须考虑每个像素的大小 ( ref )。例如,BufferedImage.TYPE_4BYTE_ABGR每个像素 4 字节。这意味着您的区域限制是 Integer.MAX_VALUE / 4在这种情况下。当然,每个像素消耗的字节数会因您使用的类型而异。通过表示每个像素的字节数调整测试最大区域。您必须查看 API 才能弄清楚:https://docs.oracle.com/javase/7/docs/api/java/awt/image/BufferedImage.html .

<小时/>

为了在保留纵横比的同时调整图像大小,数学非常简单:

double aspectRatio = width / height;

if (aspectRatio < 1) {
// taller than wide
targetHeight = maxDimension;
targetWidth = (int)(targetHeight * aspectRatio);
} else {
// wider than tall
targetWidth = maxDimension;
targetHeight = (int)(targetWidth / aspectRatio);
}

剩下的就是计算maxDimension的问题了基于图像的总面积。为了便于讨论,假设我们的最大面积是 Integer.MAX_VALUE - 8 (relatively safe)。我们可以使用代数来推断这一点。我们知道width * height = area ,根据上面的公式,我们需要两种方法来求解最大面积。

对于aspectRatio < 1我们用公式代入宽度即可得到:

height * height * aspectRatio = area

求解高度:

  • height^2 * aspectRatio = area
  • height^2 = area / aspectRatio
  • height = Math.sqrt(area / aspectRatio

对于asptectRatio >= 1我们用公式代替高度来得到它:

width * width / aspectRatio = area

求解宽度:

  • 宽度^2/纵横比 = 面积
  • 宽度^2 = 面积 * 纵横比
  • 宽度 = Math.sqrt(面积 * 纵横比)

现在我们可以更新基本公式来考虑最大区域中的形状:

public static final long MAX_AREA = (Integer.MAX_VALUE - 8) / 4;

if (aspectRatio < 1) {
targetHeight = Math.sqrt(MAX_AREA / aspectRatio);
targetWidth = (int)(targetHeight * aspectRatio);
} else {
// wider than tall
targetWidth = Math.sqrt(MAX_AREA * aspectRatio);
targetHeight = (int)(targetWidth / aspectRatio);
}

当然,这留下了测试您是否超过最大面积阈值的基本问题。这需要通过 int 以外的其他方式来完成。 .

public static final long MAX_AREA = (Integer.MAX_VALUE - 8) / 4;
long area = (long)width * (long)height;

if(area < MAX_AREA) {
// recalculate size
}

否则你会遇到溢出问题。

关于java - 在保持比例的同时调整为最大可能的图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37707822/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com