一种二值图象无损压缩算法
南京理工大学电光学院
【摘 要】利用稀疏矩阵和差分编码对二色图像进行压缩保存
源代码在线查看: j.cpp
/********************************************************************
Created: 2006/12/09 12:32
FileName: BMP.cpp
Author: Jar 包杰
Purpose: 将24位BMP二色图像文件压缩
*********************************************************************/
#include "stdafx.h"
#include "J.h"
// 声明串行化过程
IMPLEMENT_SERIAL(CJ, CObject, 0);
CJ::CJ()
{
JFileName = "";
m_pBMFH = NULL;
m_pBMIH = NULL;
m_pBits = NULL;
m_pJFH = NULL;
}
CJ::~CJ()
{
if (m_pBMFH != NULL)
{
delete m_pBMFH;
m_pBMFH = NULL;
}
if (m_pBMIH != NULL)
{
delete m_pBMIH;
m_pBMIH = NULL;
}
if(m_pBits != NULL)
{
m_pBits = NULL;
}
if(m_pJFH != NULL)
{
m_pJFH = NULL;
}
}
/*************************************************
Function: Read
Description: 读取BMP图像
Input: CFile *pFile
Output:
Return: BOOL 成功返回TRUE,否则返回FALSE
Others: 读取BMP文件头、信息头和图像数据
*************************************************/
BOOL CJ::BMPRead(CFile *pFile)
{
int nSize = sizeof(BITMAPFILEHEADER);
m_pBMFH = (LPBITMAPFILEHEADER) new BYTE[nSize];
//创建J文件头
nSize = sizeof(JFILEHEADER);
m_pJFH = (LPJFILEHEADER) new BYTE[nSize];
//读取文件头
pFile->Read(m_pBMFH, sizeof(BITMAPFILEHEADER));
// 判断是否是BMP格式的位图
if(m_pBMFH->bfType != BMP_HEADER_MARKER)
return FALSE;
nSize = sizeof(BITMAPINFOHEADER);
m_pBMIH = (LPBITMAPINFOHEADER) new BYTE[nSize];
//生成.J文件名
JFileName=pFile->GetFileName()+".j01";
//读取信息头
pFile->Read(m_pBMIH, sizeof(BITMAPINFOHEADER));
//非24位图像打开失败
if (m_pBMIH->biBitCount != 24)
return FALSE;
//读取图象数据
m_pBits = (LPBYTE) new BYTE[m_pBMIH->biSizeImage];
pFile->Read(m_pBits, m_pBMIH->biSizeImage);
return TRUE;
}
/*************************************************
Function: JWrite
Description: 压缩BMP图像
Input: *pDC
Output:
Return: BOOL 成功返回TRUE,否则返回FALSE
Others: 第一次扫描将BMP图像转换成二值矩阵,只含'0''1'
*************************************************/
bool CJ::JWrite(CDC *pDC)
{
int i,j;
BYTE *DivH,*DivMatrix;
DivMatrix = new BYTE[m_pBMIH->biHeight*m_pBMIH->biWidth]; //二值矩阵
LPBYTE BitsH = m_pBits;
DivH = DivMatrix; //标记数据区开始,防止刷新时越界
m_pJFH->JType = J_HEADER_MARKER;
m_pJFH->JHeight = (WORD)m_pBMIH->biHeight;
m_pJFH->JWidth = (WORD)m_pBMIH->biWidth;
for (i = 0;i m_pJFH->FirstColor[i] = *(m_pBits+i);
//转换成二值矩阵
for (i = 0;ibiHeight;i++)
{
for (j = 0;jbiWidth;j++)
{
BYTE tmp = *m_pBits++;
m_pBits++;m_pBits++;
if (tmp != m_pJFH->FirstColor[0])
{
*DivMatrix++ = 1;
pDC->SetPixel(j,m_pBMIH->biHeight-i,RGB(0,0,0));
}
else
{
*DivMatrix++ = 0;
pDC->SetPixel(j,m_pBMIH->biHeight-i,RGB(255,255,255));
}
}
m_pBits = m_pBits+m_pBMIH->biWidth%4;
}
m_pBits = BitsH;
DivMatrix = DivH;
CFile JFile;
JFile.Open(JFileName,CFile::modeCreate|CFile::modeReadWrite);
JFile.Write(m_pJFH,sizeof(JFILEHEADER));
for (i = 0;ibiHeight;i++)
{
for (j = 0;jbiWidth;j++)
{
JFile.Write(DivMatrix++,1);
}
}
JFile.Close();
return TRUE;
}
//串行化
void CJ::Serialize(CArchive &ar)
{
BMPRead(ar.GetFile());
}
//获取文件头指针
LPJFILEHEADER CJ::GetJFH()
{
return m_pJFH;
}