我有一个关于切割图像中的空白区域(或者只是裁剪它)的问题。我想要一个像这样的方法:
public BufferedImage crop(BufferedImage input) {
return output;
}
它应该这样做:
我知道我可以通过所有像素来获得新的界限,但是对于图像1024x768的问题,我将不得不通过1024 * 768 = 786432(第2次因为我必须通过第一次获得高度界限和第二次获得宽度边界)像素。这不是一个好方法。有什么想法如何快速做到这一点? (如果可能的话,我不想使用neihter任何其他线程或任何其他框架)
谢谢!
答案 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毫秒。
希望它会帮助某人:)