PCX 圖象檔案格式的讀寫 (轉)
PCX 圖象格式的讀寫
PCX圖象檔案格式最早出現於Zsoft公司開發的PC Paintbrush繪圖,由於該繪圖軟體功能強大併成功移植到操作,
加上PCX是最早支援彩色的圖象格式之一,PCX成為目前比較流行的圖象格式。
對於開發圖象瀏覽、處理軟體的員來講,如何讀取、儲存PCX圖象格式是最為基本的話題,作者根據自己對PCX圖象格式理解,
開發了相應的程式碼,希望對讀者有用,由於篇幅限制,在此對檔案格式不予介紹,讀者可以參考相關數目。
程式碼如下,方法程式段之後簡單講解,水平有限,還請包涵;我的電子信箱是:to:cadinfo@263">cadinfo@263.net,歡迎探討。
========================================================
/****************************************************************************
* 名稱:LoadPCXLine(PPCXHEAD ppcxHdr, LPBYTE ppcxImg, LPBYTE ppcxBits) const
*
* 引數:PPCXHEAD ppcxHdr -指向PCXHEAD結構的指標!NULL,匯入BitPlane,Byteine,=>clScanLineSize
* LPBYTE ppcxImg -指向PCX圖象區指標!NULL,RLE編碼,位置遞增+=rec。
* 呼叫之前獲得首地址指標:
* LPBYTE ppcxBits -指向DIB資料區的指標,按掃描行(scanline)長度遞增
*
* 返回:UINT rec -返回每行解壓以後的位元組數目
*
* 說明:根據PCX圖象資料指標,對RLE進行解碼
****************************************************************************/
UINT CPcxImage::LoadPCXLine(PPCXHEAD ppcxHdr, LPBYTE ppcxImg, LPBYTE ppcxBits) const
{
ASSERT(ppcxHdr!=NULL&&ppcxImg!=NULL&&ppcxBits!=NULL);
// because in bitmap bits order, it's blue=>green=>red
// however pcx is red=>green=>blue so use decrease order
//-----------------------------------------
UINT lPos(0), // 記錄存入ppcxBits的總數
iX(0), // 記錄每個位平面位元組序號
rec(0); // 讀取_ppcxImg_ 位元組序號
for ( int bp=ppcxHdr->BitPlane-1; bp >= 0; bp-- )
{
// RLE 解碼=======
iX=0;
while ( iX
{
BYTE uiValue = ppcxImg[rec++];
if ( (uiValue & 0xc0) == 0xc0 ) // 判斷高位位元組是否設定 0xc0
{
uiValue = uiValue & 0x3f ; // 計算重複
BYTE Color = ppcxImg[rec++]; // 提取顏色
// 存放到DIB
for ( BYTE bRepeat=0; bRepeat < uiValue; bRepeat++ )
{
ppcxBits[(iX++)*ppcxHdr->BitPlane+bp] = Color;
lPos++;
}
}
else
{
ppcxBits[(iX++)*ppcxHdr->BitPlane+bp] = uiValue;
lPos++;
}
}
}
return rec;
}
/****************************************************************************
* 函式名稱:PackPCXLine(PPCXHEAD ppcxHdr, LPBYTE ppcxImg, LPBYTE ppcxBits) const
*
* 引數:PPCXHEAD ppcxHdr -指向PCXHEAD結構的指標!NULL,匯入BitPlane,BytePerLine,=>clScanLineSize
* LPBYTE ppcxBits -指向DIB資料區的指標,按掃描行(scanline)長度遞增
* LPBYTE ppcxImg -指向PCX圖象區指標!NULL,RLE壓縮編碼。
* 呼叫之前宣告: LPBYTE ppcxImg=new BYTE[2*BitPlane*BytePerLine]
*
* 返回:UINT rec -返回每行壓縮以後的位元組數目
*
* 說明:根據DIB圖象資料指標,進行RLE編碼(經過測試演算法很完善,支援256和24bit真彩色)
****************************************************************************/
UINT CPcxImage::PackPCXLine(PPCXHEAD ppcxHdr, LPBYTE ppcxBits, LPBYTE ppcxImg) const
{
//----------------------------------------
// RLE壓縮
ASSERT(ppcxHdr!=NULL && ppcxBits!=NULL && ppcxImg!=NULL);
BYTE i(1);
UINT lPos(0), rec(0);
// ☆RLE編碼,最大重複<=63☆
for(int bp=ppcxHdr->BitPlane-1; bp>=0; bp--)
{
lPos=0; // 處理到的RGB序列
while(lPos
{
i=1; // 重置步長-1
//----------------->以下程式碼檢查
while((ppcxBits[(i-1+lPos)*ppcxHdr->BitPlane+bp]==ppcxBits[(i+lPos)*ppcxHdr->BitPlane+bp])
&&((lPos+i)
if(i>1 && i<64)
{
// 表明當前象素位置開始存在i個重複象素值,依次寫入PCX圖象資料Buffer
// 1.重複次數
ppcxImg[rec++]=i|0xc0;
// 2.象素值
ppcxImg[rec++]=ppcxBits[lPos*ppcxHdr->BitPlane+bp];
lPos+=i; // lPos-記錄當前掃描行中已經處理的位元組數
// rec -記錄當前已經寫入PCX檔案的位元組數
}
else
{
// 表明當前象素位置開始不存在重複象素值
// 象素值大於0xc0(192),寫標誌0xc1
if((ppcxBits[lPos*ppcxHdr->BitPlane+bp]&0xc0)==0xc0) ppcxImg[rec++]=0xc1;
ppcxImg[rec++]=ppcxBits[lPos*ppcxHdr->BitPlane+bp]; lPos++;
}
}
}
// 寫圖象資料結束
return rec;
}
===========================================================
呼叫如下:
1.// RLE解碼-------------> 已經包含8、24bit圖象
for( int iY=0; iY<=ppcxHdr->YMax; iY++ )
{
ZeroMemory(ppcxBits, clScanLineSize);
ppcxImg+=LoadPCXLine(ppcxHdr, ppcxImg, ppcxBits); // 讀取掃描行資料
ppcxBits+=clScanLineSize;
}
ppcxHdr是指向PCXHEAD結構(128BYTE)的指標,ppcxBits是存放解碼後圖象資料的buffer,ppcxImg是指向pcx圖象檔案
中圖象資料的指標,此處隨掃描行遞增。完成功能是從pcx檔案中解碼圖象資料到windows點陣圖格式的圖象資料。
2.// RLE壓縮-------------> 已經包含8、24bit圖象
// 最壞情況下申請2倍的緩衝,相鄰都不重複,並且都大於0xc0
LPBYTE ppcxImg=new BYTE[2*pcxHdr.BitPlane*pcxHdr.BytePerLine]; // 存放臨時掃描行
UINT rec(0); // 計數器,寫如PCX檔案位元組數
for( int iY=0; iY<=pcxHdr.YMax; iY++ )
{
ZeroMemory(ppcxImg,2*pcxHdr.BitPlane*pcxHdr.BytePerLine);
rec=PackPCXLine(&pcxHdr, ppcxBits, ppcxImg);
// DIB 掃描行遞增
ppcxBits+=clScanLineSize;
pFile->Write(ppcxImg,rec);
}
delete []ppcxImg;
具體引數大致同1.ppcxImg為臨時RLE壓縮後的buffer。
------【OVER】------
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-992665/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 檔案的讀寫
- 08 常用:寫入 讀取檔案格式為:alex|123
- Json檔案轉換為Excel檔案!涉及讀檔案,時間戳轉化,寫文件JSONExcel時間戳
- 如何在PL/SQL中讀寫檔案(轉)SQL
- 普通檔案的讀寫
- chm檔案怎麼轉換成TXT格式?chm檔案快速轉化成TXT格式的方法
- 檔案排版(文字檔案讀寫)
- Python中的檔案讀寫Python
- Golang 讀、寫檔案Golang
- Python 讀寫檔案Python
- Python——檔案讀寫Python
- keras讀寫檔案Keras
- 「Python」:檔案讀寫Python
- plist檔案格式轉換器
- 三維模型檔案格式解讀模型
- python config配置檔案的讀寫Python
- python讀寫excel檔案PythonExcel
- C++讀寫檔案C++
- python檔案讀寫操作Python
- C++檔案讀寫C++
- csv格式怎麼轉換成excel?csv格式轉換成excel格式檔案的方法Excel
- 如何將檔案PDF格式轉換成Word格式
- VBA建立文字檔案、讀寫文字檔案
- PDF檔案如何轉成markdown格式
- Python中的檔案的讀寫操作Python
- Python中檔案的讀寫、寫讀和追加寫讀三種模式的特點Python模式
- ofd檔案如何轉換成pdf格式 電腦上ofd檔案如何轉換成pdf格式
- 如何給視訊格式的檔案進行格式轉換 可以轉為音訊格式嗎?音訊
- 3D列印CLI檔案格式的讀取3D
- caj檔案怎麼轉換成word文件,簡單的檔案格式轉換教程
- Python中讀寫Parquet檔案的方法Python
- csv檔案的寫入和讀取
- 讀取檔案流並寫入檔案流
- Python:讀寫檔案(I/O) | 組織檔案Python
- ofd檔案如何轉換成pdf格式 電腦ofd檔案如何免費轉換為pdf格式
- JAVA中GBK格式檔案和UTF-8格式檔案互相轉換Java
- nodejs xmlreader 讀寫xml檔案NodeJSXML
- C++檔案讀寫操作C++
- Golang對檔案讀寫操作Golang