如何在Java中裁剪图像的某个区域?

21

我正在尝试执行以下代码:

private void crop(HttpServletRequest request, HttpServletResponse response){
    int x = 100;
    int y = 100;
    int w = 3264;
    int h = 2448;

    String path = "D:images\\upload_final\\030311175258.jpg";

    BufferedImage image = ImageIO.read(new File(path));
    BufferedImage out = image.getSubimage(x, y, w, h);

    ImageIO.write(out, "jpg", new File(path));

}

但是它仍然给我相同的错误:

java.awt.image.RasterFormatException: (x + width) is outside of Raster
sun.awt.image.ByteInterleavedRaster.createWritableChild(ByteInterleavedRaster.java:1230)
    java.awt.image.BufferedImage.getSubimage(BufferedImage.java:1156)

我的错误在哪里?

2个回答

33

我的初步猜测是你的 (x + w) > image.getWidth()

如果你打印出 image.getWidth(),它是3264吗? :O

你目前正在做的事情是这样的:

<-- 3264 ------>
+--------------+
|    orig      | +-- Causing the problem
|              | V
|   +--------------+
|100| overlap  |   |
|   |          |   |
|   |          |   |
+---|----------+   |
    |              |
    |    out       |
    +--------------+
如果您想要剪切orig的顶部角落,仅获取"overlap",那么您需要执行:
BufferedImage out = image.getSubimage(x, y, w-x, h-y);
如果你正在尝试做这件事:
+------------------+
|                  |
|  +-----------+   |
|  |           |   |
|  |           |   |
|  |           |   |
|  |           |   |
|  +-----------+   |
|                  |
+------------------+

那么你需要这样做:

BufferedImage out = image.getSubimage(x, y, w-2*x, h-2*y);

@Valter 更新了答案,以使我们正在做的事情更加清晰。 - corsiKa
非常感谢@glowcoder,这个方案完美地解决了我的问题。我采用了第二种方法 =) - Valter Silva
3
没问题。ASCII艺术:Stack Overflow的白板。 :-) - corsiKa

5

如果您只需要在软件中进行裁剪和其他基本的图像处理功能,我建议使用图像处理库。通常实现都经过优化和稳定。

一些Java图像处理库:ImageJMarvinJMagickJIUJH Labsimgscalr

另一个好处是让事情简单化。您可以用几行代码完成很多事情。在下面的示例中,我使用Marvin Framework进行裁剪。

原始图片:
enter image description here

裁剪后的图片:
enter image description here

来源:

MarvinImage image = MarvinImageIO.loadImage("./res/famousFace.jpg");
crop(image.clone(), image, 60, 32, 182, 62);
MarvinImageIO.saveImage(image, "./res/famousFace_cropped.jpg");

裁剪只需要一行代码,你在说什么?当然你得推广你的库。 - gpasch
@ gpasch 抱歉如果我的观点不够清晰。当我建议使用库时,与裁剪无关,而是涉及图像处理的一般情况。许多开发人员来到这里寻找解决方案。我建议使用库,而不是复制和粘贴方法。裁剪只是一行代码,但使用默认的Java API进行调整大小、旋转等操作要复杂得多。我引用了6个框架。当然,我在我的示例中使用了Marvin,因为它是我帮助开发并且我更熟悉的一个。如果其他人在我的解释之后看到这个问题,就像你一样,我会自己删除答案。 - Gabriel Archanjo
@GabrielAmbrósioArchanjo,个人而言,我很喜欢这个答案(尽管我已经打了勾!),但我会说,如果你帮助开发了框架,你应该在答案中声明。=)https://meta.stackexchange.com/a/59302/147335 - corsiKa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接