📄 membitmap.cpp
字号:
#include "stdafx.h"
#include "memory.h"
#include "memBitmap.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//以bit流形式组织数据,用于Jpeg解码
BitData::BitData()
{
flag=FALSE;
}
BitData::~BitData()
{
}
BitData::BitData(BYTE *buf,long int lenth)
//数据流初始化
{
if(!buf)return; //数据指针,以字节为单位
Data=buf;
BufLen=lenth;
BytePtr=0; //在数据中的偏移
BitPtr=0; //在当前字节的bit指针
step=1; //控制流指针前进的步长
flag=TRUE;
}
BOOL BitData::GetBit(int bits,BYTE& Value)
//从数据流中读取指定位的数据,不超过8位
{
if(BytePtr>BufLen)
{
AfxMessageBox("数据出界");
return FALSE;
}
if(bits>8)
{
AfxMessageBox("不能读取超过8位的数据");
return FALSE;
}
if(flag==FALSE)
{
AfxMessageBox("数据尚不合法");
return FALSE;
}
if(BitPtr+bits<8) //所读数据在本字节内
{
Value=*(Data+BytePtr);
Value<<=BitPtr;
Value>>=(8-bits);
BitPtr+=bits;
return TRUE;
}
else //所读数据超出本字节内
{
Value=*(Data+BytePtr);
BytePtr++;
Value<<=BitPtr;
Value>>=(8-bits);
BYTE temp=*(Data+BytePtr);
temp>>=(16-BitPtr-bits);
Value|=temp;
BitPtr=bits-(8-BitPtr);
return TRUE;
}
}
BOOL BitData::GetBit(BYTE& Value)
//从数据流中读出一bit
{
if(BytePtr>BufLen)
{
AfxMessageBox("数据出界");
return FALSE;
}
if(flag==FALSE)
{
AfxMessageBox("数据尚不合法");
return FALSE;
}
if(BitPtr==0)
{
step=1;
CurByte=*(Data+BytePtr);
if(CurByte==0xff)
{
BYTE nextByte=*(Data+BytePtr+1);
if(nextByte==0)
{
step=2;
}
else
{
AfxMessageBox("不合法的文件标志");
return FALSE;
}
}
}
Value=CurByte>>7;
if(BitPtr==7)
{
BitPtr=0;
BytePtr+=step;
CurByte<<=1;
}
else
{
BitPtr++;
CurByte<<=1;
}
return TRUE;
}
//***********************************************
//***********************************************
//内存位图类,从文件中读出数据,转变为24位位图格式
//可以支持Bmp的所有非压缩格式
//可以支持JFIF--Jpeg的简单的Baseline格式
memBitmap::memBitmap()
{
flag=0;
Scale=1.0f;
}
BOOL memBitmap::CreateDirect(int ImageWidth,int ImageHeight)
{
Release();
flag=0;
Scale=1.0f;
BytesPerLine=ImageWidth*3;
if(BytesPerLine%4!=0)BytesPerLine=(BytesPerLine/4+1)*4;
lenth=long(ImageHeight)*BytesPerLine;
bData=new BYTE[lenth+54L];
if(!bData)
{
AfxMessageBox("内存分配失败");
return FALSE;
}
flag=1;
bFileHeader=(LPBITMAPFILEHEADER)bData;
bInfoHeader=(LPBITMAPINFOHEADER)(bData+sizeof(BITMAPFILEHEADER));
bBMI=(LPBITMAPINFO)bInfoHeader;
bInfoHeader->biWidth=ImageWidth;
bInfoHeader->biHeight=ImageHeight;
bInfoHeader->biSize=40;
WORD bmptemp=(WORD)'M';
bmptemp<<=8;
bmptemp|=(BYTE)'B';
bFileHeader->bfType=bmptemp;
bFileHeader->bfOffBits=54;
bFileHeader->bfReserved1=0;
bFileHeader->bfReserved2=0;
bInfoHeader->biPlanes=1;
bInfoHeader->biBitCount=24;
bInfoHeader->biCompression=0;
bInfoHeader->biXPelsPerMeter=0;
bInfoHeader->biYPelsPerMeter=0;
bInfoHeader->biClrUsed=0;
bInfoHeader->biClrImportant=0;
bitData=bData+54;
bInfoHeader->biSizeImage=lenth;
bFileHeader->bfSize=lenth+54;
return TRUE;
}
memBitmap::memBitmap(int cx,int cy,class memBitmap &bm)
{
flag=0;
Scale=1.0f;
BytesPerLine=cx*3;
if(BytesPerLine%4!=0)BytesPerLine=(BytesPerLine/4+1)*4;
lenth=long(cy)*BytesPerLine;
bData=new BYTE[lenth+54L];
if(!bData)
{
AfxMessageBox("内存分配失败");
return ;
}
flag=1;
CopyMemory(bData,bm.bData,54);
bFileHeader=(LPBITMAPFILEHEADER)bData;
bInfoHeader=(LPBITMAPINFOHEADER)(bData+sizeof(BITMAPFILEHEADER));
bBMI=(LPBITMAPINFO)bInfoHeader;
bInfoHeader->biWidth=cx;
bInfoHeader->biHeight=cy;
bitData=bData+54;
bInfoHeader->biSizeImage=lenth;
bFileHeader->bfSize=lenth+54;
Scale=bm.GetScale();
}
BOOL memBitmap::Load(LPCTSTR filename)
{
CString str(filename,256);
if(str.Find(".bmp")!=-1)
{
CFile file;
CFileException e;
if(!file.Open(filename,CFile::modeRead,&e))
{
#ifdef _DEBUG
AfxMessageBox("文件打不开");
#endif
return FALSE;
}
file.Seek(0L,CFile::begin);
unsigned long int FileLenth;
BYTE *FileData;
FileLenth=file.GetLength();
lenth=FileLenth;
FileData=new BYTE[lenth];
bData=FileData;
if(!FileData)
{
AfxMessageBox("内存分配失败");
return FALSE;
}
if(!file.ReadHuge(FileData,FileLenth))
{
AfxMessageBox("读数据错");
return FALSE;
}
flag=1;
bFileHeader=(LPBITMAPFILEHEADER)FileData;
bInfoHeader=(LPBITMAPINFOHEADER)(FileData+sizeof(BITMAPFILEHEADER));
bBMI=(LPBITMAPINFO)bInfoHeader;
bitData=bData+54;
if(((unsigned char)bFileHeader->bfType!='B')||\
((unsigned char)(bFileHeader->bfType>>8)!='M') )
{
AfxMessageBox("不是合法的Bmp文件");
return FALSE;
}
file.Close();
// if(bInfoHeader->biBitCount!=24)
// {
// AfxMessageBox("本系统仅支持24位真彩图象,请自行转换格式");
// return FALSE;
// }
if(bInfoHeader->biCompression!=0)
{
AfxMessageBox("本系统仅支持未压缩图象");
return FALSE;
}
BytesPerLine=bInfoHeader->biWidth*(bInfoHeader->biBitCount/8);
if(BytesPerLine%4!=0)BytesPerLine=(BytesPerLine/4+1)*4;
if(bInfoHeader->biBitCount==24)return TRUE;
else if(bInfoHeader->biBitCount==8)
{
BYTE Palette[256][3];
BYTE *ImageData=bData+bFileHeader->bfOffBits;
int i,j;
for(i=0;i<256;i++)
{
for(j=0;j<3;j++)
{
Palette[i][j]=*(bitData+i*4+j);
}
}
int width=bInfoHeader->biWidth;
int height=bInfoHeader->biHeight;
int OldBytes=BytesPerLine;
flag=0;
CreateDirect(width,height);
for(j=0;j<height;j++)
{
for(i=0;i<width;i++)
{
BYTE Index=*(ImageData+j*OldBytes+i);
BYTE b=Palette[Index][0];
BYTE g=Palette[Index][1];
BYTE r=Palette[Index][2];
SetPixel(i,height-j-1,RGB(r,g,b));
}
}
flag=1;
delete FileData;
return TRUE;
}
else if(bInfoHeader->biBitCount==4)
{
BYTE Palette[16][3];
BYTE *ImageData=bData+bFileHeader->bfOffBits;
int i,j;
for(i=0;i<16;i++)
{
for(j=0;j<3;j++)
{
Palette[i][j]=*(bitData+i*4+j);
}
}
int width=bInfoHeader->biWidth;
int height=bInfoHeader->biHeight;
int OldBytes=(width+1)/2;
if(OldBytes%4!=0)OldBytes=(OldBytes/4+1)*4;
flag=0;
CreateDirect(width,height);
for(j=0;j<height;j++)
{
for(i=0;i<width;i++)
{
BYTE Index=*(ImageData+j*OldBytes+i/2);
if(i%2!=0)Index&=0xf;
else
{
Index>>=4;
Index&=0xf;
}
BYTE b=Palette[Index][0];
BYTE g=Palette[Index][1];
BYTE r=Palette[Index][2];
SetPixel(i,height-j-1,RGB(r,g,b));
}
}
flag=1;
delete FileData;
return TRUE;
}
else if(bInfoHeader->biBitCount==1)
{
BYTE Palette[2][3];
BYTE *ImageData=bData+bFileHeader->bfOffBits;
int i,j;
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
Palette[i][j]=*(bitData+i*4+j);
}
}
int width=bInfoHeader->biWidth;
int height=bInfoHeader->biHeight;
int OldBytes=(width+1)/8;
if(OldBytes%4!=0)OldBytes=(OldBytes/4+1)*4;
flag=0;
CreateDirect(width,height);
for(j=0;j<height;j++)
{
for(i=0;i<width;i++)
{
BYTE Index=*(ImageData+j*OldBytes+i/8);
Index>>=(7-i%8);
Index&=1;
BYTE b=Palette[Index][0];
BYTE g=Palette[Index][1];
BYTE r=Palette[Index][2];
SetPixel(i,height-j-1,RGB(r,g,b));
}
}
flag=1;
delete FileData;
return TRUE;
}
else
{
AfxMessageBox("非法的颜色数");
return FALSE;
}
}
else if(str.Find(".jpg")!=-1)
{
CFile file;
CFileException e;
if(!file.Open(filename,CFile::modeRead,&e))
{
#ifdef _DEBUG
AfxMessageBox("文件打不开");
#endif
return FALSE;
}
file.Seek(0L,CFile::begin);
JpegLenth=file.GetLength();
BYTE *buf=new BYTE[JpegLenth];
if(!buf)
{
AfxMessageBox("内存分配失败");
return FALSE;
}
if(!file.ReadHuge(buf,JpegLenth))
{
AfxMessageBox("读数据错");
return FALSE;
}
BOOL x=JpegToBmp(buf,JpegLenth);
delete buf;
file.Close();
if(!x)Release();
return x;
}
else
{
AfxMessageBox("不支持的格式");
return FALSE;
}
}
BOOL memBitmap::Save(LPCTSTR filename)
{
CString str(filename,256);
if(str.Find(".bmp")==-1)
{
AfxMessageBox("本系统仅支持Bmp格式的输出");
return FALSE;
}
CFile file;
CFileException e;
if(!file.Open(filename,CFile::modeCreate|CFile::modeWrite,&e))
{
#ifdef _DEBUG
AfxMessageBox("文件打不开");
#endif
return FALSE;
}
file.Seek(0L,CFile::begin);
if(flag==1)
{
file.Write(bData,lenth);
}
file.Close();
return TRUE;
}
void memBitmap::Display(int x,int y,CDC *dc)
{
StretchDIBits(dc->GetSafeHdc(),\
x,y,int(Scale*bInfoHeader->biWidth),int(Scale*bInfoHeader->biHeight),\
0,0,bInfoHeader->biWidth,bInfoHeader->biHeight,\
bitData,bBMI,DIB_RGB_COLORS,SRCCOPY);
}
void memBitmap::Display(int x,int y,int cx,int cy,CDC *dc)
{
StretchDIBits(dc->GetSafeHdc(),\
x,y,cx,cy,\
0,0,bInfoHeader->biWidth,bInfoHeader->biHeight,\
bitData,bBMI,DIB_RGB_COLORS,SRCCOPY);
}
memBitmap::~memBitmap()
{
if((flag==1)&&(bData))
delete bData;
flag=0;
}
int memBitmap::GetWidth()
{
return bInfoHeader->biWidth;
}
int memBitmap::GetHeight()
{
return bInfoHeader->biHeight;
}
void memBitmap::SetWidth(int w)
{
bInfoHeader->biWidth=w;
BytesPerLine=bInfoHeader->biWidth*3;
if(BytesPerLine%4!=0)BytesPerLine=(BytesPerLine/4+1)*4;
}
void memBitmap::SetHeight(int h)
{
bInfoHeader->biHeight=h;
}
int memBitmap::GetDispWidth()
{
return int(Scale*bInfoHeader->biWidth);
}
int memBitmap::GetDispHeight()
{
return int(Scale*bInfoHeader->biHeight);
}
COLORREF memBitmap::GetPixel(int x,int y)
{
if(flag==0)
{
AfxMessageBox("文件尚未成功读入");
return RGB(0,0,0);
}
if((x<0)||(x>=bInfoHeader->biWidth)||\
(y<0)||(y>=bInfoHeader->biHeight) )
{
AfxMessageBox("超出图象范围");
return RGB(0,0,0);
}
y=bInfoHeader->biHeight-y-1;
unsigned long temp=(long)y*(long)BytesPerLine+(long)x*3;
if(temp>=lenth)
{
AfxMessageBox("数据超出有效范围");
return RGB(0,0,0);
}
unsigned r,g,b;
b=*(bitData+temp);
g=*(bitData+temp+1);
r=*(bitData+temp+2);
return RGB(r,g,b);
}
void memBitmap::SetPixel(int x,int y,COLORREF color)
{
if(flag==0)
{
AfxMessageBox("文件尚未成功读入");
return;
}
if((x<0)||(x>=bInfoHeader->biWidth)||\
(y<0)||(y>=bInfoHeader->biHeight) )
{
AfxMessageBox("超出图象范围");
return;
}
y=bInfoHeader->biHeight-y-1;
unsigned long temp=(long)y*(long)BytesPerLine+(long)x*3;
if(temp>=lenth)
{
AfxMessageBox("数据超出有效范围");
return;
}
*(bitData+temp)=GetBValue(color);
*(bitData+temp+1)=GetGValue(color);
*(bitData+temp+2)=GetRValue(color);
}
void memBitmap::operator=(memBITMAP &bm)
{
if(flag==1)delete bData;
lenth=bm.lenth;
bData=new BYTE[lenth+54L];
if(!bData)
{
AfxMessageBox("内存分配失败");
return;
}
CopyMemory(bData,bm.bData,lenth+54L);
flag=1;
bFileHeader=(LPBITMAPFILEHEADER)bData;
bInfoHeader=(LPBITMAPINFOHEADER)(bData+sizeof(BITMAPFILEHEADER));
bBMI=(LPBITMAPINFO)bInfoHeader;
bitData=bData+54;
BytesPerLine=bm.BytesPerLine;
Scale=bm.GetScale();
}
void memBitmap::SetScale(int bl)
{
float table[10]={0.33f,0.50f,0.67f,\
1.0f,1.33f,1.5f,1.67f,\
2.0f,2.5f,3.0f,};
int CurBl=100;
for(int i=0;i<10;i++)
{
if(Scale==table[i])CurBl=i;
}
if(CurBl==100)
{
AfxMessageBox("错误的比例数据");
return ;
}
if(bl==-1)
{
if(CurBl>0)CurBl--;
}
else if(bl==1)
{
if(CurBl<9)CurBl++;
}
else return;
Scale=table[CurBl];
}
BOOL memBitmap::ChangeSize(int cx,int cy)
{
int width=GetWidth();
int height=GetHeight();
if( (cx==width)&&(cy==height))return FALSE;
double sx,sy; //x和y方向的比例系数
memBITMAP bmp1;
bmp1.CreateDirect(cx,cy);
sx=double(cx)/(double)width;
sy=double(cy)/(double)height;
int i,j;
for(i=0;i<cx;i++)
{
for(j=0;j<cy;j++)
{
double x,y;
x=(double)i/sx;
y=(double)j/sy;
if(x<=0)x=0;
if(x>=width-1)x=width-1;
if(y<=0)y=0;
if(y>=height-1)y=height-1;
if( ((int)x==0)||((int)x==width-1)||((int)y==0)||((int)y==height-1) )
{
COLORREF color=GetPixel((int)x,(int)y);
bmp1.SetPixel(i,j,color);
}
else
{
double r1,r2,r3,r4;
double g1,g2,g3,g4;
double b1,b2,b3,b4;
COLORREF c1,c2,c3,c4;
c1=GetPixel((int)x,(int)y);
c2=GetPixel((int)x+1,(int)y);
c3=GetPixel((int)x,(int)y+1);
c4=GetPixel((int)x+1,(int)y+1);
double dis1=x-(int)x;
double dis2=1-x+(int)x;
double dis3=y-(int)y;
double dis4=1-y+(int)y;
r1=GetRValue(c1);
g1=GetGValue(c1);
b1=GetBValue(c1);
r2=GetRValue(c2);
g2=GetGValue(c2);
b2=GetBValue(c2);
r3=GetRValue(c3);
g3=GetGValue(c3);
b3=GetBValue(c3);
r4=GetRValue(c4);
g4=GetGValue(c4);
b4=GetBValue(c4);
int r=int(dis4*(r1*dis2+r2*dis1)+dis3*(r3*dis2+r4*dis1));
if(r>255)r=255;
int g=int(dis4*(g1*dis2+g2*dis1)+dis3*(g3*dis2+g4*dis1));
if(g>255)g=255;
int b=int(dis4*(b1*dis2+b2*dis1)+dis3*(b3*dis2+b4*dis1));
if(b>255)b=255;
bmp1.SetPixel(i,j,RGB((BYTE)r,(BYTE)g,(BYTE)b));
// COLORREF color=GetPixel(int(x+0.5),int(y+0.5));
// bmp1.SetPixel(i,j,color);
}
}
}
Release();
CreateDirect(cx,cy);
for(i=0;i<cx;i++)
{
for(j=0;j<cy;j++)
{
COLORREF color=bmp1.GetPixel(i,j);
SetPixel(i,j,color);
}
}
bmp1.Release();
return TRUE;
}
void memBitmap::SetScale(float bl)
{
float table[10]={0.33f,0.50f,0.67f,\
1.0f,1.33f,1.5f,1.67f,\
2.0f,2.5f,3.0f,};
int CurBl=100;
for(int i=0;i<10;i++)
{
if(bl==table[i])CurBl=i;
}
if(CurBl==100)
{
AfxMessageBox("错误的比例数据");
return ;
}
Scale=table[CurBl];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -