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

📄 myimage.cpp

📁 电子监控的网络编程实例
💻 CPP
📖 第 1 页 / 共 4 页
字号:
// MyImage.cpp: implementation of the CMyImage class.
/********************************************************************************
//图像处理类--主要是图像读取显示保存
---没有处理调色板-对256以下图像绘制存在问题
// Written by: YiJian Feng
// Email: netfyee@hotmail.com
// Last Edit: 2003-9-5 
**********************************************************************************/

#include "stdafx.h"
#include "MyImage.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CMyImage::CMyImage()
{
	hImage = NULL;
	memset(&m_bih, 0, 40);
}
//根据HBITMAP(DDB位图)产生Image
CMyImage::CMyImage(HBITMAP hBitmap)
{
	memset(&m_bih, 0, 40);
	IMAGE_ERROR err = LoadDDB(hBitmap);
}

//根据HDIB(DIB位图)产生Image
CMyImage::CMyImage(HDIB hDib)
{
	memset(&m_bih, 0, 40);
	IMAGE_ERROR err = LoadDIB(hDib);
}

//根据 图像字节流 产生Image/
//其中iMode有三种方式 =0 包括BITMAPFILEHEADER+BITMAPINFOHEADER+图像字节;
//1包括BITMAPINFOHEADER+图像字节;
//2图像字节;但这时必须调用SetDibInfo()来设置位图信息;
CMyImage::CMyImage(PBYTE pImage, DWORD dwSize, int iMode)
{
	memset(&m_bih, 0, 40);
	IMAGE_ERROR err = LoadBuf(pImage, dwSize, iMode);
}

//根据 文件来 产生 Image
CMyImage::CMyImage(CString FileName)
{
	memset(&m_bih, 0, 40);
	IMAGE_ERROR err = LoadFile(FileName);
}

CMyImage::~CMyImage()
{
	DeleteObject();
}

//删除图像Image对象
IMAGE_ERROR CMyImage::DeleteObject()
{
	if(hImage)
	{
		GlobalFree(hImage);
		hImage = NULL;
	}
	return IMAGE_OK;
}

//是否是空对象
BOOL CMyImage::IsEmpty()
{
	if(hImage)
		return TRUE;
	else
		return FALSE;
}

IMAGE_ERROR CMyImage::CreateObject(DWORD dwSize)
{
	IMAGE_ERROR err = DeleteObject();
	if (err!=IMAGE_OK)
		return err;
	hImage = ::GlobalAlloc(GHND/*GMEM_FIXED*/, dwSize);
	if(hImage)
		return IMAGE_OK;
	else
		return IMAGE_ERR_CREATE;
}

//加载DDB位图
IMAGE_ERROR CMyImage::LoadDDB(HBITMAP hBitmap)
{
	BITMAP bitmap;
    WORD biBits;			// 象素位数
    UINT wLineLen;			// 行长度
    DWORD wColSize;			// 调色板大小
    DWORD dwSize;			// 文件长度 --=&&=--
	DWORD wImageSize;		// 图像大小

	PBYTE p1 = NULL; 
	
	// 计算位图文件每个像素所占字节数
	::GetObject(hBitmap, sizeof(BITMAP), &bitmap);
    
	biBits = (WORD)(bitmap.bmPlanes * bitmap.bmBitsPixel);
    wLineLen = WIDTHBYTES(bitmap.bmWidth * biBits);//(bitmap.bmWidth * biBits + 31 ) / 32 * 4;
    wColSize = sizeof(RGBQUAD) * (( biBits <= 8 ) ? 1 << biBits : 0 );
    dwSize = sizeof(BITMAPINFOHEADER) + wColSize + 
		(DWORD)(UINT)wLineLen * (DWORD)(UINT)bitmap.bmHeight;
	wImageSize = dwSize - sizeof(BITMAPINFOHEADER) - wColSize;
	
    if (biBits <= 1)
	{
		biBits = 1;
	}
    else if (biBits <= 4)
	{
		biBits = 4;
	}
    else if (biBits <= 8)
	{
		biBits = 8;
	}
    else
	{
		biBits = 24;
	}
	
	// 初始分配
	IMAGE_ERROR err = CreateObject(dwSize + sizeof(BITMAPFILEHEADER));
	if(err != IMAGE_OK)
		return err;
//	hglobal = ::GlobalAlloc(GHND, dwSize + 14);
//	m_hglobal = (HGLOBAL)::GlobalLock(hglobal);

	BITMAPINFOHEADER bih;
	BITMAPFILEHEADER bfh;
	
	// 建立文件头信息
	::memset(&bfh, 0, sizeof(BITMAPFILEHEADER));
	bfh.bfType = 'MB';
	bfh.bfSize = dwSize + sizeof(BITMAPFILEHEADER);
	bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
	p1 = (PBYTE)::GlobalLock(hImage);
	if (!p1)
		return IMAGE_ERR_LOCK;
	::memcpy(p1, &bfh, sizeof(BITMAPFILEHEADER));
	
	// 建立位图头信息
	::memset(&bih, 0, sizeof(BITMAPINFOHEADER));
    bih.biSize = sizeof(BITMAPINFOHEADER);
    bih.biWidth = bitmap.bmWidth;
    bih.biHeight = bitmap.bmHeight;
    bih.biPlanes = 1;
    bih.biBitCount = biBits;
    bih.biCompression = BI_RGB;
    bih.biSizeImage = wImageSize;
    bih.biXPelsPerMeter = 0;
    bih.biYPelsPerMeter = 0;
    bih.biClrUsed = ( biBits <= 8 ) ? 1 << biBits : 0;
    bih.biClrImportant = 0;
	::memcpy(p1 + sizeof(BITMAPINFOHEADER), &bih, sizeof(BITMAPINFOHEADER));

	//set dib
	memcpy(&m_bih, &bih, sizeof(BITMAPINFOHEADER));
	
	// 建立位图体信息
	::memcpy(p1 + bfh.bfOffBits, bitmap.bmBits, wImageSize);
	BOOL a = GlobalUnlock(hImage);
	/*win98下不需要判断
	if(!a)
	return IMAGE_ERR_UNLOCK;
	*/
	return IMAGE_OK;
}

//加载DDB位图
IMAGE_ERROR CMyImage::LoadDDB(CBitmap *pBitmap)
{
	return LoadDDB( (HBITMAP)(pBitmap->GetSafeHandle()) );
}

IMAGE_ERROR CMyImage::LoadDIB(HDIB hDib)
{
	LPBYTE lpdib;
	LPBITMAPINFOHEADER lpbih;
	BITMAPFILEHEADER bfh;
		
	// 计算位图信息
	lpdib =(LPBYTE)::GlobalLock(hDib);
	if( !lpdib )
		return IMAGE_ERR_LOCK;
	lpbih = (LPBITMAPINFOHEADER)lpdib;
	DWORD dwImageSize = lpbih->biSizeImage;

	// 建立文件头信息
	::memset(&bfh, 0, 14);
	bfh.bfType = 'MB';
	bfh.bfSize = dwImageSize + 54; // dwSize + 14;
	bfh.bfOffBits = 54;

	IMAGE_ERROR err = CreateObject(dwImageSize + 54);
	if(err != IMAGE_OK)
	{
		BOOL b = ::GlobalUnlock(hDib);
	/*win98下必须去除
	if(!b)
		return IMAGE_ERR_UNLOCK;
	*/
		return err;
	}
	PBYTE p1 = NULL;
	p1 = (PBYTE)::GlobalLock(hImage);
	if(!p1)
	{
		BOOL b = ::GlobalUnlock(hDib);
	/*win98下必须去除
	if(!b)
		return IMAGE_ERR_UNLOCK;
	*/
		return IMAGE_ERR_LOCK;
	}
	memcpy(p1, &bfh, 14);
	
	// 建立位图头并位图体信息
	memcpy(p1 + 14, lpdib, dwImageSize + 40);

	//set dib
	memcpy(&m_bih, lpbih, sizeof(BITMAPINFOHEADER));

	BOOL b = ::GlobalUnlock(hDib);
	/*win98下必须去除
	if(!b)
		return IMAGE_ERR_UNLOCK;
	*/
	
	// 解锁
	b = ::GlobalUnlock(hImage);
	/*win98下必须去除
	if(!b)
		return IMAGE_ERR_UNLOCK;
	*/
	return IMAGE_OK;
	
}
//获得图像尺寸
IMAGE_ERROR CMyImage::ImageSize(int& dwWidth, int &dwHeight)
{
	dwWidth = 0; dwHeight = 0;
	if(!hImage)
		return IMAGE_NULL;
	else
	{
		LPSTR			   lpDIBHdr;  // Pointer to BITMAPINFOHEADER
		LPBYTE			   lpImage = NULL;
		LPBITMAPINFOHEADER lpbmi;		// pointer to a Win 3.0-style DIB
		LPBITMAPCOREHEADER lpbmc;		// pointer to an other-style DIB
		// point to the header (whether old or Win 3.0
		lpImage  = (LPBYTE) ::GlobalLock(hImage);
		if (!lpImage)
			return IMAGE_ERR_LOCK;
		lpDIBHdr = LPSTR(lpImage + 14);
		lpbmi = (LPBITMAPINFOHEADER)lpDIBHdr;
		lpbmc = (LPBITMAPCOREHEADER)lpDIBHdr;
		// return the DIB height if it is a Win 3.0 DIB 
		if (IS_WIN30_DIB(lpDIBHdr))
		{
			dwHeight = lpbmi->biHeight;
			dwWidth  = lpbmi->biWidth;
		}
		else  // it is an other-style DIB, so return its height 
		{
			dwHeight = lpbmc->bcHeight;
			dwWidth = lpbmc->bcWidth;
		}
		BOOL b = ::GlobalUnlock(hImage);
			/*win98下必须去除
	if(!b)
		return IMAGE_ERR_UNLOCK;
	*/
		
	}
	return IMAGE_OK;

}

//从文件加载图像
IMAGE_ERROR CMyImage::LoadFile(CString FileName)
{
	ASSERT(!FileName.IsEmpty());
	IMAGE_ERROR err = IMAGE_OK;

	CFile file;
	CFileException fe;	
	if (!file.Open(FileName, CFile::modeRead | CFile::shareDenyNone , &fe))
	{
		//		MessageBox(NULL,"无法读取文件!","错误",MB_ICONSTOP);
		
		return IMAGE_ERR_FILENOTEXIST;
	}

	CString m_strName=FileName;
	CString m_strFileExt=FileName.Right(3);
	m_strFileExt.MakeUpper();
	if(m_strFileExt=="BMP")
	{
		TRY
		{
			err = LoadFile(file);
			if( err != IMAGE_OK )
			{
				file.Close();
				return err;
			}
		}
		CATCH (CFileException, eLoad)
		{
			file.Abort(); // will not throw an exception
			return IMAGE_ERR_READFILE;
		}
		END_CATCH
	}
	else if(m_strFileExt=="JPG")
	{
	//	file.Close();
		err = LoadJPG(FileName);
		if(err != IMAGE_OK)
			return err;
	}
	else
	{
		file.Close();
		return IMAGE_ERR_FILENOTEXIST;
	}
	
	file.Close();
	return IMAGE_OK;
}

//读位图BMP文件
IMAGE_ERROR CMyImage::LoadFile(CFile &file)
{
	BITMAPFILEHEADER bmfHeader;
	LPBITMAPINFOHEADER lpbmi=NULL;		// pointer to a Win 3.0-style DIB
	LPBITMAPINFO		lpbmifo=NULL;
	BITMAPINFO			BitmapInfo;
	LPBYTE pDIB=NULL;
	
	// Get length of DIB in bytes for use when reading
	DWORD m_dwBitsSize = file.GetLength()-sizeof(BITMAPFILEHEADER);
	
	// Go read the DIB file header and check if it's valid.
	if(file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))
		return IMAGE_ERR_READFILE;
	
	if (bmfHeader.bfType != DIB_HEADER_MARKER)
		return IMAGE_ERR_READFILE;
	
	if(file.Read((LPSTR)&BitmapInfo, sizeof(BitmapInfo)) != sizeof(BitmapInfo))
		return IMAGE_ERR_READFILE;

	//set dib
	memcpy(&m_bih, &(BitmapInfo.bmiHeader), sizeof(BITMAPINFOHEADER));
	
	if(BitmapInfo.bmiHeader.biBitCount!=24)
	{
		//		MessageBox(NULL,"读取图像文件错误,目前只支持24位真彩色图像。","读取图像文件错误",MB_OK|MB_ICONERROR);
		
		return IMAGE_ERR_RGB;
	}
	
	
	DWORD	dwWidth=BitmapInfo.bmiHeader.biWidth;
	DWORD	dwHeight=BitmapInfo.bmiHeader.biHeight;
	DWORD	dwWidthOfByte=WIDTHBYTES(dwWidth*24);
	
	DWORD	dwTemp=dwWidthOfByte*dwHeight+sizeof(BITMAPINFOHEADER);
	if(dwTemp>m_dwBitsSize)
		m_dwBitsSize=dwTemp;
	
	
	DWORD dwDibOffset=bmfHeader.bfOffBits;
	IMAGE_ERROR err = CreateObject(m_dwBitsSize + 14);
	if(err != IMAGE_OK)
	{
		return err;
	}
	// Allocate memory for DIB
//	m_hDIB = (HDIB)::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,m_dwBitsSize );
	//Allocate memory error
//	if (m_hDIB == NULL) return FALSE;
	PBYTE aa = NULL;
	aa =(PBYTE)::GlobalLock(hImage);
	if(!aa)
		return IMAGE_ERR_LOCK;
	memcpy(aa, &bmfHeader, 14);
//	memcpy(aa + 14, &(BitmapInfo->bmiHeader), 40);
	pDIB = aa + 14;
	//Point to BITMAPINFOHEADER structure 
	lpbmi=(LPBITMAPINFOHEADER)pDIB;
	lpbmifo=(LPBITMAPINFO)pDIB;
	
//	m_lpBitmapInfoHeader=(LPBITMAPINFOHEADER)pDIB;
	
	file.Seek(sizeof(BITMAPFILEHEADER),CFile::begin);
	// Go read the bits.
	if(file.ReadHuge(pDIB, m_dwBitsSize)!=m_dwBitsSize)
	{
		BOOL b = ::GlobalUnlock(hImage);
		/*win98下不能使用
		if(!b)
		return IMAGE_ERR_UNLOCK;
		*/
		err = DeleteObject();
		if(err != IMAGE_OK)
			return err;
		
		return IMAGE_ERR_READFILE;
	}
	
	if(lpbmi->biCompression!=BI_RGB)
	{
		BOOL b = ::GlobalUnlock(hImage);
		/*win98下不能使用
		if(!b)
		return IMAGE_ERR_UNLOCK;
		*/
		err = DeleteObject();
		if(err != IMAGE_OK)
			return err;

		return IMAGE_ERR_RGB;
	//	return FALSE;
	}
	
	BOOL b = ::GlobalUnlock(hImage);
		/*win98下不能使用
		if(!b)
		return IMAGE_ERR_UNLOCK;
		*/
	return IMAGE_OK;
}
//读JPG图像文件
IMAGE_ERROR CMyImage::LoadJPG(CString FileName)
{
	IMAGE_ERROR err = DeleteObject();
	if( err!= IMAGE_OK)
		return err;
	hImage=::LoadJPG(LPCTSTR(FileName));
	if(hImage==NULL)
		return IMAGE_ERR_IMAGELOAD_READ;

	PBYTE lp = NULL;
	lp = (LPBYTE)::GlobalLock(hImage);
	if(!lp)
	{
		return IMAGE_ERR_LOCK;
	}
	//set dib
	memcpy(&m_bih, lp + 14, sizeof(BITMAPINFOHEADER));
	BOOL b = ::GlobalUnlock(hImage);
			/*win98下不能使用
		if(!b)
		return IMAGE_ERR_UNLOCK;
		*/
	
	
	return IMAGE_OK;
}

IMAGE_ERROR CMyImage::LoadBuf(PBYTE pImage, DWORD dwSize, int iMode)
{
	if(!pImage)
		return IMAGE_NULL;
	IMAGE_ERROR err = DeleteObject();
	if (err != IMAGE_OK)
		return err;
	BOOL b = FALSE;
	PBYTE p = NULL;
	BITMAPFILEHEADER bfh;
	
	switch(iMode) {
	case 0:
		err = CreateObject(dwSize);
		if( err != IMAGE_OK)
			return err;
		p = (LPBYTE)::GlobalLock(hImage);
		if(!p)
			return IMAGE_ERR_LOCK;
		memcpy(p, pImage, dwSize);
		//set dib
		memcpy(&m_bih, pImage + 14, sizeof(BITMAPINFOHEADER));
		b = ::GlobalUnlock(hImage);
		/*win98下禁止使用
		if(!b)
		return IMAGE_ERR_UNLOCK;*/
		break;
	case 1:
		err = CreateObject(dwSize + 14);
		if( err != IMAGE_OK)
			return err;
		
		memset(&bfh, 0, sizeof(bfh));
		bfh.bfType = 'MB';
		bfh.bfOffBits = 54;
		bfh.bfSize = dwSize + 14;

		p = (PBYTE)::GlobalLock(hImage);
		if(!p)
			return IMAGE_ERR_LOCK;
		memcpy(p, &bfh, sizeof(bfh));
		memcpy(p + 14, pImage, dwSize);

		//set dib
		memcpy(&m_bih, pImage, sizeof(BITMAPINFOHEADER));
		
		b = ::GlobalUnlock(hImage);
		/*win98下禁止使用
		if(!b)
		return IMAGE_ERR_UNLOCK;*/
		break;
	default:
		if (m_bih.biWidth == 0 )
			return IMAGE_ERR_INFOHEADER;
		err = CreateObject(dwSize + 54);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -