亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? 用 java 保存位圖文件(轉).txt

?? 給一個初學者的建議和指導之路
?? TXT
字號:
作者:zergman
email: zergman@chinaasp.com
日期:2001-6-15 13:27:17
[b]用 Java 保存位圖文件
教程 -- 其中包括將圖像對象寫入位圖文件的全部代碼[/b]

[b]作者 Jean-Pierre Dubé[/b]
[BLOCKQUOTE][I][b]摘要[/b]
雖然 Java 提供了幾種打開圖像的機制,但保存圖像并不是它的強項。這篇技巧將講述如何將圖像保存在 24 位位圖文件中。另外,Jean-Pierre 還提供了將圖像文件寫入位圖文件所需的全部代碼。 [i][/i][/I][/BLOCKQUOTE]這篇技巧是 [url href=http://www.cn.ibm.com/developerWorks/java/jw-tips/tip043/index.shtml]Java 技巧 43[/url] 的補充,那篇技巧說明了在 Java 應用程序中加載位圖文件的過程。本月我再提供一篇教程,說明如何將圖像保存在 24 位位圖文件中,其中還包含將圖像對象寫入位圖文件的代碼片斷。 
如果您在 Microsoft Windows 環境中工作,那么創建位圖文件的功能將為您提供許多方便。例如,在我的上一個項目中,我必須將 Java 與 Microsoft Access 對接。Java 程序允許用戶在屏幕上繪圖。這幅圖隨后被打印到 Microsoft Access 報表中。由于 Java 不支持 OLE,我的唯一選擇就是創建該圖的一個位圖文件,并通知 Microsoft Access 報表在何處能找到這個位圖文件。如果您寫過向剪貼板發送圖像的應用程序,則這個技巧可能對您有用 -- 尤其是當您將這個信息傳遞給另一個應用程序時。 
[b]位圖文件的格式[/b]
位圖文件格式支持 4 位 RLE(行程長度編碼)以及 8 位和 24 位編碼。因為我們只處理 24 位格式,所以下面我們查看一下該文件的結構。 
位圖文件分為三個部分。我已將它們列在下面。 
[b]第 1 部分:位圖文件的標頭[/b]
標頭包含位圖文件的類型大小信息和版面信息。結構如下(摘自 C 語言結構定義): 
typedef struct tagBITMAPFILEHEADER {
   UINT bfType;
   DWORD bfSize;
   UINT bfReserved1;
   UINT bfReserved2;
   DWORD bfOffBits;
}BITMAPFILEHEADER;

下面是對這個清單中的代碼元素的說明: 
[UL][LI]bfType:指定文件類型,其值始終為 BM。 
[LI]bfSize:指定整個文件的大?。ㄒ宰止潪閱挝唬?。 
[LI]bfReserved1:保留 -- 必須為 0。 
[LI]bfReserved2:保留 -- 必須為 0。 
[LI]bfOffBits:指定從 BitmapFileHeader 到圖像首部的字節偏移量。 [/LI][/UL]
現在您已經明白位圖標頭的用途就是標識位圖文件。讀取位圖文件的每個程序都使用位圖標頭來進行文件驗證。 
[b]第 2 部分:位圖信息標頭[/b]
隨后的標頭稱為[i]信息標頭[/i],其中包含圖像本身的屬性。 
下面說明如何指定 Windows 3.0(或更高版本)設備獨立位圖 (DIB) 的大小和顏色格式: 
typedef struct tagBITMAPINFOHEADER {
    DWORD biSize;
    LONG biWidth;
    LONG biHeight;
    WORD biPlanes;
    WORD biBitCount;
    DWORD biCompression;
    DWORD biSizeImage;
    LONG biXPelsPerMeter;
    LONG biYPelsPerMeter;
    DWORD biClrUsed;
    DWORD biClrImportant;
} BITMAPINFOHEADER;

以上代碼清單的每個元素說明如下: 
[UL][LI]biSize:指定 BITMAPINFOHEADER 結構所需的字節數。 
[LI]biWidth:指定位圖的寬度(以象素為單位)。 
[LI]biHeight:指定位圖的高度(以象素為單位)。 
[LI]biPlanes:指定目標設備的位面數。這個成員變量的值必須為 1。 
[LI]biBitCount:指定每個象素的位數。其值必須為 1、4、8 或 24。 
[LI]biCompression:指定壓縮位圖的壓縮類型。在 24 位格式中,該變量被設置為 0。 
[LI]biSizeImage:指定圖像的大?。ㄒ宰止潪閱挝唬?。如果位圖的格式是 BI_RGB,則將此成員變量設置為 0 是有效的。 
[LI]biXPelsPerMeter:為位圖指定目標設備的水平分辨率(以“象素/米”為單位)。應用程序可用該值從最符合當前設備特征的資源群組中選擇一個位圖。 
[LI]biYPelsPerMeter:為位圖指定目標設備的垂直分辨率(以“象素/米”為單位)。 
[LI]biClrUsed:指定位圖實際所用的顏色表中的顏色索引數。如果 biBitCount 設為 24,則 biClrUsed 指定用來優化 Windows 調色板性能的參考顏色表。 
[LI]biClrImportant:指定對位圖的顯示有重要影響的顏色索引數。如果此值為 0,則所有顏色都很重要。 [/LI][/UL]
現在已定義了創建圖像所需的全部信息。 
[b]第 3 部分:圖像[/b]
在 24 位格式中,圖像中的每個象素都由存儲為 BRG 的三字節 RGB 序列表示。每個掃描行都被補足到 4 位。為了使這個過程稍復雜一點,圖像是自底而上存儲的,即第一個掃描行是圖像中的最后一個掃描行。下圖顯示了標頭 (BITMAPHEADER) 和 (BITMAPINFOHEADER) 以及部分圖像。各個部分由垂線分隔: 
0000000000 4D42 B536 0002 0000 0000 0036 0000 | 0028
0000000020 0000 0107 0000 00E0 0000 0001 0018 0000
0000000040 0000 B500 0002 0EC4 0000 0EC4 0000 0000
0000000060 0000 0000 0000 | FFFF FFFF FFFF FFFF FFFF
0000000100 FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
*

[b]現在,我們開始檢視代碼[/b]
現在我們已經知道了 24 位位圖文件的結構,下面就是您期待已久的內容:用來將圖像對象寫入位圖文件的代碼。 
import java.awt.*;
import java.io.*;
import java.awt.image.*;

public class BMPFile extends Component {

  //--- 私有常量
  private final static int BITMAPFILEHEADER_SIZE = 14;
  private final static int BITMAPINFOHEADER_SIZE = 40;

  //--- 私有變量聲明

  //--- 位圖文件標頭
  private byte bitmapFileHeader [] = new byte [14];
  private byte bfType [] = {'B', 'M'};
  private int bfSize = 0;
  private int bfReserved1 = 0;
  private int bfReserved2 = 0;
  private int bfOffBits = BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE;

  //--- 位圖信息標頭
  private byte bitmapInfoHeader [] = new byte [40];
  private int biSize = BITMAPINFOHEADER_SIZE;
  private int biWidth = 0;
  private int biHeight = 0;
  private int biPlanes = 1;
  private int biBitCount = 24;
  private int biCompression = 0;
  private int biSizeImage = 0x030000;
  private int biXPelsPerMeter = 0x0;
  private int biYPelsPerMeter = 0x0;
  private int biClrUsed = 0;
  private int biClrImportant = 0;

  //--- 位圖原始數據
  private int bitmap [];

  //--- 文件部分
  private FileOutputStream fo;

  //--- 缺省構造函數
  public BMPFile() {

  }


  public void saveBitmap (String parFilename, Image parImage, int
parWidth, int parHeight) {

     try {
        fo = new FileOutputStream (parFilename);
        save (parImage, parWidth, parHeight);
        fo.close (); 
     }
     catch (Exception saveEx) {
        saveEx.printStackTrace ();
     }

  }


  /*
   * saveMethod 是該進程的主方法。該方法
   * 將調用 convertImage 方法以將內存圖像轉換為
   * 字節數組;writeBitmapFileHeader 方法創建并寫入
   * 位圖文件標頭;writeBitmapInfoHeader 創建 
   * 信息標頭;writeBitmap 寫入圖像。
   *
   */
  private void save (Image parImage, int parWidth, int parHeight) {

     try {
        convertImage (parImage, parWidth, parHeight);
        writeBitmapFileHeader ();
        writeBitmapInfoHeader ();
        writeBitmap ();
     }
     catch (Exception saveEx) {
        saveEx.printStackTrace ();
     }
  }


  /*
   * convertImage 將內存圖像轉換為位圖格式 (BRG)。
   * 它還計算位圖信息標頭所用的某些信息。
   *
   */
  private boolean convertImage (Image parImage, int parWidth, int parHeight) {

     int pad;
     bitmap = new int [parWidth * parHeight];

     PixelGrabber pg = new PixelGrabber (parImage, 0, 0, parWidth, parHeight,
                                         bitmap, 0, parWidth);

     try {
        pg.grabPixels ();
     }
     catch (InterruptedException e) {
        e.printStackTrace ();
        return (false);
     }

     pad = (4 - ((parWidth * 3) % 4)) * parHeight;
     biSizeImage = ((parWidth * parHeight) * 3) + pad;
     bfSize = biSizeImage + BITMAPFILEHEADER_SIZE +
BITMAPINFOHEADER_SIZE;
     biWidth = parWidth;
     biHeight = parHeight;

     return (true);
  }

  /*
   * writeBitmap 將象素捕獲器返回的圖像轉換為
   * 所需的格式。請記?。簰呙栊性谖粓D文件中是
   * 反向存儲的!
   *
   * 每個掃描行必須補足為 4 個字節。
   */
  private void writeBitmap () {

      int size;
      int value;
      int j;
      int i;
      int rowCount;
      int rowIndex;
      int lastRowIndex;
      int pad;
      int padCount;
      byte rgb [] = new byte [3];


      size = (biWidth * biHeight) - 1;
      pad = 4 - ((biWidth * 3) % 4);
      if (pad == 4) // <==== 錯誤修正
         pad = 0; // <==== 錯誤修正
      rowCount = 1;
      padCount = 0;
      rowIndex = size - biWidth;
      lastRowIndex = rowIndex;

      try {
         for (j = 0; j < size; j++) {
            value = bitmap [rowIndex];
            rgb [0] = (byte) (value & 0xFF);
            rgb [1] = (byte) ((value >> 8) & 0xFF);
            rgb [2] = (byte) ((value >> 16) & 0xFF);
            fo.write (rgb);
            if (rowCount == biWidth) {
               padCount += pad;
               for (i = 1; i <= pad; i++) {
                  fo.write (0x00);
               }
               rowCount = 1;
               rowIndex = lastRowIndex - biWidth;
               lastRowIndex = rowIndex;
            }
            else
               rowCount++;
            rowIndex++;
         }

         //--- 更新文件大小
         bfSize += padCount - pad;
         biSizeImage += padCount - pad;
      }
      catch (Exception wb) {
         wb.printStackTrace ();
      }

   } 

  /*
   * writeBitmapFileHeader 將位圖文件標頭寫入文件中。
   *
   */
  private void writeBitmapFileHeader () {

     try {
        fo.write (bfType);
        fo.write (intToDWord (bfSize));
        fo.write (intToWord (bfReserved1));
        fo.write (intToWord (bfReserved2));
        fo.write (intToDWord (bfOffBits));

     }
     catch (Exception wbfh) {
        wbfh.printStackTrace ();
     }

  }

  /*
   *
   * writeBitmapInfoHeader 將位圖信息標頭
   * 寫入文件中。
   *
   */

  private void writeBitmapInfoHeader () {

     try {
        fo.write (intToDWord (biSize));
        fo.write (intToDWord (biWidth));
        fo.write (intToDWord (biHeight));
        fo.write (intToWord (biPlanes));
        fo.write (intToWord (biBitCount));
        fo.write (intToDWord (biCompression));
        fo.write (intToDWord (biSizeImage));
        fo.write (intToDWord (biXPelsPerMeter));
        fo.write (intToDWord (biYPelsPerMeter));
        fo.write (intToDWord (biClrUsed));
        fo.write (intToDWord (biClrImportant));
     }
     catch (Exception wbih) {
        wbih.printStackTrace ();
     }

  }


  /*
   *
   * intToWord 將整數轉換為單字,返回值
   * 存儲在一個雙字節數組中。
   *
   */
  private byte [] intToWord (int parValue) {

     byte retValue [] = new byte [2];

     retValue [0] = (byte) (parValue & 0x00FF);
     retValue [1] = (byte) ((parValue >> 8) & 0x00FF);

     return (retValue);

  }

  /*
   *
   * intToDWord 將整數轉換為雙字,返回值
   * 存儲在一個 4 字節數組中。
   *
   */
  private byte [] intToDWord (int parValue) {

     byte retValue [] = new byte [4];

     retValue [0] = (byte) (parValue & 0x00FF);
     retValue [1] = (byte) ((parValue >> 8) & 0x000000FF);
     retValue [2] = (byte) ((parValue >> 16) & 0x000000FF);
     retValue [3] = (byte) ((parValue >> 24) & 0x000000FF);

     return (retValue);

  }

}

[b]小結[/b]
這就是所要做的全部工作。我確信您將會發現這個類很有用,因為到 JDK 1.1.6 為止,Java 不支持用任何常用的格式保存圖像。JDK 1.2 將支持創建 JPEG 圖像,但不支持創建位圖。所以這個類仍將填補 JDK1.2 中的空白。 
如果您使用這個類并發現了改進它的方法,請通知我!下面的個人簡歷中有我的電子郵件地址。 
[TABLE][TR][TD][b]作者簡介[/b]
jeanpierre.dube Jean-Pierre Dubé 是一名自由 Java 咨詢者。他于 1988 年注冊創辦了 Infocom公司。從那時起,Infocom 已承接并開發了幾套應用程序,涉及的領域包括制造業、文檔管理和大規模輸電線管理。他有豐富的 C 語言、Visual Basic 和 Java(最近)編程經驗,他的公司現在主要使用 Java 語言。 Infocom 最近的一個項目是一種圖形 API,其測試版很快就會面市。 [/TD][/TR][/TABLE]

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产激情精品久久久第一区二区| 国产三区在线成人av| 国产91精品精华液一区二区三区| 亚洲va欧美va天堂v国产综合| 亚洲一区二区四区蜜桃| 亚洲精品videosex极品| 一区二区三区国产精品| 亚洲精品免费在线观看| 亚洲一区二区三区四区在线| 一区二区三区国产豹纹内裤在线| 一区二区三区中文字幕| 一区二区三区视频在线看| 亚洲一区二区三区爽爽爽爽爽 | 成人黄色片在线观看| 高清在线不卡av| 99精品国产99久久久久久白柏| 91视视频在线观看入口直接观看www | 欧美大片在线观看一区| 精品成人a区在线观看| 国产亚洲欧美日韩在线一区| 国产日韩欧美激情| 亚洲色图在线看| 亚洲美女精品一区| 日韩精品每日更新| 国产伦精品一区二区三区免费迷 | 日韩三级.com| 久久久久久久久久久久久女国产乱 | 成人免费黄色在线| 欧美中文字幕一二三区视频| 欧美一区欧美二区| 中文字幕免费不卡| 日韩精品色哟哟| av一二三不卡影片| 精品视频在线视频| 国产日韩欧美高清在线| 婷婷一区二区三区| 菠萝蜜视频在线观看一区| 欧美日韩二区三区| 欧美国产97人人爽人人喊| 午夜久久久久久久久久一区二区| 激情另类小说区图片区视频区| av不卡在线观看| 日韩精品中文字幕一区| 亚洲人精品午夜| 国产在线精品免费av| 欧美在线观看视频一区二区 | 欧美美女视频在线观看| 久久久99精品免费观看不卡| 亚洲国产一区二区三区| 成人av电影在线观看| 精品国产网站在线观看| 亚洲mv在线观看| 99久久精品免费| 国产欧美一区二区在线| 麻豆精品久久精品色综合| 欧美亚洲动漫制服丝袜| 日韩毛片一二三区| 国产伦精品一区二区三区在线观看| 欧美日韩精品是欧美日韩精品| 亚洲天天做日日做天天谢日日欢| 韩日精品视频一区| 日韩精品一区二区三区中文不卡| 亚洲一区二区精品3399| 色综合中文字幕国产 | 中文字幕av免费专区久久| 亚洲午夜久久久久久久久久久| 成人性视频免费网站| 2021久久国产精品不只是精品| 视频在线在亚洲| 在线观看不卡一区| 成人欧美一区二区三区小说| 成人永久免费视频| 国产午夜精品一区二区三区嫩草| 免费精品视频最新在线| 3atv一区二区三区| 日韩高清在线电影| 欧美性感一类影片在线播放| 欧美又粗又大又爽| 日韩av一区二区在线影视| 亚洲女同女同女同女同女同69| 337p日本欧洲亚洲大胆色噜噜| 美女在线视频一区| 久久电影网电视剧免费观看| 国产精品自拍av| 91精品国产综合久久精品图片| 一区二区三区蜜桃| 欧美丰满少妇xxxxx高潮对白| 亚洲18影院在线观看| 777久久久精品| 秋霞影院一区二区| 精品欧美一区二区三区精品久久 | 欧美日韩电影在线播放| 亚洲电影视频在线| 欧美一区二区观看视频| 精品无人区卡一卡二卡三乱码免费卡| 欧美一区二区三区思思人| 视频一区中文字幕| 欧美mv日韩mv亚洲| 懂色av中文字幕一区二区三区 | 色婷婷久久一区二区三区麻豆| 亚洲人成影院在线观看| 欧美无乱码久久久免费午夜一区| 日韩专区在线视频| 2019国产精品| 91麻豆精东视频| 天天影视网天天综合色在线播放| 91麻豆精品国产91久久久更新时间 | 午夜电影一区二区三区| 91精品国产高清一区二区三区蜜臀 | 午夜精彩视频在线观看不卡| 一本一道综合狠狠老| 爽好久久久欧美精品| 国产视频一区不卡| 在线亚洲一区二区| 美日韩一区二区| 国产精品盗摄一区二区三区| 欧美日本在线播放| 成人永久免费视频| 肉色丝袜一区二区| 国产精品亲子乱子伦xxxx裸| 欧美高清性hdvideosex| 国产91精品一区二区| 天天影视涩香欲综合网| 亚洲欧洲一区二区在线播放| 欧美一级理论性理论a| 99在线精品观看| 激情综合五月天| 亚洲国产综合91精品麻豆| 亚洲国产高清aⅴ视频| 日韩一区二区三区在线观看 | 日韩精品一区二| 91福利区一区二区三区| 成人的网站免费观看| 麻豆精品一二三| 石原莉奈一区二区三区在线观看| 国产精品美女久久福利网站| 精品成a人在线观看| 欧美美女黄视频| 欧美日韩午夜在线视频| 色成年激情久久综合| av动漫一区二区| 国产成人av网站| 韩国一区二区三区| 蜜臀av一区二区| 免费人成在线不卡| 日韩影院在线观看| 日韩影院免费视频| 日韩二区三区在线观看| 日韩影视精彩在线| 日日夜夜免费精品| 日本欧美大码aⅴ在线播放| 亚洲国产成人porn| 亚洲国产一区二区视频| 亚洲成国产人片在线观看| 亚洲精品久久嫩草网站秘色| 亚洲精选视频免费看| 一区二区三区视频在线看| 亚洲专区一二三| 亚洲成人资源网| 肉丝袜脚交视频一区二区| 久久99最新地址| 国产在线日韩欧美| 国产乱一区二区| www.性欧美| 欧美这里有精品| 91精品国产综合久久精品性色| 91精品免费在线| 精品国产一区二区三区四区四| 国产亚洲综合在线| 中文字幕一区二区日韩精品绯色| 中文字幕一区二区三区不卡在线 | 3751色影院一区二区三区| 精品国产污污免费网站入口 | 亚洲视频一区二区免费在线观看| 亚洲人成网站色在线观看| 五月天婷婷综合| 经典三级在线一区| 99热这里都是精品| 欧美网站大全在线观看| 欧美一区二区三区影视| 久久久久亚洲蜜桃| 亚洲视频电影在线| 蜜臀av性久久久久蜜臀aⅴ四虎| 精品亚洲porn| 91免费在线看| 日韩欧美一区二区在线视频| 欧美激情一区二区三区全黄| 一区二区三区在线观看动漫| 蜜臀久久99精品久久久久久9| 国产999精品久久| 91麻豆精品久久久久蜜臀| 国产欧美一区视频| 日韩中文字幕区一区有砖一区 | www日韩大片| 亚洲色图在线播放| 国内精品国产成人| 欧美日韩成人激情| 一区免费观看视频| 韩国欧美国产一区| 欧美精品色一区二区三区|