程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 位圖文件內部初探

位圖文件內部初探

編輯:關於C++

最常用的幾種圖象文件格式怎樣存儲圖象自從我在十四年前買回第一台pc以後,我就一直對計算機用1和0組成的數據流來存儲那些復雜的信息很感興趣。最初引起我注意的是當時曾很流行的印在雜志上的basic程序清單,它們帶有很多數據段,你可將它們鍵入並運行,以建立其他的程序。從這裡我明白了任何程序無論它多麼復雜,也只不過是一系列的針對計算機微處理器的指令而已。接著,我對ascii碼有了興趣,然後是字處理文件格式,再後來嗎,您就看到了圖象。

直至今天仍讓我著迷的一種技術是位圖文件存儲。一個位圖存儲了計算機上能夠再現一幅圖象所需的信息。我們經常在顯示器上看到圖象,例如一幅美麗的日落,然而在計算機眼裡它只是一堆0和1的組合。歸根結底,也就是位圖文件裡的這些位和字節來告訴計算機這幅圖象中每個象素該是什麼顏色,然後計算機把位圖中的顏色轉化成與它的顯示卡兼容的格式,最後輸出到顯示器上。

這個過程中有趣的是計算機怎樣解釋位圖中的數據,位圖文件有多種格式,每種格式都有自己的方法對象素數據編碼並給出此種格式所要求的一些其他信息,之所以windows95能夠讀取.bmp文件而不能讀.gif文件,就是因為他的設計人員使paint程序能夠對以.bmp格式存儲的圖象數據進行解碼,而不是.gif。

到這裡。您一定很想知道一個位圖文件裡究竟是什麼,一種格式同另一種又有什麼不同?那麼就讓我們來簡單地看看在pc機上常用的六種位圖文件格式。當然還有其他的文件格式,例如對於矢量圖形,就是存儲一些再現圖象的指令而不是每個象素的顏色數據,但是在這裡討論的這六種位圖文件格式才是您平時工作最可能使用的。

bmp文件

bmp(bitmap的縮寫)文件格式是windows本身的位圖文件格式,所謂本身是指windows內部存儲位圖即采用這種格式。一個.bmp格式的文件通常有.bmp的擴展名,但有一些是以.rle為擴展名的,rle的意思是行程長度編碼(runlengthencoding)。這樣的文件意味著其使用的數據壓縮方法是.bmp格式文件支持的兩種rle方法中的一種。

bmp文件可用每象素1、4、8、16或24位來編碼顏色信息,這個位數稱作圖象的顏色深度,它決定了圖象所含的最大顏色數。一幅1-bpp(位每象素,bitperpixel)的圖象只能有兩種顏色。而一幅24-bpp的圖象可以有超過16兆種不同的顏色。

下一頁的圖說明了一個典型.bmp文件的結構。它是以256色也就是8-bpp為例的,文件被分成四個主要的部分:一個位圖文件頭,一個位圖信息頭,一個色表和位圖數據本身。位圖文件頭包含關於這個文件的信息。如從哪裡開始是位圖數據的定位信息,位圖信息頭含有關於這幅圖象的信息,例如以象素為單位的寬度和高度。色表中有圖象顏色的rgb值。對顯示卡來說,如果它不能一次顯示超過256種顏色,讀取和顯示.bmp文件的程序能夠把這些rgb值轉換到顯示卡的調色板來產生准確的顏色。

bmp文件的位圖數據格式依賴於編碼每個象素顏色所用的位數。對於一個256色的圖象來說,每個象素占用文件中位圖數據部分的一個字節。象素的值不是rgb顏色值,而是文件中色表的一個索引。所以在色表中如果第一個r/g/b值是255/0/0,那麼象素值為0表示它是鮮紅色,象素值按從左到右的順序存儲,通常從最後一行開始。所以在一個256色的文件中,位圖數據中第一個字節就是圖象左下角的象素的顏色索引,第二個就是它右邊的那個象素的顏色索引。如果位圖數據中每行的字節數是奇數,就要在每行都加一個附加的字節來調整位圖數據邊界為16位的整數倍。

並不是所有的bmp文件結構都象表中所列的那樣,例如16和24-bpp,文件就沒有色表,象素值直接表示rgb值,另外文件私有部分的內部存儲格式也是可以變化的。例如,在16和256色.bmp文件中的位圖數據采用rle算法來壓縮,這種算法用顏色加象素個數來取代一串顏色相同的序列,而且,windows還支持os/2下的.bmp文件,盡管它使用了不同的位圖信息頭和色表格式。

pcx文件

.pcx是在pc上成為位圖文件存儲標准的第一種圖象文件格式。它最早出現在zsoft公司的paintbrush軟件包中,在80年代早期授權給微軟與其產品捆綁發行,而後轉變為microsoftpaintbrush,並成為windows的一部分。雖然使用這種格式的人在減少,但這種帶有.pcx擴展名的文件在今天仍是十分常見的。

pcx文件分為三部分,依次為:pcx文件頭,位圖數據和一個可選的色表。文件頭長達128個字節,分為幾個域,包括圖象的尺寸和每個象素顏色的編碼位數。位圖數據用一種簡單的rle算法壓縮,最後的可選色表有256個rgb值,pcx格式最初是為cga和ega來設計的,後來經過修改也支持vga和真彩色顯示卡,現在pcx圖象可以用1、4、8或24-bpp來對顏色數據進行編碼。

tiff文件

pcx格式是所有位圖文件格式中最簡單的,而tiff(taggedimagefileformat)則是最難的一種。

tiff文件含有.tif的擴展名。它以8字節長的圖象文件頭開始(ifh),這個文件頭中最重要的成員是一個指向名為圖象文件目錄(ifd)的數據結構的指針。Ifd是一個名為標記(tag)的用於區分一個或多個可變長度數據塊的表,標記中含有關於圖象的信息。Tiff文件格式定義70多種不同類型的標記,有的用來存放以象素為單位的圖象寬度和高度,有的用來存放色表(如果需要的話),當然還必須有用來存放位圖數據的標記,一個tiff格式文件完全為它的標記所決定,而且這種文件結構極易擴展,因為你要附加一些特征只須增加一些額外的標記。

究竟是什麼使tiff文件如此復雜?一方面,要寫一種能夠識別所用不同標記的軟件非常困難。大多數tiff的閱讀程序只能識別一部分標記,所以會出現這種情況:有時一個應用程序創建的tiff文件,另一個應用程序卻不能使用。創建tiff文件的程序還可能會在文件中加一些只有它自己認識的標記,雖然tiff的閱讀程序可以跳過那些它們不認得的標記,但這樣做總是有可能影響到圖象的質量。

另一方面,一個tiff文件可以包含多個圖象,每個圖象都有自己的ifd和一系列標記。Tiff文件中的位圖數據可能會用好幾種方法來壓縮,所以一個完備的tiff閱讀程序應該有rle解壓縮程序,lzw解壓縮程序和其他一些算法的解壓縮程序。然而更糟的是使用lzw的解碼必須得到unisys公司的同意,且通常是需要付版稅的。所以即使是一些相當不錯的tiff閱讀程序在它們遇到lzw算法壓縮的圖象時也是無能為力的。

盡管tiff是那麼的復雜,但仍是一種最好的跨平台格式。因為它非常靈活,無論在視覺上還是其他方面,都能把任何圖象編碼成二進制形式而不丟失任何屬性。

gif文件

當許多圖象方面的權威一想到lzw的時候,他們也會想到gif(graphicsinterchangeformat,讀作jiff)這是一種常用的跨平台的位圖文件格式,最初為compuserve公司所創。Gif文件通常帶有.gif的擴展名,而且在compuseve上大量存在。

gif文件的結構取決於它屬於哪一個版本,目前的兩種版本分別是gif87a和gif89a,前者較簡單。無論是哪個版本,它都以一個長13字節的文件頭開始,文件頭中包含判定此文件是gif文件的標記、版本號和其他的一些信息。如果這個文件只有一幅圖象,文件頭後緊跟一個全局色表來定義圖象中的顏色。如果含有多幅圖象(gif和tiff格式一樣,允許在一個文件裡編碼多個圖象),那麼全局色表就被各個圖象自帶的局部色表所替代。

在gif87a文件中,文件頭和全局色表之後是圖象,它可能會是頭尾相接的一串圖象中的第一個,每個圖象由三部分組成,一個10字節長的圖象描述,一個可選的局部色表和位圖數據。為有效利用空間,位圖數據用lzw算法來壓縮。

gif89a結構與此類似,但它還包括可選的擴展塊來存放每個圖象的附加信息。Gif89a詳細定義了四種擴展塊:圖象控制擴展塊,它用來描述圖象怎樣被顯示(例如,顯示是應該象一個透明物去覆蓋上一個圖象,還是簡單的替換它);簡單文本擴展塊,它包含顯示在圖象中的文本;注釋擴展塊,它以ascii文本形式存放注釋;應用擴展塊,它存放生成該文件的應用程序的私有數據。這些擴展塊可以出現在文件中全局色表的任何地方。

gif最顯著的優點是它的廣泛使用和它的緊密性。但它有兩個弱點,一個是用gif格式存放的文件最多只能含有256種顏色。另一個可能更重要,就是那些使用了gif格式的軟件開發者必須征得compuserve的同意,他們每賣出一個拷貝都要向compuserve付版稅。這個政策是compuserve仿效unisys公司作出的,它抑制了那些程序員在他的圖象應用程序中支持gif文件。

png文件

png(portablenetworkgraphic,發音做ping)文件格式是作為gif的替代品開發的,它能夠避免使用gif文件所遇到的常見問題。它從gif那裡繼承了許多特征,而且支持真彩色圖象。更重要的是,在壓縮位圖數據時它采用了一種頗受好評的lz77算法的一個變種,lz77則是lzw的前身,而且可以免費使用。由於篇幅所限,在這裡就不花時間來具體討論png格式了。

jpeg文件

jpeg(jointphotographicexpertsgroup,發音做jay-peg)文件格式最初由c-cubemicrosystems推出,是為了提供一種存儲深度位象素的有效方法,例如對於照片掃描,顏色很多而且差別細微(有時也不細微)。Jpeg和這裡討論的其他格式的最大區別是jpeg使用一種有損壓縮算法,無損壓縮算法能在解壓後准確再現壓縮前的圖象,而有損壓縮則犧牲了一部分的圖象數據來達到較高的壓縮率。但是這種損失很小以至於人們很難察覺。

jpeg圖象壓縮是一個復雜的過程,經常需要專門的硬件來幫助。首先圖象以象素為單位分成8*8的塊。然後,每個塊分三個步驟被壓縮。第一步使用dct(discretecosinetransform)離散余弦變換把8*8的象素矩陣變成8*8的頻率(也就是顏色改變的速度)矩陣。第二步對頻率矩陣中的值用量化矩陣進行量化,濾掉那些總體上對圖象不重要的部分。第三步,也就是最後一步,對量化後的頻率矩陣使用無損壓縮。

因為被量化後的頻率矩陣缺了許多高頻信息,通常能被壓縮到一半甚至更少。無損壓縮一般根本不能壓縮真正的照片圖象,所以50%的壓縮率已是相當不錯了,但另一方面,無損壓縮能把一些圖象文件尺寸減少90%,這樣的圖象文件就不適合用jpeg來壓縮。

jpeg的有損部分產生在第二步,量化矩陣的值越高,從圖象中丟掉的信息就越多,從而壓縮率就越高,可是同時圖象的質量就越差。在jpeg壓縮時可以選擇一個量化因子,這個因子的值決定了量化矩陣中的數值。理想的量化因子要在壓縮率和圖象質量間達到平衡,所以對不同的圖象要選擇不同的量化因子,通常要經過若干次嘗試後方可確定.

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved