删除图像JAVA中的空白区域

时间:2016-04-23 13:20:31

标签: java swing bufferedimage

我有一个关于切割图像中的空白区域(或者只是裁剪它)的问题。我想要一个像这样的方法:

public BufferedImage crop(BufferedImage input) {
    return output;
}

它应该这样做:

http://i.stack.imgur.com/IGTRS.png

我知道我可以通过所有像素来获得新的界限,但是对于图像1024x768的问题,我将不得不通过1024 * 768 = 786432(第2次因为我必须通过第一次获得高度界限和第二次获得宽度边界)像素。这不是一个好方法。有什么想法如何快速做到这一点? (如果可能的话,我不想使用neihter任何其他线程或任何其他框架)

谢谢!

1 个答案:

答案 0 :(得分:2)

我在思考很多,并提出了这种方法如何做到这一点。

public static BufferedImage crop(BufferedImage image) {
    int minY = 0, maxY = 0, minX = Integer.MAX_VALUE, maxX = 0;
    boolean isBlank, minYIsDefined = false;
    Raster raster = image.getRaster();

    for (int y = 0; y < image.getHeight(); y++) {
        isBlank = true;

        for (int x = 0; x < image.getWidth(); x++) {
            //Change condition to (raster.getSample(x, y, 3) != 0) 
            //for better performance
            if (raster.getPixel(x, y, (int[]) null)[3] != 0) {
                isBlank = false;

                if (x < minX) minX = x;
                if (x > maxX) maxX = x;
            }
        }

        if (!isBlank) {
            if (!minYIsDefined) {
                minY = y;
                minYIsDefined = true;
            } else {
                if (y > maxY) maxY = y;
            }
        }
    }

    return image.getSubimage(minX, minY, maxX - minX + 1, maxY - minY + 1);
}

此方法仅适用于alpha。要使用“jpg”,您需要在此更改条件(这里的true表示当前像素不为空白):

if (raster.getPixel(x, y, (int[]) null)[3] != 0) 

我感到很惊讶,但这种方法效果非常快(裁剪1024x768图像需要70-100毫秒)。我也在5000x5000图像上测试了它,不幸的是这种方法在这种情况下非常慢(1000-1500毫秒)。

它将图像划分为每个y坐标的垂直线。然后它在这一行中查找不是空白像素。如果没有找到空白像素,则会转到下一行,但如果找到它则会查找minX和maxX。此外,如果minY尚未定义,则定义它并且bool“minYIsDefined”成立。但是如果定义了minY,它就定义了maxY。

编辑

正如在coments(thx FiReTiTi)中所建议的那样,使用'getSample()'方法我们可以更快。这是因为'getPixel()'方法使用'getSample()'方法使其数组为3-4次(取决于图像类型)。所以新的条件会像这样消失:

if (raster.getSample(x, y, 3) != 0) 

我的测试表明,裁剪1024x768图像所需的时间是10-30毫秒。在5000x5000的情况下,图像时间为100-300毫秒。

希望它会帮助某人:)