java – 如何在BufferedImage中找到对象的范围

huangapple go评论66阅读模式
英文:

java - How do I find the extents of an object within a BufferedImage

问题

我正试图找到 PNG 图像中对象的上、下、左和右范围。图像具有透明背景和中间的黑色圆圈。我如何找到圆圈(完全为黑色)的上、下、左和右范围,从而将圆圈与透明背景隔离?

我目前尝试过的方法如下:

public static BufferedImage trimImage(BufferedImage image) {
    int left = 0, right = 0, up = 0, down = 0;
    
    for (int i = 0; i < image.getHeight(); i++) {
        for (int j = 0; j < image.getWidth(); j++) {
            if (image.getRGB(j, i) == 0) {
                up = i;
                break;
            }
        }
    }
    
    for (int i = 0; i < image.getWidth(); i++) {
        for (int j = 0; j < image.getHeight(); j++) {
            if (image.getRGB(i, j) == 0) {
                left = i;
                break;
            }
        }
    }
    
    for (int i = 0; i < image.getHeight(); i++) {
        for (int j = 0; j < image.getWidth(); j++) {
            if (image.getRGB(j, i) == 0 && i > down) {
                down = i;
            }
        }
    }
    
    for (int i = 0; i < image.getWidth(); i++) {
        for (int j = 0; j < image.getHeight(); j++) {
            if (image.getRGB(i, j) == 0 && i > down) {
                right = i;
            }
        }
    }
    
    System.out.println(up + "," + down + "," + left + "," + right);
    BufferedImage temp = image.getSubimage(left, up, right - left, down - up);
    return temp;
}

你知道是否有更简单的方法吗?这个方法给我返回以下错误:

Exception in thread "main" java.awt.image.RasterFormatException: (x + width) is outside raster

非常感谢你的帮助!

编辑:这里是完整的堆栈跟踪:

Exception in thread "main" java.awt.image.RasterFormatException: (x + width) is outside raster
at sun.awt.image.IntegerInterleavedRaster.createWritableChild(Unknown Source)
at java.awt.image.BufferedImage.getSubimage(Unknown Source)
at main.ImageHandler.trimLetter(ImageHandler.java:114)
at main.HandwritingReader.<init>(HandwritingReader.java:48)
at main.HandwritingReader.main(HandwritingReader.java:55)
英文:

So I am trying to find the upper, lower, left and right extents of an object in a png image. The image has a transparent background and a black circle in the middle. How do I find the upper, lower, left and right extents of the circle (which is completely black) thus isolating the circle from the transparent background?

What I tried so far:

    public static BufferedImage trimImage(BufferedImage image) {
int left = 0, right = 0, up = 0, down = 0;
for(int i = 0; i&lt;image.getHeight(); i++) {
for(int j = 0; j&lt;image.getWidth(); j++) {
if(image.getRGB(j, i)==0) {
up = i;
break;
}
}
}
for(int i = 0; i&lt;image.getWidth(); i++) {
for(int j = 0; j&lt;image.getHeight(); j++) {
if(image.getRGB(i, j)==0) {
left = i;
break;
}
}
}
for(int i = 0; i&lt;image.getHeight(); i++) {
for(int j = 0; j&lt;image.getWidth(); j++) {
if(image.getRGB(j, i)==0&amp;&amp;i&gt;down) {
down = i;
}
}
}
for(int i = 0; i&lt;image.getWidth(); i++) {
for(int j = 0; j&lt;image.getHeight(); j++) {
if(image.getRGB(i, j)==0&amp;&amp;i&gt;down) {
right = i;
}
}
}
System.out.println(up+&quot;,&quot;+down+&quot;,&quot;+left+&quot;,&quot;+right);
BufferedImage temp = image.getSubimage(left, up, right-left, down-up);
return temp;
}

Do you know a simpler method? This gives me the following error:

Exception in thread &quot;main&quot; java.awt.image.RasterFormatException: (x + width) is outside raster

Any help is appreciated. Thanks!

edit: Here's the complete stackTrace():

Exception in thread &quot;main&quot; java.awt.image.RasterFormatException: (x + width) is outside raster
at sun.awt.image.IntegerInterleavedRaster.createWritableChild(Unknown Source)
at java.awt.image.BufferedImage.getSubimage(Unknown Source)
at main.ImageHandler.trimLetter(ImageHandler.java:114)
at main.HandwritingReader.&lt;init&gt;(HandwritingReader.java:48)
at main.HandwritingReader.main(HandwritingReader.java:55)

答案1

得分: 1

考虑到左边是最低的x坐标,顶部是最低的y坐标,右边是最高的x坐标,底部是最高的y坐标。

int left = Integer.MAX_VALUE;
int right = 0;
int top = Integer.MAX_VALUE;
int bottom = 0;

for(int i = 0; i<image.getWidth(); i++) {
    for(int j = 0; j<image.getHeight(); j++) {
        if(image.getRGB(i, j)==0) {
            left = Math.min(left, i);
            right = Math.max(right, i);
            top = Math.min(top, j);
            bottom = Math.max(bottom, j);
        }
    }
}

当循环完成时,这将为您提供边界。

我创建了一个示例图像并尝试了它。

BufferedImage image = new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB);
Graphics g = image.getGraphics();
g.setColor(Color.BLACK);
g.fillOval(25, 25, 32, 32);
g.dispose();

在这种情况下,我不得不检查 image.getRGB() != 0,因为透明像素的值为0,但黑色像素的alpha值为255。

英文:

Consider that the left is the lowest x coordinate, top is the lowest y coordinate, right is the highest x coordinate and bottom is the highest y coordinate.

int left = Integer.MAX_VALUE;
int right = 0;
int top = Integer.MAX_VALUE;
int bottom = 0;
for(int i = 0; i&lt;image.getWidth(); i++) {
for(int j = 0; j&lt;image.getHeight(); j++) {
if(image.getRGB(i, j)==0) {
left = Math.min(left, i);
right = Math.max(right, i);
top = Math.min(top, j);
bottom = Math.max(bottom, j);
}
}
}

That should give you the bounds when the loop completes.

I made an example image and tried it out.

		BufferedImage image = new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB);
Graphics g = image.getGraphics();
g.setColor(Color.BLACK);
g.fillOval(25, 25, 32, 32);
g.dispose();

In this case, I had to check if image.getRGB() != 0 because the transparent pixels are 0, but the black pixels have 255 alpha value.

huangapple
  • 本文由 发表于 2020年10月2日 13:46:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/64166704.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定