📄 winpic.cpp
字号:
// WinPic.cpp: implementation of the CWinPic class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "LCYImageProcess.h"
#include "WinPic.h"
#include "SuoFangDlg.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CWinPic::CWinPic()
{
m_ImageData = NULL;
m_BmpFile = NULL;
m_BiWidth = 0;
m_BiHeight = 0;
}
CWinPic::~CWinPic()
{
delete[] m_ImageData;
delete m_BmpFile;
}
//打开BMP文件
int CWinPic::OpenFile(CString filepath)
{
m_BmpFile=new CFile;
if(!(m_BmpFile->Open(filepath,CFile::modeRead)))
{
return FILE_OPEN_FAILED;
}
m_BmpFile->SeekToBegin();
m_BmpFile->Read(&m_FileHeader,sizeof(m_FileHeader));
char* IsBmp;
IsBmp=(char*)&(m_FileHeader.bfType);
//如果不是BMP文件,或文件有错误
if(IsBmp[0]!='B'||IsBmp[1]!='M'||m_FileHeader.bfSize!=m_BmpFile->GetLength())
{
return FILE_ERROR;
}
return INIT_SUCCESS;
}
RGBCOLOR* CWinPic::LoadImageData()
{
if(!m_BmpFile)
{
return NULL;
}
m_BmpFile->SeekToBegin();
m_BmpFile->Read(&m_FileHeader,sizeof(m_FileHeader));
m_BmpFile->Read(&m_InfoHeader,sizeof(m_InfoHeader));
//得到图象的宽度,高度和位深度
m_BiWidth=m_InfoHeader.biWidth;
m_BiHeight=m_InfoHeader.biHeight;
m_BibitCount=m_InfoHeader.biBitCount;
//为图象数据指针分配空间
m_ImageData=(RGBCOLOR*)(new BYTE[m_BiWidth*m_BiHeight*3*10*10]);
//读取图象数据
switch(m_BibitCount)
{
case 1:
if(ReadImageData_1())
{
return m_ImageData;
}
else
{
return NULL;
}
case 4:
if(ReadImageData_4())
{
return m_ImageData;
}
else
{
return NULL;
}
case 8:
if(ReadImageData_8())
{
return m_ImageData;
}
else
{
return NULL;
}
case 16:
if(ReadImageData_16())
{
return m_ImageData;
}
else
{
return NULL;
}
case 24:
if(ReadImageData_24())
{
return m_ImageData;
}
else
{
return NULL;
}
default:
return NULL;
}
}
/*////////////////////////
从深度为1的位图中获得每个象素点的RGB值
成功返回TRUE,失败返回FALSE
/////////////////////////*/
bool CWinPic::ReadImageData_1()
{
//读取调色板2个
RGBCOLOR* palette=new RGBCOLOR[2];
m_BmpFile->Seek(54,CFile::begin);//Move the file pointer 54 bytes forward from the beginning of the file.
m_BmpFile->Read(&palette[0].rgbBlue,1);//1-The maximum number of bytes to be read from the file
m_BmpFile->Read(&palette[0].rgbGreen,1);
m_BmpFile->Read(&palette[0].rgbRed,1);
m_BmpFile->Seek(1,CFile::current); //1- Move the file pointer 1 bytes from the current position in the file
m_BmpFile->Read(&palette[1].rgbBlue,1);
m_BmpFile->Read(&palette[1].rgbGreen,1);
m_BmpFile->Read(&palette[1].rgbRed,1);
//读取位图数据
m_BmpFile->Seek(m_FileHeader.bfOffBits,CFile::begin);
int width=m_BiWidth/8;
if(m_BiWidth%8)
{
width++;
}
BYTE* data=new BYTE[width*m_BiHeight];
for(int i=0;i<m_BiHeight;i++)
{
m_BmpFile->Read(&data[(m_BiHeight-i-1)*width],width);//width-The maximum number of bytes to be read from the file
////如果存储图象每行象素的字节数不是4的倍数,每次读一行位图数据后要越过空白字符
if(width%4)
{
m_BmpFile->Seek(4-width%4,CFile::current);
}
}
//由位图数据和调色板获得每个象素点的RGB值
for(i=0;i<m_BiHeight;i++)
{
int j=i*width;
int n=0;
for(int k=0;k<m_BiWidth;k++)
{
if(n==8)
{
n=0;
j++;
}
BYTE temp;
temp=data[j]&(0x80 >> n);
n++;
//位图数据错误
if(m_InfoHeader.biClrUsed==1&&temp!=0)
{
delete[] data;
delete[] palette;
return false;
}
RGBCOLOR* p=m_ImageData;
if(temp)
{
p[i*m_BiWidth+k].rgbBlue=palette[1].rgbBlue;
p[i*m_BiWidth+k].rgbGreen=palette[1].rgbGreen;
p[i*m_BiWidth+k].rgbRed=palette[1].rgbRed;
}
else
{
p[i*m_BiWidth+k].rgbBlue=palette[0].rgbBlue;
p[i*m_BiWidth+k].rgbGreen=palette[0].rgbGreen;
p[i*m_BiWidth+k].rgbRed=palette[0].rgbRed;
}
}
}
delete[] data;
delete[] palette;
return true;
}
/*////////////////////////
从深度为4的位图中获得每个象素点的RGB值
成功返回TRUE,失败返回FALSE
/////////////////////////*/
bool CWinPic::ReadImageData_4()
{
//读取调色板16个//
RGBCOLOR* palette=new RGBCOLOR[16];
m_BmpFile->Seek(54,CFile::begin);
for(int i=0;i<16;i++)
{
m_BmpFile->Read(&palette[i].rgbBlue,1);
m_BmpFile->Read(&palette[i].rgbGreen,1);
m_BmpFile->Read(&palette[i].rgbRed,1);
m_BmpFile->Seek(1,CFile::current);
}
//读取位图数据
m_BmpFile->Seek(m_FileHeader.bfOffBits,CFile::begin);
int width=m_BiWidth/2+m_BiWidth%2;
BYTE* data=new BYTE[width*m_BiHeight];
for(i=0;i<m_BiHeight;i++)
{
m_BmpFile->Read(&data[(m_BiHeight-i-1)*width],width);
if(width%4)
{
////如果存储图象每行象素的字节数不是4的倍数,每次读一行位图数据后要越过空白字符
m_BmpFile->Seek(4-width%4,CFile::current);
}
}
//由位图数据和调色板获得每个象素点的RGB值
for(i=0;i<m_BiHeight;i++)
{
int j=i*width;
for(int k=0;k<m_BiWidth;k++)
{
BYTE temp;
if(k%2)
{
temp = data[j++] << 4;
temp = temp >> 4;
}
else
{
temp = data[j] >> 4;
}
if(m_InfoHeader.biClrUsed && temp>m_InfoHeader.biClrUsed)
{
delete[] data;
delete[] palette;
return false; //位图数据错误
}
m_ImageData[i*m_BiWidth+k].rgbBlue=palette[temp].rgbBlue;
m_ImageData[i*m_BiWidth+k].rgbGreen=palette[temp].rgbGreen;
m_ImageData[i*m_BiWidth+k].rgbRed=palette[temp].rgbRed;
}
}
delete[] data;
delete[] palette;
return true;
}
bool CWinPic::ReadImageData_8()
{
//读取调色板
RGBCOLOR *palette = new RGBCOLOR[256];
m_BmpFile->Seek(54, CFile::begin);
for(int i=0; i<256; i++)
{
m_BmpFile->Read(&palette[i].rgbBlue, 1);
m_BmpFile->Read(&palette[i].rgbGreen, 1);
m_BmpFile->Read(&palette[i].rgbRed, 1);
m_BmpFile->Seek(1, CFile::current);
}
//读取位图数据
m_BmpFile->Seek(m_FileHeader.bfOffBits, CFile::begin);
BYTE *data = new BYTE[m_BiHeight*m_BiWidth];
for(i=0; i<m_BiHeight; i++)
{
m_BmpFile->Read(&data[(m_BiHeight-i-1)*m_BiWidth], m_BiWidth);
//如果图象宽度不是4的倍数,每次读一行位图数据后要越过空白字符
if(m_BiWidth%4)
m_BmpFile->Seek(4-m_BiWidth%4, CFile::current);
}
//由位图数据查位图颜色表,获得每个象素点颜色的R,G,B分量
for(LONG j=0; j<m_BiHeight*m_BiWidth; j++)
{
if(m_InfoHeader.biClrUsed && data[j]>m_InfoHeader.biClrUsed)
{
delete[] data;
delete[] palette;
return false; //位图数据错误
}
m_ImageData[j].rgbBlue = palette[data[j]].rgbBlue;
m_ImageData[j].rgbGreen = palette[data[j]].rgbGreen;
m_ImageData[j].rgbRed = palette[data[j]].rgbRed;
}
delete[] data;
delete[] palette;
return true;
}
/*/////////////////////////////////////////
从位深度为16的位图中获得每个象素点
的RGB值,成功返回true,失败返回false
/////////////////////////////////////////*/
bool CWinPic::ReadImageData_16()
{
m_BmpFile->Seek(m_FileHeader.bfOffBits, CFile::begin);
WORD temp;
for(int i=m_BiHeight-1; i>=0; i--)
{
for(int j=0; j<m_BiWidth; j++)
{
m_BmpFile->Read(&temp, 2);
m_ImageData[i*m_BiWidth+j].rgbRed = temp >> 10;
m_ImageData[i*m_BiWidth+j].rgbGreen = (temp & 0x03E0) >> 5;
m_ImageData[i*m_BiWidth+j].rgbBlue = (temp & 0x001F);
m_ImageData[i*m_BiWidth+j].rgbRed *= 8;
m_ImageData[i*m_BiWidth+j].rgbGreen *= 8;
m_ImageData[i*m_BiWidth+j].rgbBlue *= 8;
}
//如果图象宽度不是4的倍数,每次读一行位图数据后要越过空白字符
if((m_BiWidth*2)%4)
{
m_BmpFile->Seek(4-(m_BiWidth*2)%4, CFile::current);
}
}
return true;
}
/*/////////////////////////////////////////
从位深度为24的位图中获得每个象素点
的RGB值,成功返回true,失败返回false
/////////////////////////////////////////*/
bool CWinPic::ReadImageData_24()
{
m_BmpFile->Seek(m_FileHeader.bfOffBits, CFile::begin);
for(int i=m_BiHeight-1; i>=0; i--)
{
for(int j=0; j<m_BiWidth; j++)
{
m_BmpFile->Read(&(m_ImageData[i*m_BiWidth+j].rgbBlue), 1);
m_BmpFile->Read(&(m_ImageData[i*m_BiWidth+j].rgbGreen), 1);
m_BmpFile->Read(&(m_ImageData[i*m_BiWidth+j].rgbRed), 1);
}
//如果存储图象每行象素的字节数不是4的倍数,每次读一行位图数据后要越过空白字符
if((m_BiWidth*3)%4)
m_BmpFile->Seek(4-(m_BiWidth*3)%4, CFile::current);
}
return true;
}
//图象按比例缩放
void CWinPic::SuoFang(float zoom)
{
long x_old,y_old,x_new,y_new;
float num=(float)1.0/zoom;
long w_old=m_BiWidth;
long h_old=m_BiHeight;
long w_new=(long) (w_old*zoom);
long h_new=(long) (h_old*zoom);
RGBCOLOR* rgb=(RGBCOLOR*)new BYTE[w_new*h_new*3];
for(y_new=0;y_new<h_new;y_new++)
{
for(x_new=0;x_new<w_new;x_new++)
{
x_old=(long)(x_new*num);
y_old=(long)(y_new*num);
if((x_old>=0) && (x_old<w_old) && (y_old>=0) && (y_old<h_old))
{
//rgb[(h_new-y_new-1)*w_new+x_new].rgbRed=m_imageData[(h_old-y_old-1)*w_old+x_old].rgbRed;
// rgb[(h_new-y_new-1)*w_new+x_new].rgbGreen=m_imageData[(h_old-y_old-1)*w_old+x_old].rgbGreen;
// rgb[(h_new-y_new-1)*w_new+x_new].rgbBlue=m_imageData[(h_old-y_old-1)*w_old+x_old].rgbBlue;
rgb[y_new*w_new+x_new].rgbRed=m_ImageData[y_old*w_old+x_old].rgbRed;
rgb[y_new*w_new+x_new].rgbGreen=m_ImageData[y_old*w_old+x_old].rgbGreen;
rgb[y_new*w_new+x_new].rgbBlue=m_ImageData[y_old*w_old+x_old].rgbBlue;
}
}
}
for(int i=0;i<w_new*h_new;i++)
{
m_ImageData[i].rgbRed=rgb[i].rgbRed;
m_ImageData[i].rgbGreen=rgb[i].rgbGreen;
m_ImageData[i].rgbBlue=rgb[i].rgbBlue;
}
m_BiWidth=w_new;
m_BiHeight=h_new;
delete[] rgb;
}
//图象不按比例缩放
void CWinPic::SuoFang1(float zoom1,float zoom2)
{
long x_old,y_old,x_new,y_new;
//得到新旧图象的转换系数
float num1=(float)1.0/zoom1;
float num2=(float)1.0/zoom2;
long w_old=m_BiWidth;
long h_old=m_BiHeight;
//新图象的高宽
long w_new=(long) (w_old*zoom1);
long h_new=(long) (h_old*zoom2);
//分配存储新图象的临时空间
RGBCOLOR* rgb=(RGBCOLOR*)new BYTE[w_new*h_new*3];
for(y_new=0;y_new<h_new;y_new++)
{
for(x_new=0;x_new<w_new;x_new++)
{
x_old=(long)(x_new*num1);
y_old=(long)(y_new*num2);
if((x_old>=0) && (x_old<w_old) && (y_old>=0) && (y_old<h_old))
{
rgb[y_new*w_new+x_new].rgbRed=m_ImageData[y_old*w_old+x_old].rgbRed;
rgb[y_new*w_new+x_new].rgbGreen=m_ImageData[y_old*w_old+x_old].rgbGreen;
rgb[y_new*w_new+x_new].rgbBlue=m_ImageData[y_old*w_old+x_old].rgbBlue;
}
}
}
for(int i=0;i<w_new*h_new;i++)
{
m_ImageData[i].rgbRed=rgb[i].rgbRed;
m_ImageData[i].rgbGreen=rgb[i].rgbGreen;
m_ImageData[i].rgbBlue=rgb[i].rgbBlue;
}
m_BiWidth=w_new;
m_BiHeight=h_new;
//删除临时空间
delete[] rgb;
}
//图象平移
void CWinPic::Move(long xoff, long yoff)
{
//原图象的高,宽
long width=m_BiWidth;
long height=m_BiHeight;
//新图象的高宽
long width_new=width+xoff;
long height_new=height+yoff;
long x0,y0,x1,y1;
//分配存储新图象数据的临时空间
RGBCOLOR* temp=(RGBCOLOR*)new BYTE[width_new*height_new*3];
for(y1=0;y1<height_new;y1++)
{
for(x1=0;x1<width_new;x1++)
{
x0=x1-xoff;
y0=y1-yoff;
//将原图象数据复制到新图象
if((y0>=0) && (y0<height) && (x0>=0) && (x0<width))
{
temp[y1*width_new+x1].rgbRed=m_ImageData[y0*width+x0].rgbRed;
temp[y1*width_new+x1].rgbGreen=m_ImageData[y0*width+x0].rgbGreen;
temp[y1*width_new+x1].rgbBlue=m_ImageData[y0*width+x0].rgbBlue;
}
//对于原图象中没有的数据,直接赋值
else
{
temp[y1*width_new+x1].rgbRed=255;
temp[y1*width_new+x1].rgbGreen=255;
temp[y1*width_new+x1].rgbBlue=255;
}
}
}
m_BiWidth=width_new;
m_BiHeight=height_new;
//存储新图象的数据
for(int i=0;i<width_new*height_new;i++)
{
m_ImageData[i].rgbRed=temp[i].rgbRed;
m_ImageData[i].rgbGreen=temp[i].rgbGreen;
m_ImageData[i].rgbBlue=temp[i].rgbBlue;
}
//删除临时空间
delete[] temp;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -