如何在 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 02:04:01  来源:igfitidea点击:

How to auto crop an image white border in Java?

javaimage-processing

提问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);