📄 image.cpp
字号:
// Image.cpp: implementation of the CImage class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "cvc.h"
#include "math.h"
#include "malloc.h"
#include "Image.h"
#include "windowsx.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
void CImage::FormatImage()
{
m_image = NULL;
m_imageheader = NULL;
m_bytesperline = 0;
m_bytesperpixel = 0;
}
void CImage::Free()
{
if(m_image != NULL)
GlobalFreePtr( m_image );
if(m_imageheader != NULL)
GlobalFreePtr( m_imageheader);
FormatImage();
}
CImage::CImage()
{
FormatImage(); /* 置0所有的数据成员 */
}
CImage::~CImage()
{
Free();
}
inline RECT CImage::GetRect() const
{
RECT rcDib={0,0,GetWidth(),GetHeight()};
return rcDib;
}
BOOL CImage::LoadFromFile(LPCTSTR lpszFileName)
{
// 1、打开文件
CFile file;
CFileException e;
if ( !file.Open(lpszFileName,CFile::modeRead,&e) )
{
// 打开文件失败
char strErr[1024]="";
e.GetErrorMessage(strErr,1024);
TRACE0(strErr);
e.Delete();
return FALSE;
}
// 2、释放已持有位图资源
Free();
// 3、设置装载成功与否标记;结构化装载位图并设置数据项
char szErrMsg[1024]="";
BOOL bLoadFlag = FALSE;
try
{
// a) 读取文件头信息
BITMAPFILEHEADER bfh;
if (file.Read((LPSTR)&bfh, sizeof(BITMAPFILEHEADER)) != sizeof(BITMAPFILEHEADER)){
strcpy(szErrMsg,"读取文件头时出错。\n");
AfxThrowResourceException();
}
if (bfh.bfType != IMAGE_HEADER_MARKER){
strcpy(szErrMsg,"这不是一个IMAGE位图文件。\n");
AfxThrowResourceException();
}
// b) 分配空间、读取信息头
UINT nBIHSize = bfh.bfOffBits - sizeof(BITMAPFILEHEADER);
m_imageheader = (LPBITMAPINFO)GlobalAllocPtr( GHND,nBIHSize /*+ 256*sizeof(RGBQUAD) */);
if (0 == m_imageheader)
{
strcpy(szErrMsg,"分配空间失败!\n");
AfxThrowResourceException();
}
if (file.Read(m_imageheader,nBIHSize) != nBIHSize)
{
strcpy(szErrMsg,"读取位图信息头时出错。\n");
AfxThrowResourceException();
}
if (m_imageheader->bmiHeader.biSize != sizeof(BITMAPINFOHEADER))
{
strcpy(szErrMsg,"这不是一个Windows IMAGE\n");
AfxThrowResourceException();
}
// c) 分配空间、读取象素矩阵
DWORD dwImgSize = file.GetLength() - bfh.bfOffBits;
m_image = (LPBYTE)GlobalAllocPtr(GHND,dwImgSize);
if (0 == m_image)
{
strcpy(szErrMsg,"分配空间失败!\n");
AfxThrowResourceException();
}
if (file.ReadHuge(m_image,dwImgSize) != dwImgSize)
{
strcpy(szErrMsg,"读取象素矩阵失败!\n");
AfxThrowResourceException();
}
// e) 到此,读入成功,填写其他成员
m_bytesperline = WIDTHBYTES(GetWidth()*m_imageheader->bmiHeader.biBitCount);
m_bytesperpixel = m_imageheader->bmiHeader.biBitCount>>3;
//MakeRMaskWord(m_dwReadMaskWord,(BYTE)m_imageheader->bmiHeader.biBitCount);
//MakeWMaskWord(m_dwWriteMaskWord,(BYTE)m_imageheader->bmiHeader.biBitCount);
// f) 调用 Flip(TRUE) 函数垂直翻转位图
//Flip( TRUE );
// g) 标记装载成功
bLoadFlag = TRUE;
}
catch (CException *e)
{
TRACE0( szErrMsg );
e->Delete();
Free();
bLoadFlag = FALSE; // 装载失败
}
// 第五步
file.Close();
return bLoadFlag;
}
COLOR CImage::GetPixelColor(LONG x,LONG y) const
{
if(IsValid())
return ((*(DWORD*)(m_image+m_bytesperline*x+y*m_bytesperpixel))&0x00ffffff);
else
return NULL;
}
void CImage::SetPixelColor(LONG x,LONG y,const COLOR color)
{
*(DWORD*)(m_image+m_bytesperline*x+y*m_bytesperpixel)&=0xff000000;
*(DWORD*)(m_image+m_bytesperline*x+y*m_bytesperpixel)|=color;
}
BYTE CImage::GetRedValue(LONG x,LONG y) const
{
COLOR allcolor;
allcolor=GetPixelColor(x,y);
BYTE colorvalue;
colorvalue=GetRValue(allcolor);
return colorvalue;
}
BYTE CImage::GetGreenValue(LONG x,LONG y) const
{
COLOR allcolor;
allcolor=GetPixelColor(x,y);
BYTE colorvalue;
colorvalue=GetGValue(allcolor);
return colorvalue;
}
BYTE CImage::GetBlueValue(LONG x,LONG y) const
{
COLOR allcolor;
allcolor=GetPixelColor(x,y);
BYTE colorvalue;
colorvalue=GetBValue(allcolor);
return colorvalue;
}
BOOL CImage::ShowImage(HDC hDC, LONG x, LONG y)
{
if (!IsValid() || !hDC)
return FALSE;
if (x < 0 || y < 0)
return FALSE;
// 源矩形
RECT rcDib = GetRect();
// 目标矩形
RECT rcDst = {x, y
, x + RECTWIDTH(&rcDib)
, y + RECTHEIGHT(&rcDib)};
return ::SetDIBitsToDevice(hDC, // hDC
rcDst.left, // XDest
rcDst.top, // YDest
RECTWIDTH(&rcDst), // nDestWidth
RECTHEIGHT(&rcDst), // nDestHeight
(&rcDib)->left, // XSrc 指左下角坐标
(int)GetHeight()- (&rcDib)->top - RECTHEIGHT(&rcDib),
0, // nStartScan
GetHeight(), // nNumScans
m_image, // lpBits
m_imageheader, // lpBitsInfo
DIB_RGB_COLORS); // iUsage=DIB_PAL_COLORS or DIB_RGB_COLORS
}
BOOL CImage::Save(LPCTSTR lpszFileName) const
{
if ( !IsValid() )
return FALSE;
CFile file;
if( !file.Open(lpszFileName
,CFile::modeWrite|CFile::modeCreate|CFile::shareDenyWrite) )
return FALSE;
BITMAPFILEHEADER bmfHdr;
// 位图的头两个字节一定是"BM"
bmfHdr.bfType = IMAGE_HEADER_MARKER;
DWORD dwDIBSize = *(LPDWORD)&m_imageheader->bmiHeader.biSize + NumColors()*sizeof(RGBQUAD);
// 计算未压缩位图图象大小
DWORD dwBmBitsSize;
dwBmBitsSize = m_bytesperline * m_imageheader->bmiHeader.biHeight; // 象素矩阵大小
dwDIBSize += dwBmBitsSize;
m_imageheader->bmiHeader.biSizeImage = dwBmBitsSize;
bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + m_imageheader->bmiHeader.biSize + NumColors()*sizeof(RGBQUAD);
// 写文件头
file.Write((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER));
// 写信息头
UINT bmiSize = sizeof(BITMAPINFO); //+ (NumColors()-1)*sizeof(RGBQUAD);
file.Write(m_imageheader, bmiSize);
// 写象素
file.WriteHuge(m_image, dwBmBitsSize);
file.Close();
return TRUE;
}
inline WORD CImage::NumColors() const
{
if(!IsValid())
{
return 0;
}
if(m_imageheader->bmiHeader.biClrUsed != 0)
{
return (WORD)m_imageheader->bmiHeader.biClrUsed;
}
switch(m_imageheader->bmiHeader.biBitCount){
case 1: return 2;
case 4: return 16;
case 8: return 256;
case 16:
case 24:
case 32: return 0;
default: TRACE0("无效的信息头\n"); return 0;
}
}
CImage& CImage::operator =(const CImage &dibSrc)//"="在CImage类中的重载
{
CImage &dibDst = *this; // 引入 dibDst 使源与目标更清楚
dibDst.Free(); // 清空目标DIB
try{
// 1、计算源图信息头大小;为目标图分配相应的空间
UINT nBmiSize = sizeof(BITMAPINFO) + dibSrc.NumColors()*sizeof(RGBQUAD);
dibDst.m_imageheader = (LPBITMAPINFO)GlobalAllocPtr(GHND,nBmiSize);
if (0 == dibDst.m_imageheader)
{
TRACE0("分配信息头空间失败\n");
AfxThrowResourceException();
}
memcpy( dibDst.m_imageheader,dibSrc.m_imageheader,nBmiSize );
// 2、计算源图象素矩阵大小;为目标图分配空间
DWORD dwImgSize = dibSrc.m_bytesperline * dibSrc.GetHeight();
dibDst.m_image = (LPBYTE)GlobalAllocPtr(GHND,dwImgSize);
if (0 == dibDst.m_image)
{
TRACE0("分配象素矩阵空间失败\n");
AfxThrowResourceException();
}
memcpy(dibDst.m_image,dibSrc.m_image,dwImgSize);
// 3、创建成功。填写其他数据成员
dibDst.m_bytesperline = dibSrc.m_bytesperline;
dibDst.m_bytesperpixel = dibSrc.m_bytesperpixel;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -