📄 dib.cpp
字号:
Returns: Number of read ints.
*************************************************************************/
DWORD CDib::Read(CFile& file)
{
// Ensures no memory leaks will occur
Free();
BITMAPFILEHEADER bmfHeader;
// Go read the DIB file header and check if it's valid.
if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))
return 0;
if (bmfHeader.bfType != DIB_HEADER_MARKER)
return 0;
DWORD dwReadints = sizeof(bmfHeader);
// Allocate memory for DIB
m_pBMI = (LPBITMAPINFO)GlobalAllocPtr(GHND, bmfHeader.bfOffBits-sizeof(BITMAPFILEHEADER) + 256*sizeof(RGBQUAD));
if (m_pBMI == 0)
return 0;
// Read header.
if (file.Read(m_pBMI, bmfHeader.bfOffBits-sizeof(BITMAPFILEHEADER)) != (UINT)(bmfHeader.bfOffBits-sizeof(BITMAPFILEHEADER)))
{
GlobalFreePtr(m_pBMI);
m_pBMI = NULL;
return 0;
}
dwReadints += bmfHeader.bfOffBits-sizeof(BITMAPFILEHEADER);
DWORD dwLength = file.GetLength();
// Go read the bits.
m_pBits = (LPBYTE)GlobalAllocPtr(GHND, dwLength - bmfHeader.bfOffBits);
if (m_pBits == 0)
{
GlobalFreePtr(m_pBMI);
m_pBMI = NULL;
return 0;
}
if (file.ReadHuge(m_pBits, dwLength-bmfHeader.bfOffBits) != (dwLength - bmfHeader.bfOffBits))
{
GlobalFreePtr(m_pBMI);
m_pBMI = NULL;
GlobalFreePtr(m_pBits);
m_pBits = NULL;
return 0;
}
dwReadints += dwLength - bmfHeader.bfOffBits;
CreatePalette();
return dwReadints;
}
#ifdef _DEBUG
void CDib::Dump(CDumpContext& dc) const
{
CObject::Dump(dc);
}
#endif
//////////////////////////////////////////////////////////////////////////
//// Clipboard support
//---------------------------------------------------------------------
//
// Function: CopyToHandle
//
// Purpose: Makes a copy of the DIB to a global memory block. Returns
// a handle to the new memory block (NULL on error).
//
// Returns: Handle to new global memory block.
//
//---------------------------------------------------------------------
HGLOBAL CDib::CopyToHandle() const
{
CSharedFile file;
try
{
if (Save(file)==0)
return 0;
}
catch (CFileException* e)
{
e->Delete();
return 0;
}
return file.Detach();
}
//---------------------------------------------------------------------
//
// Function: ReadFromHandle
//
// Purpose: Initializes from the given global memory block.
// and free the memory.
// Returns: Number of read ints.
//
//---------------------------------------------------------------------
DWORD CDib::ReadFromHandle(HGLOBAL hGlobal)
{
CSharedFile file;
file.SetHandle(hGlobal, FALSE);
DWORD dwResult = Read(file);
GlobalFree(file.Detach());
return dwResult;
}
//////////////////////////////////////////////////////////////////////////
//// Serialization support
void CDib::Serialize(CArchive& ar)
{
CFile* pFile = ar.GetFile();
ASSERT(pFile != NULL);
if (ar.IsStoring())
{ // storing code
Save(*pFile);
}
else
{ // loading code
Read(*pFile);
}
}
BOOL CDib::IsGray()
{
if(m_pBMI->bmiHeader.biBitCount!=8) return FALSE;
for( int i=0;i<256;i++)
{
if(m_pBMI->bmiColors[i].rgbBlue!=i) return FALSE;
if(m_pBMI->bmiColors[i].rgbGreen!=i) return FALSE;
if(m_pBMI->bmiColors[i].rgbRed!=i) return FALSE;
}
return TRUE;
}
int CDib::GetXY8(int x, int y)
{
#ifdef _DEBUG
//Cause a point on the right or bottom side is outside CRect.
CRect rc(0,0, Width(),Height());
ASSERT(rc.PtInRect(CPoint(x,y)));
ASSERT(m_pBMI->bmiHeader.biBitCount==8);
#endif //_DEBUG
// call this function only when biBitCount==8
int TrueWidth;
TrueWidth=(Width()+3)/4*4;
y=Height()-1-y;
return m_pBits[y*TrueWidth+x];
}
void CDib::SetXY8(int x, int y, int val)
{
#ifdef _DEBUG
//Cause a point on the right or bottom side is outside CRect.
CRect rc(0,0, Width(),Height());
ASSERT(rc.PtInRect(CPoint(x,y)));
ASSERT(m_pBMI->bmiHeader.biBitCount==8);
#endif //_DEBUG
// call this function only when biBitCount==8
int TrueWidth;
TrueWidth=(Width()+3)/4*4;
y=Height()-1-y;
m_pBits[y*TrueWidth+x]=val;
}
void CDib::ToGray()
{
CSize m_size(Width(),Height());
int m_TrueWidth=(Width()+3)/4*4;
for(int i=0;i<256;i++)
{
m_pBMI->bmiColors[i].rgbReserved=(int)((float)m_pBMI->bmiColors[i].rgbRed*0.3+\
(float)m_pBMI->bmiColors[i].rgbGreen*0.59+\
(float)m_pBMI->bmiColors[i].rgbBlue*0.11+0.5);
}
for(i=0; i<(int)m_TrueWidth*m_size.cy ; i++)
{
m_pBits[i]=m_pBMI->bmiColors[m_pBits[i]].rgbReserved;
}
for(i=0;i<256;i++)
{
m_pBMI->bmiColors[i].rgbBlue=i;
m_pBMI->bmiColors[i].rgbGreen=i;
m_pBMI->bmiColors[i].rgbRed=i;
m_pBMI->bmiColors[i].rgbReserved=0;
}
}
CDib& CDib::operator =(CDib &dib)
{
if(IsValid()) Free();
int iSize;
iSize=GlobalSize(GlobalHandle(dib.m_pBMI));
m_pBMI=(LPBITMAPINFO)GlobalAllocPtr(GHND, iSize);
CopyMemory((LPBYTE)m_pBMI,(LPBYTE)dib.m_pBMI,iSize);
iSize=GlobalSize(GlobalHandle(dib.m_pBits));
m_pBits=(LPBYTE)GlobalAllocPtr(GHND, iSize);
CopyMemory(m_pBits,dib.m_pBits,iSize);
CreatePalette();
return *this;
}
void CDib::Copy(CDib &dib)
{
if(IsValid()) Free();
int iSize;
iSize=GlobalSize(GlobalHandle(dib.m_pBMI));
m_pBMI=(LPBITMAPINFO)GlobalAllocPtr(GHND, iSize);
CopyMemory((LPBYTE)m_pBMI,(LPBYTE)dib.m_pBMI,iSize);
iSize=GlobalSize(GlobalHandle(dib.m_pBits));
m_pBits=(LPBYTE)GlobalAllocPtr(GHND, iSize);
CopyMemory(m_pBits,dib.m_pBits,iSize);
CreatePalette();
}
void CDib::ConvertToRGB()
{
if(!IsValid()) return;
if(m_pBMI->bmiHeader.biBitCount==24) return;
ASSERT(m_pBMI->bmiHeader.biBitCount==8);
LPBYTE pBits;
LPBITMAPINFO pBMI;
int iWidth;
int i,j;
//prepare bitmapinfoheader for true color bitmap
pBMI = (LPBITMAPINFO)GlobalAllocPtr(GHND, sizeof(BITMAPINFOHEADER));
CopyMemory((PVOID)pBMI, (PVOID)m_pBMI,sizeof(BITMAPINFOHEADER));
pBMI->bmiHeader.biBitCount=24;
pBMI->bmiHeader.biClrUsed=0;
pBMI->bmiHeader.biSizeImage=0;
iWidth=((pBMI->bmiHeader.biWidth*3+3)/4*4);
// prepare memory for bits
pBits= (LPBYTE)GlobalAllocPtr(GHND, iWidth*pBMI->bmiHeader.biHeight);
for(i=0;i<pBMI->bmiHeader.biHeight;i++)
{
LPBYTE lpSource;
LPBYTE lpDest;
lpDest=pBits+(pBMI->bmiHeader.biHeight-1-i)*((pBMI->bmiHeader.biWidth*3+3)/4*4);
lpSource=m_pBits+(pBMI->bmiHeader.biHeight-1-i)*((pBMI->bmiHeader.biWidth+3)/4*4);
for(j=0;j<pBMI->bmiHeader.biWidth;j++)
{
lpDest[3*j+2]=m_pBMI->bmiColors[lpSource[j]].rgbRed;
lpDest[3*j+1]=m_pBMI->bmiColors[lpSource[j]].rgbGreen;
lpDest[3*j]=m_pBMI->bmiColors[lpSource[j]].rgbBlue;
}
}
Free();
m_pBMI=pBMI;
m_pBits=pBits;
CreatePalette();
}
DWORD CDib::Read(LPCSTR filename)
{
CFile file;
CFileException fe;
DWORD dwSize;
if (!file.Open(filename, CFile::modeRead | CFile::shareDenyWrite, &fe))
{
//ReportSaveLoadException(lpszPathName, &fe, FALSE, AFX_IDP_FAILED_TO_OPEN_DOC);
AfxMessageBox("read error!");
return 0;
}
dwSize=Read(file);
file.Close();
return dwSize;
}
DWORD CDib::Save(LPCSTR filename)
{
CFile file;
CFileException fe;
DWORD dwSize;
if (!file.Open(filename, CFile::modeCreate |CFile::modeWrite | CFile::shareDenyWrite, &fe))
{
//ReportSaveLoadException(lpszPathName, &fe, FALSE, AFX_IDP_FAILED_TO_OPEN_DOC);
AfxMessageBox("save error!");
return 0;
}
dwSize=Save(file);
file.Close();
return dwSize;
}
int CDib::GetXYR(int x, int y)
{
int TrueWidth;
TrueWidth=(Width()*3+3)/4*4;
y=Height()-1-y;
return m_pBits[y*TrueWidth+x*3+2];
}
int CDib::GetXYG(int x, int y)
{
int TrueWidth;
TrueWidth=(Width()*3+3)/4*4;
y=Height()-1-y;
return m_pBits[y*TrueWidth+x*3+1];
}
int CDib::GetXYB(int x, int y)
{
int TrueWidth;
TrueWidth=(Width()*3+3)/4*4;
y=Height()-1-y;
return m_pBits[y*TrueWidth+x*3];
}
void CDib::SetXYR(int x, int y, int val)
{
int TrueWidth;
TrueWidth=(Width()*3+3)/4*4;
y=Height()-1-y;
m_pBits[y*TrueWidth+x*3+2]=val;
}
void CDib::SetXYG(int x, int y, int val)
{
int TrueWidth;
TrueWidth=(Width()*3+3)/4*4;
y=Height()-1-y;
m_pBits[y*TrueWidth+x*3+1]=val;
}
void CDib::SetXYB(int x, int y, int val)
{
int TrueWidth;
TrueWidth=(Width()*3+3)/4*4;
y=Height()-1-y;
m_pBits[y*TrueWidth+x*3]=val;
}
float CDib::RGB_Y(int R, int G, int B)
{
return (float)(0.299*R+0.587*G+0.114*B);
}
float CDib::RGB_U(int R, int G, int B)
{
return (float)(-0.16875*R-0.33126*G+0.5*B);
}
float CDib::RGB_V(int R, int G, int B)
{
return (float)(0.5*R-0.41869*G-0.08131*B);
}
int CDib::YUV_R(float Y, float U, float V)
{
int b=Y+1.402*(V);
if (b > 255)
{
b=255;
}
else if (b < 0)
{
b=0;
}
return (int)(b);
}
int CDib::YUV_G(float Y, float U, float V)
{
int b=Y-0.34413*(U)-0.71414*(V);
if (b > 255)
{
b=255;
}
else if (b < 0)
{
b=0;
}
return (int)(b);
}
int CDib::YUV_B(float Y, float U, float V)
{
int b=Y+1.772*(U);
if (b > 255)
{
b=255;
}
else if (b < 0)
{
b=0;
}
return (int)(b);
}
//DEL void CDib::RGB_GRAY()
//DEL {
//DEL
//DEL if( m_pBMI== NULL || m_pBits == NULL || m_pBMI->bmiHeader.biBitCount!=24)
//DEL return;
//DEL
//DEL DWORD bmWidthints = (m_pBmih->biWidth * m_pBmih->biBitCount + 31) / 32*4;
//DEL int i,j;
//DEL int r,b,g;
//DEL LPint pint = m_pBits;
//DEL
//DEL
//DEL ASSERT(pint != NULL);
//DEL memcpy( pint, m_pBits,m_dwSizeImage);
//DEL if( m_hBitmap )
//DEL ::DeleteObject(m_hBitmap);
//DEL m_hBitmap = hBitmap;
//DEL if( m_pBits && !m_bNoDelBits )
//DEL delete[] m_pBits;
//DEL m_pBits = pint;
//DEL m_bNoDelBits = 1;
//DEL m_bGray = 1;
//DEL
//DEL }
int CDib::GETXY_Y(int x,int y)
{
return(RGB_Y(GetXYR(x,y),GetXYG(x,y),GetXYB(x,y)));
}
int CDib::GETXY_U(int x,int y)
{
return(RGB_U(GetXYR(x,y),GetXYG(x,y),GetXYB(x,y)));
}
int CDib::GETXY_V(int x,int y)
{
return(RGB_V(GetXYR(x,y),GetXYG(x,y),GetXYB(x,y)));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -