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

📄 dib.cpp

📁 vc++实现简单图像编辑器。。。。。。。。。
💻 CPP
📖 第 1 页 / 共 4 页
字号:
// Dib.cpp: implementation of the CDib class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"

#include "Dib.h"

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_SERIAL(CDib,,CObject,1);

CDib::CDib()
{
	m_hDib=NULL;
	m_pPalette=NULL;
	m_pBitmap=NULL;
}

CDib::~CDib()
{
	Destroy();
	if(m_pBitmap!=NULL)
	{
		delete m_pBitmap;
		m_pBitmap=NULL;
	}
	if(m_pPalette!=NULL)
	{
		delete m_pPalette;
		m_pPalette=NULL;
	}
}
//create default empty DIB use system palette
BOOL CDib::Create(DWORD dwWidth, DWORD dwHeight)
{
  HDIB hDib=CreateDefaultDIB(dwWidth,dwHeight);
  if(!hDib)
	return FALSE;
  Destroy();
  m_hDib=hDib;
  return UpdateInternal();
}
//create default empty DIB
BOOL CDib::Create(DWORD dwWidth, DWORD dwHeight, WORD wBitCount)
{
	HDIB hDib=CreateDIB(dwWidth,dwHeight,wBitCount);
	if(!hDib)
		return FALSE;
    Destroy();
    m_hDib=hDib;
    return UpdateInternal();
}
//create default DIB from DIB data block
//根据内存指针,创建图像内存块句柄
BOOL CDib::Create(LPBYTE lpDIB)
{
	if(lpDIB==NULL)
		return FALSE;
	//计算内存块大小
	DWORD dwSize=DIBLockSize(lpDIB);
	//分配内存
	HDIB hDib=GlobalAlloc(GHND,dwSize);
	//check that DIB handle is valid
	if(!hDib)
		return FALSE;
	//内存锁定
	LPBYTE lpbi=(LPBYTE)GlobalLock(hDib);
	if(!lpbi)
		return FALSE;
	//内存复制(内存块一样,但类型不一样)
	CopyMemory(lpbi,lpDIB,dwSize);
	GlobalUnlock(hDib);
	//如果m_hDib已指向某个内存块,销毁
	Destroy();
	//指定成员变量的内存块(注意重新分配了内存)
	m_hDib=hDib;
	return UpdateInternal();

}
//create  DIB from DIB data block
BOOL CDib::Create(LPBYTE lpDIB, WORD wBitCount)
{
    if(lpDIB==NULL)
		return FALSE;
	if(!Create(lpDIB))
		return FALSE;
    WORD wBits=((LPBITMAPINFOHEADER)lpDIB)->biBitCount ;
	if(!wBitCount==wBits)
		return FALSE;

	HDIB hNewDib=ConvertDIBFormat(m_hDib,wBitCount,NULL);

	if(!hNewDib)
		return FALSE;
	
	Destroy();
	m_hDib=hNewDib;
	return UpdateInternal();

}
//create default DIB from DIBSECTION data block
BOOL CDib::Create(HBITMAP hBitmap)
{
	if (!hBitmap)
		return FALSE;
	HDIB hDib=DIBSectionToDIB(hBitmap);
	if(!hDib)
		return FALSE;
	Destroy();
	m_hDib=hDib;
	return UpdateInternal();
}

//create  DIB from DDB data block
BOOL CDib::Create(HBITMAP hBitmap, WORD wBitCount)
{
	 if (!hBitmap)
		return FALSE;
	HDIB hDib=DIBSectionToDIB(hBitmap);
	if(!hDib)
		return FALSE;
	DIBSECTION ds;
	HDIB hNewDib;
	GetObject(hBitmap,sizeof(DIBSECTION),&ds);
	if(wBitCount==ds.dsBmih .biBitCount )
		hNewDib=hDib;
	else
	{
		hNewDib=ConvertDIBFormat(hDib,wBitCount,NULL);
		//cleanup hDib
		GlobalFree(hDib);
	}
	if(!hNewDib)
		return FALSE;

	Destroy();
	m_hDib=hNewDib;
	return UpdateInternal();

}
//create DIB from  DDB and given palette
BOOL CDib::Create(HBITMAP hBitmap, HPALETTE hPalette)
{
	if (!hBitmap)
		return FALSE;
	if(!hPalette)
		return FALSE;
	HDIB hDib=BitmapToDIB(hBitmap,hPalette);
	if(!hDib)
		return FALSE;
	Destroy();
	m_hDib=hDib;
	return UpdateInternal();

}
//create DIB from  DDB and given palette
BOOL CDib::Create(HBITMAP hBitmap, HPALETTE hPalette, WORD wBitCount)
{
	if (!hBitmap)
		return FALSE;
	if(!hPalette)
		return FALSE;
	HDIB hDib=BitmapToDIB(hBitmap,hPalette,wBitCount);
	if(!hDib)
		return FALSE;
	Destroy();
	m_hDib=hDib;
	return UpdateInternal();
}
//create DIB from  given CRect
BOOL CDib::Create(CRect rcScreen)
{
   	HDIB hDib=CopyScreenToDIB(rcScreen);
	if(!hDib)
		return FALSE;

	Destroy();
	m_hDib=hDib;
	return UpdateInternal();
}
//create DIB from  given window
BOOL CDib::Create(HWND hWnd, WORD fPrintArea)
{
    HDIB hDib=CopyWindowToDIB(hWnd,fPrintArea);
	if(!hDib)
		return FALSE;

	Destroy();
	m_hDib=hDib;
	return UpdateInternal();
}
//create DIB from  given window and area
BOOL CDib::Create(HWND hWnd, CRect rcClientArea)
{
    HDIB hDib=CopyClientRectToDIB(hWnd,rcClientArea);
	if(!hDib)
		return FALSE;

	Destroy();
	m_hDib=hDib;
	return UpdateInternal();
}
// connect the resource number with the DIB
BOOL CDib::Attach(HDIB hDib)
{
	if(!hDib)
		return FALSE;

	Destroy();
	m_hDib=hDib;
	return UpdateInternal();
}
//create DIB from given resource Number
BOOL CDib::Load(UINT uIDS, LPCTSTR lpszDibType)
{
	LPCSTR lpszDibRes=MAKEINTRESOURCE(uIDS);
	return Load(lpszDibRes,lpszDibType);
}
//Create DIB from given resource name
BOOL CDib::Load(LPCTSTR lpszDibRes, LPCTSTR lpszDibType)
{
	HINSTANCE hInst=AfxGetInstanceHandle();
	HRSRC hRes=::FindResource (hInst,lpszDibRes,lpszDibType);
	HGLOBAL hData=::LoadResource (hInst,hRes);
	//if resource ok?
	if(hRes==NULL||hData==NULL)
		return FALSE;
	//get resource buffer
	LPBYTE lpBuf=(LPBYTE)::LockResource (hData);
	//is DIB?
	if(((LPBITMAPFILEHEADER)lpBuf)->bfType !=DIB_HEADER_MARKER)
		return FALSE;
	//use this buffer to create CDib
	LPBYTE lpDIB=lpBuf+sizeof(BITMAPFILEHEADER);
	return Create(lpDIB);

}
//create DIB from given file name  
BOOL CDib::Load(LPCTSTR lpszDibFile)
{
	try
	{
		CFile file(lpszDibFile,CFile::modeRead|CFile::shareDenyNone);
		if(!Read(&file))
			return FALSE;
	}
	catch(CException e)
	{
		return FALSE;
	}
	return TRUE;
}

BOOL CDib::Save(LPCTSTR lpszDibFile)
{
	try
	{
		CFile file(lpszDibFile,CFile::modeCreate|CFile::modeWrite);
		if(!Write(&file))
			return FALSE;
	}
	catch(CException e)
	{
		return FALSE;
	}
	return TRUE;
}
//Read a DIB file
BOOL CDib::Read(CFile *pFile)
{
	//改变鼠标形状
	SetCursor(LoadCursor(NULL,IDC_WAIT));
	//位图信息头
	LPBITMAPINFOHEADER lpbi;
	LPBYTE lpBI;
	DWORD dwSize;
	HDIB hDIB;
	//位图文件头
	BITMAPFILEHEADER bmfHdr;
	try
	{
		//read DIB file header	
		//读位图文件头
		int nSize=sizeof(BITMAPFILEHEADER);
		pFile->Read ((LPBYTE)&bmfHdr,nSize);
		//IS DIB file?
		//判断是否BMP图像
		if(bmfHdr.bfType !=DIB_HEADER_MARKER ) //"BM"
		{
			SetCursor(LoadCursor(NULL,IDC_ARROW));
			return FALSE;
		}
		//纠正错误的文件长度信息
		DWORD dwLength=pFile->GetLength ();
		if(bmfHdr.bfSize !=dwLength)
			bmfHdr.bfSize =dwLength;
		//read DIB INFO
		//计算剩余的文件大小(除位图文件头外)
		dwSize=bmfHdr.bfSize -sizeof(BITMAPFILEHEADER);
	
		//sizeof(BITMAPINFOHEADER);
		//分配内存空间,返回内存句柄
		hDIB=GlobalAlloc(GHND,dwSize);
		//锁定内存句柄
		lpBI=(LPBYTE)GlobalLock(hDIB);
		//读剩余的数据
		DWORD dwCount=pFile->ReadHuge (lpBI,dwSize);
		//read ok?
		//判断是否正常读取(和预计的大小是否相同)
		if(dwCount!=dwSize)
		{
			GlobalUnlock(hDIB);
			GlobalFree(hDIB);
			SetCursor(LoadCursor(NULL,IDC_ARROW));
			return FALSE;
		}
		//解析最前面的位图信息头
		lpbi=(LPBITMAPINFOHEADER)lpBI;
		//check to see if  it's a window DIB
		//判断位图信息头是否和预计的相同
		if(lpbi->biSize !=sizeof(BITMAPINFOHEADER))
		{
			GlobalUnlock(hDIB);
			GlobalFree(hDIB);
			SetCursor(LoadCursor(NULL,IDC_ARROW));
			return FALSE;
		}
		//FILL COLOR NUM ITEM
		//检查图像颜色数目字段(可能没有填写)
		int nNumColors=(UINT) lpbi->biClrUsed ;
		if(nNumColors==0)
		{
			//no color table for 24-bits default size otherwise
			//根据每像素的位数,计算颜色数目
			if(lpbi->biBitCount !=24)
				nNumColors=1<<lpbi->biBitCount ;
		}
		//fill in some default values if they are zero
		//填上可能没有填充的内容
		if(lpbi->biClrUsed ==0)
			lpbi->biClrUsed =nNumColors;
		if(lpbi->biSizeImage ==0)
			//计算图像字节大小,注意4个字节补齐
			lpbi->biSizeImage =
			((((lpbi->biWidth *(DWORD)lpbi->biBitCount )
			+31)&~31)>>3)*lpbi->biHeight ;		    
	}
	//异常处理
	catch(CException e)
	{
		GlobalUnlock(hDIB);
		GlobalFree(hDIB);
		SetCursor(LoadCursor(NULL,IDC_ARROW));
		return FALSE;		
	}
	//create CDib with DIB buffer
	BOOL bSuccess;
	//创建图像内存块句柄
	bSuccess=Create(lpBI);
	GlobalFree(lpBI);
	
	//恢复鼠标形状
	SetCursor(LoadCursor(NULL,IDC_ARROW));
	//恢复文件头指针
	pFile->SeekToBegin ();
	return bSuccess;
	
}

BOOL CDib::Write(CFile *pFile)
{
	SetCursor(LoadCursor(NULL,IDC_WAIT));
	
	BITMAPFILEHEADER bmfHdr;//header for bitmap file
	LPBITMAPINFOHEADER lpbi;//pointer to DIB info structure
	DWORD dwDIBSize;
	//get the pointer to the DIB memory
	lpbi=(LPBITMAPINFOHEADER)GlobalLock(m_hDib);
	if(!lpbi)
	{
		GlobalUnlock(m_hDib);
		SetCursor(LoadCursor(NULL,IDC_ARROW));
		return FALSE;
	}
		//check to see if  it's a window DIB
	if(lpbi->biSize !=sizeof(BITMAPINFOHEADER))
		{
			GlobalUnlock(m_hDib);
			SetCursor(LoadCursor(NULL,IDC_ARROW));
			return FALSE;
		}
	//Fill in the fields of the file header
	//Fill in the file type (first 2bytes must be "BM" for 
	//a Bitmap

	bmfHdr.bfType =DIB_HEADER_MARKER;//"BM"

	//calculating the size of the DIB is a bit trickly(if we want to
	// do it right).The easiest way to do this is to call GlobalSize()
	// on our global handle, but since the size of our global memory
	//may have been padded a few bytes, we may end uup writing out a 
	//few too many bytes to the file(which may vause problems with 
	//some apps,like HC 3.0

	// so Instead let's calculate the size manually

	//To do this ,find size of Header Plus size of Color table,Since
	//the first DWORD in both BITMAPINFOHEADER and
	//BITMAPCOREHEADER contains the size of the structure, let's use
	//this

	//partial calculation
    	
	dwDIBSize=*(LPDWORD)lpbi+PaletteSize((LPBYTE)lpbi);
		      
	//Now calculate the size of the image

	//It's an RLE butmap,we can't calculate size, so trust the
	//biSizeImage field

	if((lpbi->biCompression ==BI_RLE8)||
	   (lpbi->biCompression ==BI_RLE4))
	   dwDIBSize+=lpbi->biSizeImage ;
	else
	{
		DWORD dwBmBitsSize;//Size of Bitmap Bits only
		//It's not RLE,so size is width (DWORD aligned)*Height

		dwBmBitsSize=WIDTHBYTES((lpbi->biWidth )*
			                   ((DWORD)lpbi->biBitCount ))*lpbi->biHeight ;
		dwDIBSize+=dwBmBitsSize;

		//Now since we have calculated the correct size,why don't
		// fill in the biSizeImage field

		lpbi->biSizeImage =dwBmBitsSize;
	}

	//calculate the file size by adding the DIB size to
	//size of (BITMAPFILEHEADER)

	bmfHdr.bfSize =dwDIBSize+sizeof(BITMAPFILEHEADER);
	bmfHdr.bfReserved1= 0;
	bmfHdr.bfReserved2 =0;

	//Now calculate the offset the actual bitmap bits will be in
	// the file-- It's tje bitmap file header plus the DIB header
	// plus the size of the color table

	bmfHdr.bfOffBits =(DWORD)sizeof(BITMAPFILEHEADER)+
		lpbi->biSize +PaletteSize((LPBYTE)lpbi);
	//write the file header

	try
	{
	   pFile->Write (&bmfHdr,
		      sizeof(BITMAPFILEHEADER));

	//write the DIB header and the bits--use local version of
	//mywrite, so we can write more than 32767 bytes of data

	  pFile->WriteHuge(lpbi,dwDIBSize);
	}
	catch(CException e)
	{
		GlobalUnlock(m_hDib);
		SetCursor(LoadCursor(NULL,IDC_ARROW));
		return FALSE;		
	}


	GlobalUnlock(m_hDib);
	SetCursor(LoadCursor(NULL,IDC_ARROW));
	return TRUE;

}
//destroy DIB and release memory
void CDib::Destroy()
{
	if(m_hDib!=NULL)
	{
		DestroyDIB(m_hDib);
		m_hDib=NULL;
	}
}
//unconnect tje DIB and CDib object
HDIB CDib::Detach()
{
	if(m_hDib==NULL)
		return NULL;
	HDIB hDib=m_hDib;
	m_hDib=NULL;
	if(m_pBitmap!=NULL)
	{
		delete m_pBitmap;
		m_pBitmap=NULL;
	}
	if(m_pPalette!=NULL)
	{
		delete m_pPalette;
		m_pPalette=NULL;
	}
	return hDib;
}

void CDib::Serialize(CArchive &ar)
{
	CObject::Serialize (ar);
	ar.Flush ();
	if(ar.IsStoring ())
	{
		Write(ar.GetFile ());
	}
	else
	{
		Read(ar.GetFile ());
	}


}

BOOL CDib::Display(CDC *pDC, int xDest, int yDest, int nWidthDest, int nHeightDest, int xSrc, int ySrc, DWORD dwRop)
{
	CDC MemDC;
	MemDC.CreateCompatibleDC (pDC);
	CBitmap*pOldBmp=MemDC.SelectObject (m_pBitmap);
	CPalette* pOldPal=pDC->SelectPalette (m_pPalette,TRUE);
	pDC->RealizePalette ();

	BOOL bSuccess=pDC->BitBlt (xDest,yDest,
		                       nWidthDest,nHeightDest,

⌨️ 快捷键说明

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