如何在 Java 中自动裁剪图像白色边框?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10678015/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to auto crop an image white border in Java?
提问by rreyes1979
What's the easiest way to auto crop the white border out of an image in java? Thanks in advance...
在java中从图像中自动裁剪白色边框的最简单方法是什么?提前致谢...
采纳答案by fahim ayat
If you want the white parts to be invisible, best way is to use image filters and make white pixels transparent, it is discussed hereby @PhiLho with some good samples, if you want to resize your image so it's borders won't have white colors, you can do it with four simple loops, this little method that I've write for you does the trick, note that it just crop upper part of image, you can write the rest,
如果您希望白色部分不可见,最好的方法是使用图像过滤器并使白色像素透明,@PhiLho在此处讨论了一些好的示例,如果您想调整图像大小,使其边框不会有白色颜色,你可以用四个简单的循环来完成,我为你写的这个小方法可以解决问题,注意它只是裁剪图像的上部,你可以写其余的,
private Image getCroppedImage(String address) throws IOException{
BufferedImage source = ImageIO.read(new File(address)) ;
boolean flag = false ;
int upperBorder = -1 ;
do{
upperBorder ++ ;
for (int c1 =0 ; c1 < source.getWidth() ; c1++){
if(source.getRGB(c1, upperBorder) != Color.white.getRGB() ){
flag = true;
break ;
}
}
if (upperBorder >= source.getHeight())
flag = true ;
}while(!flag) ;
BufferedImage destination = new BufferedImage(source.getWidth(), source.getHeight() - upperBorder, BufferedImage.TYPE_INT_ARGB) ;
destination.getGraphics().drawImage(source, 0, upperBorder*-1, null) ;
return destination ;
}
回答by Todd
Here's a way to crop all 4 sides, using the color from the very top-left pixel as the baseline, and allow for a tolerance of color variation so that noise in the image won't make the crop useless
这是一种裁剪所有 4 个边的方法,使用左上角像素的颜色作为基线,并允许颜色变化容差,以便图像中的噪声不会使裁剪无用
public BufferedImage getCroppedImage(BufferedImage source, double tolerance) {
// Get our top-left pixel color as our "baseline" for cropping
int baseColor = source.getRGB(0, 0);
int width = source.getWidth();
int height = source.getHeight();
int topY = Integer.MAX_VALUE, topX = Integer.MAX_VALUE;
int bottomY = -1, bottomX = -1;
for(int y=0; y<height; y++) {
for(int x=0; x<width; x++) {
if (colorWithinTolerance(baseColor, source.getRGB(x, y), tolerance)) {
if (x < topX) topX = x;
if (y < topY) topY = y;
if (x > bottomX) bottomX = x;
if (y > bottomY) bottomY = y;
}
}
}
BufferedImage destination = new BufferedImage( (bottomX-topX+1),
(bottomY-topY+1), BufferedImage.TYPE_INT_ARGB);
destination.getGraphics().drawImage(source, 0, 0,
destination.getWidth(), destination.getHeight(),
topX, topY, bottomX, bottomY, null);
return destination;
}
private boolean colorWithinTolerance(int a, int b, double tolerance) {
int aAlpha = (int)((a & 0xFF000000) >>> 24); // Alpha level
int aRed = (int)((a & 0x00FF0000) >>> 16); // Red level
int aGreen = (int)((a & 0x0000FF00) >>> 8); // Green level
int aBlue = (int)(a & 0x000000FF); // Blue level
int bAlpha = (int)((b & 0xFF000000) >>> 24); // Alpha level
int bRed = (int)((b & 0x00FF0000) >>> 16); // Red level
int bGreen = (int)((b & 0x0000FF00) >>> 8); // Green level
int bBlue = (int)(b & 0x000000FF); // Blue level
double distance = Math.sqrt((aAlpha-bAlpha)*(aAlpha-bAlpha) +
(aRed-bRed)*(aRed-bRed) +
(aGreen-bGreen)*(aGreen-bGreen) +
(aBlue-bBlue)*(aBlue-bBlue));
// 510.0 is the maximum distance between two colors
// (0,0,0,0 -> 255,255,255,255)
double percentAway = distance / 510.0d;
return (percentAway > tolerance);
}
回答by wutzebaer
And here just another Example
这里只是另一个例子
private static BufferedImage autoCrop(BufferedImage sourceImage) {
int left = 0;
int right = 0;
int top = 0;
int bottom = 0;
boolean firstFind = true;
for (int x = 0; x < sourceImage.getWidth(); x++) {
for (int y = 0; y < sourceImage.getWidth(); y++) {
// pixel is not empty
if (sourceImage.getRGB(x, y) != 0) {
// we walk from left to right, thus x can be applied as left on first finding
if (firstFind) {
left = x;
}
// update right on each finding, because x can grow only
right = x;
// on first find apply y as top
if (firstFind) {
top = y;
} else {
// on each further find apply y to top only if a lower has been found
top = Math.min(top, y);
}
// on first find apply y as bottom
if (bottom == 0) {
bottom = y;
} else {
// on each further find apply y to bottom only if a higher has been found
bottom = Math.max(bottom, y);
}
firstFind = false;
}
}
}
return sourceImage.getSubimage(left, top, right - left, bottom - top);
}
回答by Diego Iba?ez
img is original image source BufferedImage subImg = img.getSubimage(0, 0, img.getWidth() - 1, img.getHeight() - 1);
img 为原始图片源 BufferedImage subImg = img.getSubimage(0, 0, img.getWidth() - 1, img.getHeight() - 1);