1. 程式人生 > >Java圖片讀取之BufferedImage得到畫素矩陣的兩種方式

Java圖片讀取之BufferedImage得到畫素矩陣的兩種方式

最近在嘗試著採用Java在影象處理領域實踐一下常用的機器學習演算法。首先涉及到的是如何將一副圖片讀取到一個畫素矩陣中(Java中就是一維或二維陣列中)。在實踐過程中,通過測試程式碼,我發現基於BufferedImage可以有兩種獲取畫素矩陣的方式,但需要注意畫素點的儲存順序問題。
具體表現在:本例中的圖片是一副彩色圖片(部落格頭像),大小為425*292,即寬度(Width)為425,高度(Height)為292。
放上測試程式碼(剛測試完就放上來了,不要糾結細節),後面再說明:

/**
 * Created by Song on 2016/12/29.
 * 用於讀取Image檔案
 */
public final class ImgHandler { public static void getData(String path){ try{ BufferedImage bimg = ImageIO.read(new File(path)); int [][] data = new int[bimg.getWidth()][bimg.getHeight()]; //方式一:通過getRGB()方式獲得畫素矩陣 //此方式為沿Height方向掃描 for
(int i=0;i<bimg.getWidth();i++){ for(int j=0;j<bimg.getHeight();j++){ data[i][j]=bimg.getRGB(i,j); //輸出一列資料比對 if(i==0) System.out.printf("%x\t",data[i][j]); } } Raster raster = bimg.getData(); System.out.println(""
); int [] temp = new int[raster.getWidth()*raster.getHeight()*raster.getNumBands()]; //方式二:通過getPixels()方式獲得畫素矩陣 //此方式為沿Width方向掃描 int [] pixels = raster.getPixels(0,0,raster.getWidth(),raster.getHeight(),temp); for (int i=0;i<pixels.length;) { //輸出一列資料比對 if((i%raster.getWidth()*raster.getNumBands())==0) System.out.printf("ff%x%x%x\t",pixels[i],pixels[i+1],pixels[i+2]); i+=3; } }catch (IOException e){ e.printStackTrace(); } } public static void main(String [] args){ getData("E:\\a.jpg"); } }

在方式一中,getRGB()方法,根據手冊,其返回的int型資料(32位)為ARGB格式,其中ARGB各佔8bit。getRGB的兩個引數x,y分別對應畫素點的橫縱座標,但需注意的是,以圖片左上角點為座標原點,x軸正方向是沿著width方向的,y軸正方向是沿著Height方向的。不信的同學,可以試著把二者調換,就會發現系統會報陣列溢位的異常。
在方式二中,畫素會通過getPixels()方法被儲存在一個一維陣列中。其中temp資料為讀取資料的緩衝區,其大小的確定一定要是其影象通道數(通過getNumBands()獲得)的整數倍,例如這裡的彩色圖片有RGB三個通道,所以通道數就為3。在最終得到的結果一維陣列中,一維陣列的大小為Width*Height*NumBands。此處,一個畫素點佔三個位置(R,G,B),與方式一得到的值作比對時,才發現,這裡的一維陣列中,畫素點的排列順序是按著Width橫向掃碼得到的。
鑑於操作的便捷來說,個人肯定偏向於方向一,首先它把RGB值整合到了一起,不像方式二中是分開的三個int數,二是二維陣列相較於一維陣列,肯定更加接近矩陣的概念,便於運算。