<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-57  評(píng)論-202  文章-17  trackbacks-0
          要將BufferedImage實(shí)例保存為BMP文件,就需要知道BMP文件的格式,可以參考我轉(zhuǎn)載的文章:《BMP文件格式》
          下面是我的將BufferedImage實(shí)例保存為24位色BMP文件的實(shí)現(xiàn)。
          首先是BMP文件相關(guān)的兩個(gè)頭結(jié)構(gòu):BMPFileHeader和BMPInfoHeader。

    /*
     * Created on 2005-6-21
     *
     * TODO To change the template for this generated file go to
     * Window - Preferences - Java - Code Style - Code Templates
     
    */

    package org.lotus.image.codec.bmp;

    /**
     * <p> Title: BMP文件的頭結(jié)構(gòu)</p>
     * 
     * <p> Description: BMP文件的頭結(jié)構(gòu)固定是14個(gè)字節(jié),其定義如下:</p>
     * <p>
     * byte[2] bfType;                    指定文件類型,必須是0x424D,即字符串“BM”,也就是說所有.bmp文件的頭兩個(gè)字節(jié)都是“BM“
     * byte[4] bfSize;                    指定文件大小,包括這14個(gè)字節(jié)
     * byte[2] bfReserved1;            保留字
     * byte[2] bfReserved2;            保留字
     * byte[4] bfOffBits;                為從文件頭到實(shí)際的位圖數(shù)據(jù)的偏移字節(jié)數(shù)
     * </p>
     * 
     * <p> Copyright: Copyright (c) 2005</p>
     * 
     * <p> Company: 21Lotus</p>
     * 
     * @author George Hill
     * @version 1.0
     
    */


    class BMPFileHeader {

        
    // Header data
        private byte[] data = new byte[14];

        
    public byte[] getData() {
            
    return this.data;
        }

        
        
    // BMP file size
        private int size;
        
        
    public int getSize() {
            
    return this.size;
        }

        
        
    private int offset;
        
        
    public int getOffset() {
            
    return this.offset;
        }

        
        BMPFileHeader(
    int size, int offset) {
            
    this.size = size;
            
    this.offset = offset;
            
            data[
    0= 'B';
            data[
    1= 'M';

            
    int value = size;
            data[
    2= (byte) value;
            value 
    = value >>> 8;
            data[
    3= (byte) value;
            value 
    = value >>> 8;
            data[
    4= (byte) value;
            value 
    = value >>> 8;
            data[
    5= (byte) value;

            value 
    = offset;
            data[
    10= (byte) value;
            value 
    = value >>> 8;
            data[
    11= (byte) value;
            value 
    = value >>> 8;
            data[
    12= (byte) value;
            value 
    = value >>> 8;
            data[
    13= (byte) value;
        }

        
    }


    /*
     * Created on 2005-6-21
     *
     * TODO To change the template for this generated file go to
     * Window - Preferences - Java - Code Style - Code Templates
     
    */

    package org.lotus.image.codec.bmp;

    /**
     * <p>Title: BMP文件內(nèi)容的頭結(jié)構(gòu)</p>
     *
     * <p>Description: BMP文件內(nèi)容的頭結(jié)構(gòu)固定是40個(gè)字節(jié),其定義如下:</p>
     * <p>
     * byte[4] biSize;                            指定這個(gè)結(jié)構(gòu)的長度,為40
     * byte[4] biWidth;                            指定圖象的寬度,單位是象素
     * byte[4] biHeight;                        指定圖象的高度,單位是象素
     * byte[2] biPlanes;                        必須是1,不用考慮
     * byte[2] biBitCount;                    指定表示顏色時(shí)要用到的位數(shù),常用的值為1(黑白二色圖), 4(16色圖), 8(256色), 24(真彩色圖)
     * byte[4] biCompression;                指定位圖是否壓縮
     * byte[4] biSizeImage;                    指定實(shí)際的位圖數(shù)據(jù)占用的字節(jié)數(shù)
     * byte[4] biXPelsPerMeter;            指定目標(biāo)設(shè)備的水平分辨率,單位是每米的象素個(gè)數(shù)
     * byte[4] biYPelsPerMeter;            指定目標(biāo)設(shè)備的垂直分辨率,單位是每米的象素個(gè)數(shù)
     * byte[4] biClrUsed;                        指定本圖象實(shí)際用到的顏色數(shù),如果該值為零,則用到的顏色數(shù)為2biBitCount
     * byte[4] biClrImportant;            指定本圖象中重要的顏色數(shù),如果該值為零,則認(rèn)為所有的顏色都是重要的
     * </p>
     *
     * <p>Copyright: Copyright (c) 2005</p>
     *
     * <p>Company: 21Lotus</p>
     *
     * @author George Hill
     * @version 1.0
     
    */


    class BMPInfoHeader {

        
    private byte[] data = new byte[40];
        
        
    public byte[] getData() {
            
    return this.data;
        }

        
        
    private int width;
        
        
    public int getWidth() {
            
    return this.width;
        }

        
        
    private int height;
        
        
    public int getHeight() {
            
    return this.height;
        }

        
        
    public int bitCount;
        
        
    public int getBitCount() {
            
    return this.bitCount;
        }

        
        
    public BMPInfoHeader(int width, int height, int bitCount) {
            
    this.width = width;
            
    this.height = height;
            
    this.bitCount = bitCount;
            
            data[
    0= 40;

            
    int value = width;
            data[
    4= (byte) value;
            value 
    = value >>> 8;
            data[
    5= (byte) value;
            value 
    = value >>> 8;
            data[
    6= (byte) value;
            value 
    = value >>> 8;
            data[
    7= (byte) value;

            value 
    = height;
            data[
    8= (byte) value;
            value 
    = value >>> 8;
            data[
    9= (byte) value;
            value 
    = value >>> 8;
            data[
    10= (byte) value;
            value 
    = value >>> 8;
            data[
    11= (byte) value;

            data[
    12= 1;

            data[
    14= (byte) bitCount;

            value 
    = width * height * 3;
            
    if (width % 4 != 0)
              value 
    += (width % 4* height;
            data[
    20= (byte) value;
            value 
    = value >>> 8;
            data[
    21= (byte) value;
            value 
    = value >>> 8;
            data[
    22= (byte) value;
            value 
    = value >>> 8;
            data[
    23= (byte) value;
        }

        
    }


          仿照com.sun.image.codec.jpeg.JPEGImageEncoder寫的接口類BMPEncoder。

    /*
     * Created on 2005-6-21
     *
     * TODO To change the template for this generated file go to
     * Window - Preferences - Java - Code Style - Code Templates
     
    */

    package org.lotus.image.codec.bmp;

    import java.awt.image.
    *;
    import java.io.IOException;

    /**
     * <p>Title: </p>
     *
     * <p>Description: </p>
     *
     * <p>Copyright: Copyright (c) 2005</p>
     *
     * <p>Company: 21Lotus</p>
     *
     * @author George Hill
     * @version 1.0
     
    */


    public interface BMPEncoder {

          
    public void encode(BufferedImage bi) throws IOException;
          
          
    public static final int BIT_COUNT_BLACKWHITE = 1;
          
    public static final int BIT_COUNT_16COLORS = 4;
          
    public static final int BIT_COUNT_256COLORS = 8;
          
    public static final int BIT_COUNT_TRUECOLORS = 24;
          
    }


          BMPEncoder接口的實(shí)現(xiàn)BMPEncoderImpl。

    /*
     * Created on 2005-6-21
     *
     * TODO To change the template for this generated file go to
     * Window - Preferences - Java - Code Style - Code Templates
     
    */

    package org.lotus.image.codec.bmp;

    import java.awt.image.
    *;
    import java.io.
    *;

    /**
     * <p>Title: </p>
     *
     * <p>Description: </p>
     *
     * <p>Copyright: Copyright (c) 2005</p>
     *
     * <p>Company: 21Lotus</p>
     *
     * @author George Hill
     * @version 1.0
     
    */


    class BMPEncoderImpl implements BMPEncoder {
        
        
    private OutputStream out;
        
        
    public BMPEncoderImpl(OutputStream out{
            
    this.out = out;
        }

        
          
    public void encode(BufferedImage bi) throws IOException {
              
    int width = bi.getWidth();
              
    int height = bi.getHeight();
              
              boolean needBlank 
    = (width % 4 != 0);
              
              
    int size = width * height * 3;
              
    if (needBlank) {
                  size 
    += (width % 4* height;
              }

              
              BMPFileHeader fileHeader 
    = new BMPFileHeader(size, 54);
              BMPInfoHeader infoHeader 
    = new BMPInfoHeader(width, height, BIT_COUNT_TRUECOLORS);

              
    byte[] rgbs = new byte[3];
              
    byte[] blank = new byte[width % 4];
              
              
    out.write(fileHeader.getData());
              
    out.write(infoHeader.getData());

              
    int index = 0;
              
    for (int y = height - 1; y >= 0; y--{
                  
    for (int x = 0; x < width; x++{
                      index 
    += 3;

                      
    int rgb = bi.getRGB(x, y);
                      rgbs[
    0= (byte) rgb;
                      rgb 
    = rgb >>> 8;
                      rgbs[
    1= (byte) rgb;
                      rgb 
    = rgb >>> 8;
                      rgbs[
    2= (byte) rgb;

                      
    out.write(rgbs);

                      
    if (needBlank && (index % (width * 3== 0)) {
                          
    out.write(blank);
                      }

                  }

              }

          }


    }


          一個(gè)工廠類BMPCodec。

    /*
     * Created on 2005-6-21
     *
     * TODO To change the template for this generated file go to
     * Window - Preferences - Java - Code Style - Code Templates
     
    */

    package org.lotus.image.codec.bmp;

    import java.io.OutputStream;

    /**
     * <p>Title: </p>
     *
     * <p>Description: </p>
     *
     * <p>Copyright: Copyright (c) 2005</p>
     *
     * <p>Company: 21Lotus</p>
     *
     * @author George Hill
     * @version 1.0
     
    */


    public class BMPCodec {

        
    public static BMPEncoder createBMPEncoder(OutputStream dest) {
            
    return new BMPEncoderImpl(dest);
        }

        
    }


          下面是我的測試用例:

    /*
     * Created on 2005-6-22
     *
     * TODO To change the template for this generated file go to
     * Window - Preferences - Java - Code Style - Code Templates
     
    */

    package org.lotus.test;

    import java.awt.
    *;
    import java.awt.image.
    *;
    import java.io.
    *;

    import junit.framework.TestCase;

    import org.lotus.image.codec.bmp.
    *;

    /**
     * <p>Title: </p>
     *
     * <p>Description: </p>
     *
     * <p>Copyright: Copyright (c) 2005</p>
     *
     * <p>Company: 21Lotus</p>
     *
     * @author George Hill
     * @version 1.0
     
    */

    public class BMPCodecTest extends TestCase {

        
    /*
         * @see TestCase#setUp()
         
    */

        
    protected void setUp() throws Exception {
            super.setUp();
        }


        
    /*
         * @see TestCase#tearDown()
         
    */

        
    protected void tearDown() throws Exception {
            super.tearDown();
        }


        
    public void testCreateBMPEncoder() throws Exception {
            
    int width = 104;
            
    int height = 100;
            
    int size = width * height * 3;
            
    if (width % 4 != 0)
              size 
    += (width % 4* height;
            size 
    += 54;
            BufferedImage image 
    = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            Graphics g 
    = image.getGraphics();
            g.setColor(Color.WHITE);
            g.fillRect(
    00, width, height);

            g.setColor(Color.BLUE);
            g.setFont(
    new Font("宋體", Font.ITALIC, 20));
            g.drawString(
    "Hello"3030);
            
            BMPCodec.createBMPEncoder(
    new FileOutputStream("C:\\house\\test.bmp")).encode(image);
        }


    }


          保存的BMP文件如圖:

    test.JPG
    posted on 2005-07-04 17:33 小米 閱讀(3434) 評(píng)論(6)  編輯  收藏 所屬分類: Java

    評(píng)論:
    # re: 如何將BufferedImage實(shí)例保存為BMP文件 2005-07-05 21:24 | jek
    怎么才能使生成的bmp文件看上去更亂一些呢,例如驗(yàn)證碼  回復(fù)  更多評(píng)論
      
    # re: 如何將BufferedImage實(shí)例保存為BMP文件 2005-07-06 09:37 | 小米
    這個(gè)可以看我的另外一篇隨筆《我的網(wǎng)頁附加碼實(shí)現(xiàn)》http://m.tkk7.com/georgehill/archive/2005/05/12/4228.html  回復(fù)  更多評(píng)論
      
    # re: 如何將BufferedImage實(shí)例保存為BMP文件 2007-11-27 16:29 | wangle

    if (needBlank && (index % (width * 3) == 0)) {
    out.write(blank);
    }

    我只看到 blank new了,但沒有附值.這一點(diǎn)不里解.請指教.謝謝!

    我的mail: wanglework@163.com  回復(fù)  更多評(píng)論
      
    # re: 如何將BufferedImage實(shí)例保存為BMP文件 2007-11-27 16:37 | wangle
    還對著幾句不理解:

    byte[width % 4];

    if (width % 4 != 0)
    size += (width % 4) * height;


    if (needBlank && (index % (width * 3) == 0))

    望賜教.謝謝!

    我的mail: wanglework@163.com  回復(fù)  更多評(píng)論
      
    # re: 如何將BufferedImage實(shí)例保存為BMP文件 2007-11-27 16:41 | wangle
    這里回復(fù)也可以! 我以后回常來拜訪的!!  回復(fù)  更多評(píng)論
      
    # re: 如何將BufferedImage實(shí)例保存為BMP文件 2007-12-09 17:19 | wangle
    呵呵,因?yàn)轫?xiàng)目里有一個(gè)關(guān)于解析BMP的問題。在網(wǎng)上找到你這。
    自己敲過代碼后明白些了。謝謝!!  回復(fù)  更多評(píng)論
      
    主站蜘蛛池模板: 免费国产99久久久香蕉| 性xxxxx免费视频播放| 国产成人无码免费看视频软件| 又大又粗又爽a级毛片免费看| 亚洲国产精彩中文乱码AV| 亚洲国产成人无码av在线播放| 337P日本欧洲亚洲大胆艺术图| 国产好大好硬好爽免费不卡| 在线免费观看视频你懂的| 国产亚洲婷婷香蕉久久精品 | 伊伊人成亚洲综合人网7777| 亚洲国产模特在线播放| 一级成人a做片免费| 日韩av无码成人无码免费| 亚洲人成在线播放网站| 亚洲乱码无人区卡1卡2卡3| 91免费国产视频| 精品国产一区二区三区免费看| 久久国产亚洲电影天堂| 免费国产va在线观看| 99久久久国产精品免费无卡顿 | 亚洲尹人香蕉网在线视颅| 国产精品亚洲专区无码WEB | 性感美女视频免费网站午夜| 亚洲国产精品va在线播放 | 免费无码婬片aaa直播表情| 青青青免费国产在线视频小草| 亚洲中文久久精品无码ww16| 亚洲精品无码中文久久字幕| 久久免费国产视频| 区三区激情福利综合中文字幕在线一区亚洲视频1 | a毛片免费播放全部完整| 日本无吗免费一二区| 亚洲一级片在线观看| 精品亚洲永久免费精品| 亚洲国产精品综合久久一线| 亚洲最大av资源站无码av网址| 性xxxx视频免费播放直播| 国产亚洲精品成人AA片新蒲金| 视频一区在线免费观看| 成人免费视频一区二区三区|