java.lang.IllegalArgumentException:宽度(-2147483647)和高度(-2147483647)不能是< = 0

时间:2017-02-26 03:39:43

标签: java image-processing

此问题与以下自动裁剪方法相关联:https://stackoverflow.com/a/12645803/7623700

尝试在Eclipse中运行以下Java代码时出现以下异常:

     Exception in thread "main" java.lang.IllegalArgumentException: Width (-2147483647) and height (-2147483647) cannot be <= 0
at java.awt.image.DirectColorModel.createCompatibleWritableRaster(Unknown Source)
at java.awt.image.BufferedImage.<init>(Unknown Source)
at getCroppedImage.getCropImage(getCroppedImage.java:44)
at getCroppedImage.<init>(getCroppedImage.java:16)
at getCroppedImage.main(getCroppedImage.java:79)

代码对其他人有用,所以我想问题可能在于我尝试使用它的方式,这是我的代码:

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class getCroppedImage {
    getCroppedImage() throws IOException{
    String imagePath = "C:\\Users\\lah\\workspace\\Testing\\images";
    BufferedImage image = ImageIO.read(new   File("C:\\Users\\lah\\workspace\\Testing\\images\\image1.jpg"));

    BufferedImage resultImage1 = getCropImage(image,2.0);
    File outFile1 = new File(imagePath, "croppedimage.png");
    ImageIO.write(resultImage1, "PNG", outFile1);
    }

//start of original method in the above link
public BufferedImage getCropImage(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();
       //System.out.println(width+" "+height);
       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);
    }
    // end of original method in the above link
    public static void main(String[] args) throws IOException {
        getCroppedImage ci = new getCroppedImage();

    }
}

可能导致错误的原因是什么?非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

我已运行您的代码并在以下行中收到错误。

BufferedImage destination = new BufferedImage((bottomX - topX + 1),
                (bottomY - topY + 1), BufferedImage.TYPE_INT_ARGB);

当我在此行之前添加print语句时,如下所示。

System.out.println((bottomX - topX + 1) + " " + (bottomY - topY + 1));

打印 - -2147483647 -2147483647。然后我看到,您已初始化topYtopX,如下所示。

int topY = Integer.MAX_VALUE, topX = Integer.MAX_VALUE;

实际上,没有任何变量 - topXtopYbottomXbottomY没有得到更新,因为以下if条件永远不会评估为{{ 1}}。

True

当我检查您的if (colorWithinTolerance(baseColor, source.getRGB(x, y), tolerance)) { // your code goes here } 功能时,我发现了以下问题。

colorWithinTolerance()

这个条件应该是 - private boolean colorWithinTolerance(int a, int b, double tolerance) { // your code return (percentAway > tolerance); } 。因为如果percentAway < tolerance大于percentAway,那么当您检查距离是否在给定的容差限制范围内时,您的函数应返回tolerance

我编写了调试过程,以便您可以在下次调试自己的代码。

答案 1 :(得分:0)

算法说明:

该算法将左上角点视为白色,并找到与其至少公差%(远离&gt;)的所有像素:这将导致区域与白色不同并且因为您想要裁剪出白色应该是你的有效区域。

唯一的问题是容差应该是百分之百

percentAway = distance / 510.0d

不能超过一个(它是颜色距离的标准化数量)。

因此,如果将公差定义为十进制

例如

BufferedImage resultImage1 = getCropImage(image, 0.2);

应该有用。

(条件保持在百分之百>公差)