2017-02-26 155 views
-3

這個問題被鏈接到用於自動裁剪下面的方法:https://stackoverflow.com/a/12645803/7623700java.lang.IllegalArgumentException異常:寬度(-2147483647)和高度(-2147483647)不能<= 0

嘗試時出現以下異常在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(); 

    } 
} 

什麼可能導致錯誤?任何幫助深表感謝。

+0

我投票關閉這個問題作爲一個錯字。 OP,當你想檢查某個值是否在某個容差範圍內時,你應該檢查該值是否爲_lower_,而不是_higher_。 – Tom

回答

1

我已經運行了你的代碼,並在下面一行中得到錯誤。

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

當我在這行之前添加一個打印語句如下。

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

它印 - -2147483647 -2147483647。然後我看到,您已經初始化topYtopX,如下所示。其實沒有

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

的變量 - topXtopYbottomXbottomY沒有得到更新,因爲以下if條件從不計算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,那麼當您檢查距離是否在給定容差限制的範圍內時,您的函數應返回False

我寫了我的調試過程,以便您可以從下次調試您自己的代碼。

+0

嗨,我確實檢查過,觸發有問題的代碼之前,寬度和高度不是負值。如果在輸入引起問題的if顏色容差線之前打印寬度和高度,那麼它不是負數也不爲零 – lahronin

+0

我也嘗試使用具有相同問題的不同圖像文件,問題是我正在閱讀圖像文件的方式? – lahronin

+0

你能提一下你在哪一行出錯嗎? –

0

的算法的說明:

所述算法採用的左上頂點爲白色,並發現從它是至少公差%不同的所有像素(遠>):這將導致在該區域即是不同於白色,因爲你想挖出應該是你有效區域的白色。

唯一的問題是,寬容應該是一個%,自

percentAway = distance/510.0d 

不能超過一個(這是顏色的距離的歸一化量)。

因此,如果您定義的公差爲十進制

例如

BufferedImage resultImage1 = getCropImage(image, 0.2); 

應該工作。

(與狀態保持在percentAway>公差)

+0

謝謝你的解釋,我是圖像處理新手,你的評論當然有幫助。裁剪現在已經發生,但是我不太明白爲什麼輸出圖像會失真,因爲顏色容差部分只是爲了幫助確定新的x和y座標,我不知道代碼如何導致顏色改變? – lahronin

+0

只是爲了提供一些背景知識,我試圖從文檔的照片中剪出文檔,可能這不是預期的目的。不過,在將原始座標應用於原始座標之前,您是否認爲製作副本來確定座標會解決此問題?或者先將此副本轉換爲黑白/灰度,可以提高準確性? – lahronin