乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      png圖片的壓縮與解壓縮

       勤奮不止 2012-07-17

      在J2ME平臺上PNG圖片格式幾乎成為了標(biāo)準(zhǔn),無數(shù)臺手持設(shè)備上運(yùn)行的J2ME程序幾乎都選用PNG來顯示圖像,包括大量的手機(jī)游戲以及手機(jī)應(yīng)用,所以對PNG文件格式的了解,可以更有效的減少Jar Size,保護(hù)自有知識產(chǎn)權(quán)。

      PNG文件格式:
              PNG文件格式分為PNG-24和PNG-8,其最大的區(qū)別是PNG-24是用24位來保存一個像素值,是真彩色,而PNG-8是用8位索引值來在調(diào)色盤中索引一個顏色,因?yàn)橐粋€索引值的最大上限為2的8次方既128,故調(diào)色盤中顏色數(shù)最多為128種,所以該文件格式又被叫做PNG-8 128仿色。
             PNG-24因?yàn)槠鋱D片容量過大,而且在Nokia和Moto等某些機(jī)型上創(chuàng)建圖片失敗和顯示不正確等異常時有發(fā)生,有時還會嚴(yán)重拖慢顯示速度,故并不常用,CoCoMo認(rèn)為這些異常和平臺底層的圖像解壓不無關(guān)系。不過該格式最大的優(yōu)點(diǎn)是可以保存Alpha通道,同事也曾有過利用該圖片格式實(shí)現(xiàn)Alpha 混合的先例,想來隨著技術(shù)的發(fā)展,手機(jī)硬件平臺的提升,Alpha混合一定會被廣泛的應(yīng)用,到那時該格式的最大優(yōu)勢才會真正發(fā)揮。
             PNG-8文件是目前廣泛應(yīng)用的PNG圖像格式,其主要有六大塊組成:
      1.文件頭
      2.IHDR塊
      3.PLTE塊
      4.tRNS塊
      5.IDAT塊
      6.文件尾
      這六大塊按順序排列,也就是說IDAT塊永遠(yuǎn)是在PLTE塊之后,期間也會有許多其他的區(qū)塊用來描述信息,例如圖像的最后修改時間是多少,圖像的創(chuàng)建者是誰等,不過這些區(qū)塊的信息對我們來說都是可有可無的描述信息,故壓縮時一般先向這些區(qū)塊開刀。

      數(shù)據(jù)塊:
      除了文件頭,其中四大數(shù)據(jù)塊和文件尾都是由統(tǒng)一的數(shù)據(jù)塊文件結(jié)構(gòu)描述的:
              Chunk Length: 4byte
              Chunk Type:   4byte
              Chunk Data:   Chunk Length的長度
              Chunk CRC:    4byte
      例如IHDR塊的數(shù)據(jù)長度為13,既
              Chunk Length = 13
              Chunk Type = "IHDR"

      文件頭:
      用來標(biāo)示PNG文件,為固定的64個字節(jié):0x89504e47 0x0d0a1a0a

      IHDR塊:
      用來描述圖像的基本信息,其格式為:
             圖像寬:    4byte
             圖像高:    4byte
             圖像色深: 4byte
             顏色類型: 1byte
             壓縮方法: 1byte
             濾波方法: 1byte
             掃描方法: 1byte
      曾經(jīng)有人問過我,撒叫濾波方法和掃描方法,汗,說實(shí)話我也不知道,不過我們是在做手機(jī)游戲,不是在搞圖形學(xué)不是嘛。

      PLTE塊:
      這個就是傳說中放置調(diào)色盤數(shù)據(jù)的地方啦,其格式為:
            循環(huán)
                 RED:    1byte
                 GREEN:1byte
                 BLUE:  1byte
            END
      循環(huán)長度嘛,不就是Chunk Length / 3的長度嘛,而且Chunk Length一定為3的倍數(shù)。

      tRNS塊:
      這個塊時有時無,主要是看你是否使用了透明色。該區(qū)塊的格式為:
            循環(huán)
                 if(對應(yīng)調(diào)色盤顏色非透明)
                     0xFF:  1byte
                 else
                     0x00:  1byte
            END
      循環(huán)長度為調(diào)色盤的顏色數(shù),相當(dāng)于調(diào)色盤顏色表的一個對應(yīng)表,標(biāo)識該顏色是否透明,0xFF不透明,0x00透明。故如果用UltraEdit查看PNG文件的二進(jìn)制編碼,如果看到一大片F(xiàn)F,一般就是tRNS區(qū)塊啦,因?yàn)橐粋€PNG文件一般只有一個透明色。

      IDAT塊:
      這個就是存放圖像數(shù)據(jù)的地方啦,這里要注意的是一個PNG文件可能有多個IDAT區(qū)塊,而其他三大區(qū)塊只可能有一個。
      IDAT 區(qū)塊是經(jīng)過壓縮的,所以數(shù)據(jù)不可讀,壓縮算法一般為LZ77滑動窗口算法,如果硬要看里面的數(shù)據(jù)的話,用zlib庫也是可以的,CoCoMo當(dāng)年就見過 Windows Mobile上的帝國時代巨變態(tài)的用zlib庫壓縮和解壓該區(qū)塊來進(jìn)一步減少PNG文件大小,真是寸K寸金啊。

      IEND塊:
      該區(qū)塊雖然也按照數(shù)據(jù)塊的結(jié)構(gòu),但Chunk Data是沒有的,所以是固定的96個字節(jié):0x00000000 0x49454e44 0xae426082

      PNG圖像壓縮:
              了解了PNG的文件結(jié)構(gòu),壓縮就有的放矢了。壓縮有6個級別,可以根據(jù)需要選擇。
      Level1:讀取PNG文件,將除六大塊之外的所有區(qū)塊都過濾掉
      Level2:文件頭是固定的0x89504e47 0x0d0a1a0a,文件尾是固定的0x00000000 0x49454e44 0xae426082,去掉!
      Level3:每個區(qū)塊的Chunk Type我們是否需要呢?很明顯,我們自己寫的壓縮格式自己應(yīng)該清楚是按照什么樣的順序,去掉!
      Level4:每個區(qū)塊的Chunk Length我們是否需要呢?
                 IHDR塊:定長13個字節(jié),明顯不需要,去掉。
                 PLTE塊:最多128個顏色,為撒要用4byte來記錄區(qū)塊長度而不是用1byte來記錄顏色數(shù)呢?
                 tRNS塊:既然有顏色數(shù),tRNS又是調(diào)色盤顏色表的對應(yīng)表,既數(shù)量與顏色數(shù)相同,為撒還需要呢?
                 IDAT塊:我想這個是唯一需要4byte來記錄長度的區(qū)塊。
      Level5:每個區(qū)塊的Chunk CRC是否需要呢?
                 因?yàn)橛嬎鉉RC需要一些時間,但對于字節(jié)較少的區(qū)塊一般可以忽略不計,所以對于這個問題還是由程序員自己決定吧。對于CRC的計算可以參看CoCoMo的另一篇Blog“PNG文件的CRC碼計算
      Level6:每個區(qū)塊我們是否要原封不動的保存期數(shù)據(jù)呢?
                IHDR塊:除了寬、高、色深是需要的,后面那4byte的信息是固定的0x03000000
                PLTE塊:為撒要用3byte來表示RGB而不是2byte的565格式?壓縮方法可以參看CoCoMo的另一篇Blog“關(guān)于PNG圖像壓縮的一點(diǎn)感悟
                tRNS塊:我想tRNS塊是冗余最多的區(qū)塊了吧,大段大段的0xFF明顯沒有必要,一般的PNG文件只有一個透明色,為撒要用對應(yīng)表的方法而不是一個索引來記錄到底哪個是透明色呢?由于顏色數(shù)最多128,所以只需1byte就可以代替tRNS那么多0xFF啦。
                IDAT塊:么想法,如果你夠變態(tài),把zlib加進(jìn)來吧!

      PNG圖像解壓:
              創(chuàng)建了自定義的文件,J2ME端讀取后,就面臨解壓的問題了。我們可以利用此函數(shù)來創(chuàng)建Image:
      static Image
      createImage(byte[] imageData, int imageOffset, int imageLength)
           前提是傳入的imageData與PNG未被壓縮前的一致。因?yàn)镻NG文件格式是固定的,所以讀取自定義的壓縮文件后,開始將那些默認(rèn)的數(shù)據(jù)再添加進(jìn)去,實(shí)現(xiàn)解壓的目的。下面就開始解壓之旅吧!
      首先要創(chuàng)建一個ByteArrayOutputStream out,

      1.寫入文件頭:
      out.writeInt(0x89504e47);
      out.writeInt(0x0d0a1a0a);

      2.寫入IHDR塊
      out.writeInt(13);
      out.writeInt(0x49484452);  //0x49484452為Chunk Type "IHDR"
      out.writeInt(width);
      out.writeInt(height);
      out.writeByte(depth);
      out.writeInt(0x03000000);  //壓縮時舍掉的4byte,默認(rèn)0x03000000
      out.writeInt(crc);
      其他區(qū)塊方法一致,故略過。。。

      3.寫入文件尾
      out.writeInt(0x00000000);
      out.writeInt(0x49454e44);
      out.writeInt(0xae426082);

      4.轉(zhuǎn)換成數(shù)組,創(chuàng)建Image
      byte[] pngBuffer = out.toByteArray();
      Image image = Image.createImage(pngBuffer, 0, pngBuffer.length);

      哈哈,大功告成。這里注意如果中途數(shù)據(jù)寫入有錯誤,經(jīng)常會出現(xiàn)創(chuàng)建Image失敗的異常,而且非常不好調(diào)試,不過只要自定的壓縮格式定下來后,對應(yīng)的創(chuàng)建Image的函數(shù)只要寫一次,以后基本不會出問題哈。

      PNG圖像加解密:
              很多人都擔(dān)心自己辛苦創(chuàng)作的漂亮的美術(shù)圖片很easy就被別人拿到了,究其原因是由于PNG文件格式是固定的,稍微了解的人用UltraEdit很容易就能找到IHDR,PLTE等標(biāo)識了。CoCoMo就經(jīng)??碐ameLoft的圖像文件,哈哈。一般是2byte的Length,然后緊接著圖片數(shù)據(jù),都放在一個文件里,直接拷貝2進(jìn)制然后粘貼到一個新文件里就是一幅圖。后來的加密技術(shù)會把PNG分塊,例如前100個字節(jié)一塊,緊接著1K一塊,最后剩余字節(jié)一塊,然后把塊順序打亂,用2byte來記錄總長度,1byte記錄順序,但是這并沒有從根本上消除IHDR,IEND這些顯眼的定位標(biāo)識,好像在對破解者說:嘿,看,我就在這里!
             現(xiàn)在了解了之前的壓縮和解壓技術(shù),這個問題也就迎刃而解了,因?yàn)镃hunk Length,Chunk Type和Chunk CRC這些東西都消失了,甚至連數(shù)據(jù)塊本身的數(shù)據(jù)都修改了,我可以按照ImageWidth、ImageHeight、ImageDepth的順序?qū)憯?shù)據(jù),也可以倒過來寫。我想再牛的PNG分析器也是無能為力的吧,唯一可以定位的就只有IDAT區(qū)塊了,不過就算得到該區(qū)塊的數(shù)據(jù),也應(yīng)該是一張黑白圖。

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多