图像的一般格式
摘要:描述了各種圖像文件結構,尤其著重講述了PPM文件格式以及PPM文件的讀寫。因為最近在使用PPM文件做圖像處理,以前并未接觸到,所以會特別關注。?
?
???一般的圖像文件結構主要都包含有文件頭、文件體和文件尾等三部分:
????文件頭:軟件ID、軟件版本號、圖像分辨率、圖像尺寸、圖像深度、彩色類型、編碼方式、壓縮算法
???文件體:圖像數據、彩色變換表
???文件尾:用戶名、注釋、開發日期、工作時間
???以上是一個大概的圖像文件結構說明,實際的結構根據不同的格式其中的條目要細得多,結構也復雜得多,各個條目所占空間及條目間的排列順序也大不相同。目前還沒有非常統一的圖像文件格式。但大多數圖像處理軟件都與數種圖像文件格式相兼容,也即可讀取多種不同格式的圖像文件。這樣,不同的圖像格式間可相互轉換。當然,還有專門的圖像格式轉換軟件,用于各種圖像格式間的轉換。
BMP格式
BMP是一種與硬件設備無關的圖像文件格式,使用非常廣。它采用位映射存貯格式,除了圖像深度可選以外,不采用其它任何壓縮,因此,BMP文件所占用的空間很大。BMP文件的圖像深度可選1bit、4 bit、8 bit及24bit。BMP文件存儲數據時,圖像的掃描方式是按從左到右、從下到上的順序。
PCX格式
是PC 畫筆的圖像文件格式。PCX的圖像深度可選為1、4、8bit。由于這種文件格式出現較早,它不支持真彩色。PCX文件采用RLE行程編碼,文件體中存放的是壓縮后的圖像數據。因此,將采集到的圖像數據寫成PCX文件格式時,要對其進行RLE編碼;而讀取一個PCX文件時首先要對其進行RLE解碼,才能進一步顯示和處理。
TIFF格式
TIFF(Tag Image FileFormat)文件是由Aldus和Microsoft公司為掃描儀和桌上出版系統研制開發的一種較為通用的圖像文件格式。TIFF格式靈活易變,它又定義了四類不同的格式:TIFF-B適用于二值圖像;TIFF-G適用于黑白灰度圖像;TIFF-P適用于帶調色板的彩色圖像;TIFF-R適用于RGB真彩圖像。TIFF支持多種編碼方法,其中包括RGB無壓縮、RLE壓縮及JPEG壓縮等。
GIF格式
GIF(Graphics Interchange Format)是CompuServe公司在1987年開發的圖像文件格式,1989年在1987年版本基礎上進行了擴充,擴充后的版本號定義為GIF89a,而1987年版本則為GIF87a。GIF采用LZW壓縮算法來存儲圖象數據,并采用了可變長度等壓縮算法。GIF的圖像深度從1bit到8bit,也即GIF最多支持256種顏色的圖像。GIF格式的另一個特點是其在一個GIF文件中可以存多幅彩色圖像,如果把存于一個文件中的多幅圖像數據逐幅讀出并顯示到屏幕上,就可構成一種最簡單的動畫。
SWF格式
SWF(Shock WaveFlash)是Macromedia公司軟件Flash生成的一種動畫文件格式。這是一種網絡矢量圖形標準,壓縮率高,但需要Flash軟件或插件才能播放
JPEG格式
JPEG(Joint Photographic ExpertsGroup)是由CCITT(國際電報電話咨詢委員會)和ISO(國際標準化組織)聯合組成的一個圖像專家組。該專家組制定的第一個壓縮靜態數字圖像的國際標準,其標準名稱為“連續色調靜態圖像的數字壓縮和編碼(DigitalCompression and Coding of Continuous - tone StillImage)”,簡稱為JPEG算法。這是一個適用范圍很廣的通用標準,其目標如下:
???1.開發的算法在圖像壓縮率方面是 /或接近當前的科學水平,圖像的保真度在較寬的壓縮范圍里的評價是“很好”、“優秀”到與原圖像“不能區別”。
???2.開發的算法可實際應用于任何一類數字圖像源,如對圖像的大小、顏色空間、像素的長寬比、圖像的內容、復雜程度、顏色數及統計特性等都不加限制。
???3.對開發的算法,在計算的復雜程度方面可以調整,因而可根據性能和成本要求來選擇用軟件執行還是用硬件執行。
????4.開發的算法包括四種編碼方式:如順序編碼、累進編碼、無損壓縮編碼和分層編碼等。
???JPEG采用對稱的壓縮算法,也即在同一系統環境下壓縮和解壓縮所用的時間相同。采用JPEG壓縮編碼算法壓縮的圖像,其壓縮比約為1:5至1:50,甚至更高。
PNG格式
PNG(Portable Network Graphic Format,便攜式網絡圖象格式)是W3C組織在20世紀90年代中期開始開發的一種無損位圖文件存儲格式,1996年10月1日正式公布,是一種輕便、無法律障礙、壓縮性能好且規范好的一個標準,其目的是企圖替代GIF和TIFF,同時增加一些它們文件格式所不具備的特性。PNG名稱來源于非官方的“PNG'sNot GIF”,是一種位圖文件(bitmapfile)存儲格式,讀成“ping”。PNG支持索引彩色、灰度和真彩色,并提供可選的α通道。用來存儲灰度圖象時,灰度圖象的深度可多達16位(bit),存儲彩色圖象時,彩色圖象的深度可多達48位(bit),并且還可存儲多達16位的α通道數據。PNG圖象格式文件(或者稱為數據流)由一個8字節的PNG文件署名(PNG filesignature)域和按照特定結構組織的3個以上的數據塊(chunk)組成。PNG定義了兩種類型的數據塊,一種是稱為關鍵數據塊(criticalchunk),這是標準的數據塊;另一種叫做輔助數據塊(ancillarychunks),這是可選的數據塊。關鍵數據塊定義了4個標準數據塊,每個PNG文件都必須包含它們,PNG讀寫軟件也都必須要支持這些數據塊。雖然PNG文件規范沒有要求PNG編解碼器對可選數據塊進行編碼和解碼,但規范提倡支持可選數據塊。
?
特別關注PPM
PPM灰度文件:
文件頭由3行文本組成,可由fgets讀出
1)第一行為“P2",表示文件類型
2)第二行為圖像的寬度和高度
3)第三行為最大的象素值255
接下來是圖像數據塊。按行順序存儲。每個象素占4個字節,灰度通道為4字節ASCII碼表示的整數,高字節在前。左上角為坐標原點。
16位PPM文件:(至少適用于讀取由DCRAW生成的PPM文件)
文件頭由3行文本組成,可由fgets讀出
1)第一行為“P6",表示文件類型
2)第二行為圖像的寬度和高度
3)第三行為最大的象素值
接下來是圖像數據塊。按行順序存儲。每個象素占6個字節,依次為紅綠藍通道,每個通道為2字節整數,高字節在前。
?
PPM彩色文件:
文件頭由3行文本組成,可由fgets讀出
1)第一行為“P3",表示文件類型
2)第二行為圖像的寬度和高度
3)第三行為最大的象素值255
接下來是圖像數據塊。按行順序存儲。每個象素占12個字節,依次為紅綠藍通道,每個通道為4字節ASCII碼表示的整數,高字節在前。左上角為坐標原點。
?
PPM文件的讀寫
??#ifndef ??PNM_FILE_H?
??#define ?PNM_FILE_H?????
??#include ??<cstdlib>?
??#include ??<climits>?
??#include ??<cstring>?
??#include ??<fstream>?
??#include ??"image.h"?
??#include ??"misc.h"?
??#include ?<iostream.h>//for ?debug,qiansen??????
??#define ??BUF_SIZE?256???
???
??class?pnm_error??{ ??};
?static?image<rgb>?*loadPPM(const?char?*name)??{ ?
??????char??buf[BUF_SIZE],?doc[BUF_SIZE];?
??????
??????
?????std::ifstream?file(name,?std::ios::in?|std::ios::binary); ?
?????pnm_read(file, ??buf); ?
?????if?(strncmp(buf,?"P5",?2)){?
?????????//throw?pnm_error(); ?
?????????cout<<"pnmversion??is?P6,may?be not supported."<<endl;?
??????}?
?????pnm_read(file,?buf); ?
??????intwidth?=?atoi(buf);?
?????pnm_read(file, buf); ?
?????int?height =?atoi(buf);?
???
?????pnm_read(file,?buf); ?
?????if(atoi(buf)>UCHAR_MAX) ?
????????throw?pnm_error(); ?
???
??????
?????image<rgb>?*im?=?new?image<rgb>(width,??height); ?
?????file.read((char*)imPtr(im,0,0),?width?*?height?*sizeof(rgb));???
?????return?im; ?
??} ?
???
?static?void?savePPM(image<rgb>*im,?constchar *name) ??{ ?
??????intwidth?= im->width(); ?
??????int height=?im->height(); ?
?????std::ofstream?file(name,?std::ios::out?|?std::ios::binary);?
???
?????file<<"P6\n"<<width<<"?"<<height<<"\n"<<UCHAR_MAX<<"\n";?
?????file.write((char*)imPtr(im,0,0),width?*?height?*sizeof(rgb)); ?
??}??
參考文獻:
[1]http://topic.csdn.net/t/20050912/10/4263160.html
[2]http://www.kylinx.net/node/55
[3]http://blog.csdn.net/begtostudy/archive/2006/10/13/1332750.aspx
轉自:http://blog.163.com/jianweicheng@126/blog/static/3567320220071122112155300/
?
from:?http://blog.csdn.net/yangtrees/article/details/7731762
轉載于:https://www.cnblogs.com/GarfieldEr007/p/5401872.html
總結
- 上一篇: New Day
- 下一篇: 在ubuntu14.04 64位虚拟机