⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 image.cpp

📁 本压缩软件有vc++图象处理编程的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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 + -