今天使用ImageIO實現裁切圖片,遇到了一個錯誤:
Not a JPEG file: starts with 0xff 0xd9
因為要獲取裁剪原點和裁切尺寸,所以我想獲取圖片寬高,用較小的一個作為裁切尺寸,進而得到一個正方形的圖,所以就有了如下代碼:
File imageFile = new File(imageFileFullPath); FileInputStream imageFileInputStream = new FileInputStream(imageFile); // 獲取原始圖片,用於讀取寬和高 BufferedImage bufferedImage = ImageIO.read(imageFileInputStream); int imageWidth = bufferedImage.getWidth(); int imageHeight = bufferedImage.getHeight(); if(imageWidth == imageHeight) { //直接返回,不進行裁切 } // 取較小的數值為裁剪尺寸 int clipSize = imageWidth > imageHeight ? imageHeight : imageWidth;
然而在裁切並輸出結果時,又用到了這樣的代碼:
Iterator<ImageReader> readerIt = ImageIO.getImageReadersByFormatName("jpg"); ImageReader reader = readerIt.next(); // 獲取圖片流 ImageInputStream imageInputStream = ImageIO.createImageInputStream(imageFileInputStream); reader.setInput(imageInputStream, true); Rectangle rectangle = new Rectangle(0, 0, clipSize, clipSize); param.setSourceRegion(rectangle); //讀取選取的區域 BufferedImage clipedImage = reader.read(0, param);
沒過多久我就找到了解決辦法,以至於我認為導致錯誤的原因就是定義了兩個BufferedImage。這個解決方法是:去掉獲取寬高的BufferedImage對象的定義,改用reader獲取原始圖片尺寸:
int imageWidth = reader.getWidth(0); int imageHeight = reader.getHeight(0);
這樣就能夠正常運行了。以目前掌握的知識還不能理解文章開頭提到的錯誤是如何出現的,因為去掉一個BufferedImage的定義就能夠正常裁切,所以我想是不是不能定義兩個BufferedImage對象的原因,直到我嘗試了以下方法:
BufferedImage clipedImage = bufferedImage.getSubimage(0, 0, clipSize, clipSize);
取代上面的那一大段代碼,同樣用到了兩個BufferedImage對象,這種形式就能夠很好地去執行。
之後我又繼續思考可能導致這個錯誤的原因,發現了一個可疑之處:
// 獲取原始圖片,用於讀取寬和高 BufferedImage bufferedImage = ImageIO.read(imageFileInputStream);
這個imageFileInputStream對象是已經讀取到的圖片對象,而ImageIO的read方法還有一個參數就是File,所以我替換了一下:
BufferedImage bufferedImage = ImageIO.read(imageFile);
竟然也裁切成功了!不過還是沒有從根本上理解錯誤出現的原因,暫且記下,以後慢慢發現。
圖片裁切的代碼參考了:
http://www.oschina.net/code/snippet_857368_14826
再貼一個BufferedImage相關的好文:
http://blog.163.com/yuhua_kui/blog/static/9679964420139118203818/