gpt4 book ai didi

java - BufferedImage getSubimage 抛出异常,参数看似不错

转载 作者:行者123 更新时间:2023-11-30 02:10:47 24 4
gpt4 key购买 nike

这里是 Java 8。尝试坚持使用 BufferedImage API,而不是深入研究 JavaFx 领域。

我有一个宽 768 像素、高 432 像素的 JPG 图像。我想使用 BufferedImage#getSubimage(...) 从其中心裁剪一个居中 400x400 像素的正方形。 .

我有以下代码:

BufferedImage image = ImageIO.read(imageTempFile);

int dim = 400;
int xCropBuffer, yCropBuffer;
xCropBuffer = (image.getWidth() - dim) / 2;
yCropBuffer = (image.getHeight() - dim) / 2;

log.info("width = " + image.getWidth() + ", height = " + image.getHeight() + ", dim = " + dim + ", xCropBuffer = " + xCropBuffer + ", yCropBuffer = " + yCropBuffer);

image = image.getSubimage(xCropBuffer, yCropBuffer + dim, dim, dim);

在运行时这会引发以下异常:

java.awt.image.RasterFormatException: (y + height) is outside of Raster
at sun.awt.image.ByteInterleavedRaster.createWritableChild(ByteInterleavedRaster.java:1248)
at java.awt.image.BufferedImage.getSubimage(BufferedImage.java:1202)
at java_awt_image_BufferedImage$getSubimage.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:149)
at com.myapp.DefaultMediaService.uploadImage(DefaultMediaService.java:56)
at com.myapp.MediaService$uploadImage.call(Unknown Source)

日志在抛出异常之前打印以下消息:

width = 768, height = 432, dim = 400, xCropBuffer = 184, yCropBuffer = 16

所以我传入 image.getSubimage(184, 416, 400, 400) 参数...这应该没问题吧?!图像为 768x432,因此 (184, 416) 应该是其左上角的有效坐标,并且 184 + 400 < 768 和 416 - 400 > 0。因此所有这些参数应映射到图像内的有效 400x400 矩形,对吗?

最佳答案

绘制图像与绘制文本不同,其中上升是从基线到较小的 y 坐标。图像由其左上角指定,并向 x 和 y 的更大坐标延伸。因此,您不应为 y 坐标指定 + dim

BufferedImage oldImage = ImageIO.read(imageFile),
newImage = oldImage.getSubimage(
(oldImage.getWidth()-dim)/2, (oldImage.getHeight()-dim)/2, dim, dim);
ImageIO.write(newImage, "png", imageFile);

为了完整起见,由于您之前的问题似乎有些困惑,这里有一些替代方案可以实现相同的图像转换,它可以用作其他图像操作的模板:

  • 通过BufferedImageOp

    BufferedImage oldImage = ImageIO.read(imageFile),
    newImage = new BufferedImage(dim, dim, oldImage.getType());
    BufferedImageOp op = new AffineTransformOp(
    AffineTransform.getTranslateInstance(
    -(oldImage.getWidth()-dim)/2, -(oldImage.getHeight()-dim)/2),
    AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
    op.filter(oldImage, newImage);
    ImageIO.write(newImage, "png", imageFile);
  • 通过图形

    BufferedImage oldImage = ImageIO.read(imageFile),
    newImage = new BufferedImage(dim, dim, oldImage.getType());
    Graphics2D gfx = newImage.createGraphics();
    gfx.drawImage(oldImage,
    -(oldImage.getWidth()-dim)/2, -(oldImage.getHeight()-dim)/2, null);
    gfx.dispose();
    ImageIO.write(newImage, "png", imageFile);

无论哪种情况,通过使目标图像小于原始图像来暗示裁剪到所需的尺寸。然后,源图像只需通过(-x,-y)进行平移即可选择所需的细节矩形。

关于java - BufferedImage getSubimage 抛出异常,参数看似不错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50156861/

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