熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Javascript >> 正文

在Java應用程序讀取8位和24位Windows位圖

2013-11-23 17:58:35  來源: Javascript 

  Java 的當前發行版並不正式支持在 Java 應用程序中讀取 Microsoft Windows 位圖文件但別擔心我們有辦法解決這個問題!這篇技巧將說明如何完成這一任務 我們首先說明讀取 Microsoft Windows 文件格式的基本步驟
  
  Windows DIB(設備獨立的位圖)文件格式比較簡單與純位圖格式不同DIB 格式保留著用於在內存中存儲圖像的明確信息問題是圖像格式的變體如此之多( 位和 以及其他格式)本篇 Java 技巧中提供的解決方案只處理 位和 位兩種格式這兩種格式代表了最常見的變體
  
  不管是哪種 Windows DIB 子類型這種文件格式總是由 位文件頭和 位信息頭組成這兩個標頭精確包含有關文件的存儲內容和存儲次序的信息有關標頭中每一項的確切含義請參考 Microsoft Software Development Kit (SDK)文件其余部分的內容隨信息頭中數據的不同而不同
  
  我們看一下本文要處理的兩種子類型 位格式很簡單RGB(紅藍)顏色值( 個字節並按 BGR 排序)緊接在信息頭之後但是每個掃描行都被補足到 個字節按照說明文檔(請參閱 Microsoft SDK)的說法這種補足是為了優化 Windows 位圖繪圖 API同時底部的掃描行是文件中的第一項內容 因此相對普通的圖形坐標系統(其矢量方向的正向分別為向下和向右)而言必須從後向前讀取圖像
  
   位子類型由於在信息頭和象素數據之間插入調色板信息而復雜化因此每個象素條目只是進入 位 RGB 顏色的調色板數組的一個 位索引在象素信息中每個掃描行同樣被補足到 個字節
  
  請注意本文提供的位圖圖像加載方法不支持對壓縮位圖圖像進行解壓縮實際上這個例程甚至不尋求這種可能性!如果遇到壓縮 Windows DIB 文件該例程肯定會產生異常Windows SDK 中有對壓縮 Windows DIB 格式的說明
  
  至於性能在運行 Microsoft Windows DXMHz 系統上該例程讀取 x 的文件(大約 千字節)所需的時間不超過 使用 BufferedInputStream 而不是 FileInputStream 可明顯提高性能
  
  以下例程讀取兩種文件格式中的任一種並生成一個 Image 圖像以下代碼並未包含全面的錯誤和異常處理以避免使該例程更加復雜您總可用 Windows Paint 程序對不支持的 Windows DIB 子類型進行轉換
  
  /**
  loadbitmap() 方法由 Windows C 代碼轉換而來
  只能讀取未壓縮的 位和 位圖像已在
  Windows 上用 Microsoft Paint 保存的圖像
  對它進行了測試如果圖像不是 位或 位圖像
  該程序拒絕進行任何嘗試我猜測如果先用
  然後用 對字節執行掩碼操作則也可將
  圖像包括在內我實際上對這些圖像不感興趣
  如果嘗試讀取壓縮圖像該例程可能失敗並產生
  一個 IOException 異常如果變量 ncompression
  不為 則表示已經過壓縮
  
  參數
  sdir 和 sfile 是 FileDialog 的
  getDirectory() 和 getFile() 方法的結果
  
  返回值
  Image 對象切記要檢查 (Image)null !!!!
  
  */
  public Image loadbitmap (String sdir String sfile)
  {
  Image image;
  Systemoutprintln(loading:+sdir+sfile);
  try
  {
  FileInputStream fs=new FileInputStream(sdir+sfile);
  int bflen=; // 字節 BITMAPFILEHEADER
  byte bf[]=new byte[bflen];
  fsread(bfbflen);
  int bilen=; // 字節 BITMAPINFOHEADER
  byte bi[]=new byte[bilen];
  fsread(bibilen);
  
  // 解釋數據
  int nsize = (((int)bf[]&xff)< < )
  | (((int)bf[]&xff)< < )
  | (((int)bf[]&xff)< < )
  | (int)bf[]&xff;
  Systemoutprintln(File type is :+(char)bf[]+(char)bf[]);
  Systemoutprintln(Size of file is :+nsize);
  
  int nbisize = (((int)bi[]&xff)< < )
  | (((int)bi[]&xff)< < )
  | (((int)bi[]&xff)< < )
  | (int)bi[]&xff;
  Systemoutprintln(Size of bitmapinfoheader is :+nbisize);
  
  int nwidth = (((int)bi[]&xff)< < )
  | (((int)bi[]&xff)< < )
  | (((int)bi[]&xff)< < )
  | (int)bi[]&xff;
  Systemoutprintln(Width is :+nwidth);
  
  int nheight = (((int)bi[]&xff)< < )
  | (((int)bi[]&xff)< < )
  | (((int)bi[]&xff)< < )
  | (int)bi[]&xff;
  Systemoutprintln(Height is :+nheight);
  
  int nplanes = (((int)bi[]&xff)< < ) | (int)bi[]&xff;
  Systemoutprintln(Planes is :+nplanes);
  
  int nbitcount = (((int)bi[]&xff)< < ) | (int)bi[]&xff;
  Systemoutprintln(BitCount is :+nbitcount);
  
  // 查找表明壓縮的非零值
  int ncompression = (((int)bi[])< < )
  | (((int)bi[])< < )
  | (((int)bi[])< < )
  | (int)bi[];
  Systemoutprintln(Compression is :+ncompression);
  
  int nsizeimage = (((int)bi[]&xff)< < )
  | (((int)bi[]&xff)< < )
  | (((int)bi[]&xff)< < )
  | (int)bi[]&xff;
  Systemoutprintln(SizeImage is :+nsizeimage);
  
  int nxpm = (((int)bi[]&xff)< < )
  | (((int)bi[]&xff)< < )
  | (((int)bi[]&xff)< < )
  | (int)bi[]&xff;
  Systemoutprintln(XPixels per meter is :+nxpm);
  
  int nypm = (((int)bi[]&xff)< < )
  | (((int)bi[]&xff)< < )
  | (((int)bi[]&xff)< < )
  | (int)bi[]&xff;
  Systemoutprintln(YPixels per meter is :+nypm);
  
  int nclrused = (((int)bi[]&xff)< < )
  | (((int)bi[]&xff)< < )
  | (((int)bi[]&xff)< < )
  | (int)bi[]&xff;
  Systemoutprintln(Colors used are :+nclrused);
  
  int nclrimp = (((int)bi[]&xff)< < )
  | (((int)bi[]&xff)< < )
  | (((int)bi[]&xff)< < )
  | (int)bi[]&xff;
  Systemoutprintln(Colors important are :+nclrimp);
  
  if (nbitcount==)
  {
  // 位格式不包含調色板數據但掃描行被補足到
  // 個字節
  int npad = (nsizeimage / nheight) nwidth * ;
  int ndata[] = new int [nheight * nwidth];
  byte brgb[] = new byte [( nwidth + npad) * * nheight];
  fsread (brgb (nwidth + npad) * * nheight);
  int nindex = ;
  for (int j = ; j < nheight; j++)
  {
  for (int i = ; i < nwidth; i++)
  {
  ndata [nwidth * (nheight j ) + i] =
  (&xff)< <
  | (((int)brgb[nindex+]&xff)< < )
  | (((int)brgb[nindex+]&xff)< < )
  | (int)brgb[nindex]&xff;
  // Systemoutprintln(Encoded Color at (
  +i++j+)is:+nrgb+ (RGB)= (
  +((int)(brgb[]) & xff)+
  +((int)brgb[]&xff)+
  +((int)brgb[]&xff)+));
  nindex += ;
  }
  nindex += npad;
  }
  
  image = createImage
  ( new MemoryImageSource (nwidth nheight
  ndata nwidth));
  }
  else if (nbitcount == )
  {
  // 必須確定顏色數如果 clrsused 參數大於
  // 則顏色數由它決定如果它等於 則根據
  // bitsperpixel 計算顏色數
  int nNumColors = ;
  if (nclrused > )
  {
  nNumColors = nclrused;
  }
  else
  {
  nNumColors = (&xff)< < nbitcount;
  }
  Systemoutprintln(The number of Colors is+nNumColors);
  
  // 某些位圖不計算 sizeimage 域請找出
  // 這些情況並對它們進行修正
  if (nsizeimage == )
  {
  nsizeimage = ((((nwidth*nbitcount)+) & ~ ) >> );
  nsizeimage *= nheight;
  Systemoutprintln(nsizeimage (backup) is+nsizeimage);
  }
  
  // 讀取調色板顏色
  int npalette[] = new int [nNumColors];
  byte bpalette[] = new byte [nNumColors*];
  fsread (bpalette nNumColors*);
  int nindex = ;
  for (int n = ; n < nNumColors; n++)
  {
  npalette[n] = (&xff)< <
  | (((int)bpalette[nindex+]&xff)< < )
  | (((int)bpalette[nindex+]&xff)< < )
  | (int)bpa
From:http://tw.wingwit.com/Article/program/Java/Javascript/201311/25466.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.