📄 image.cpp
字号:
/* if not enough memory, clean up and return NULL */
lpPal = (LPLOGPALETTE) GlobalAllocPtr(GHND, sizeof(LOGPALETTE)
+ sizeof(PALETTEENTRY)
* wNumColors);
if (lpPal == 0) return FALSE;
/* set version and number of palette entries */
lpPal->palVersion = 0x300;
lpPal->palNumEntries = wNumColors;
for (i = 0; i < (int)wNumColors; i++)
{
lpPal->palPalEntry[i].peRed = pBMI->bmiColors[i].rgbRed;
lpPal->palPalEntry[i].peGreen = pBMI->bmiColors[i].rgbGreen;
lpPal->palPalEntry[i].peBlue = pBMI->bmiColors[i].rgbBlue;
lpPal->palPalEntry[i].peFlags = 0;
}
/* create the palette and get handle to it */
delete m_pPal;
m_pPal=new CPalette;
bResult = m_pPal->CreatePalette(lpPal);
GlobalFreePtr(lpPal);
}
return bResult;
}
///////////////////////////////////////////////////////////////////
BOOL CImage::CreateGreyPalette()
{
LPLOGPALETTE lpPal; // pointer to a logical palette
LPBITMAPINFO pBMI = BMInfoPtr();
HANDLE hLogPal; // handle to a logical palette
int i; // loop index
WORD wNumColors=NumColors(); // number of colors in color table
BOOL bResult=FALSE;
/* allocate memory block for logical palette */
hLogPal = ::GlobalAlloc(GHND, sizeof(LOGPALETTE)
+ sizeof(PALETTEENTRY)
* wNumColors);
/* if not enough memory, clean up and return NULL */
if (hLogPal == 0) return FALSE;
lpPal = (LPLOGPALETTE) ::GlobalLock((HGLOBAL) hLogPal);
/* set version and number of palette entries */
lpPal->palVersion = 0x300;
lpPal->palNumEntries = wNumColors;
//set the grey value of palette
for (i = 0; i < (int)wNumColors; i++)
{
lpPal->palPalEntry[i].peRed = i;
lpPal->palPalEntry[i].peGreen = i;
lpPal->palPalEntry[i].peBlue = i;
lpPal->palPalEntry[i].peFlags = 0;
pBMI->bmiColors[i].rgbRed=i;
pBMI->bmiColors[i].rgbGreen=i;
pBMI->bmiColors[i].rgbBlue=i;
}
/* create the palette and get handle to it */
delete m_pPal;
m_pPal=new CPalette;
bResult = m_pPal->CreatePalette(lpPal);
::GlobalUnlock((HGLOBAL) hLogPal);
::GlobalFree((HGLOBAL) hLogPal);
return bResult;
}
///////////////////////////////////////////////////////////////////
//create a grey DIB according to the color bmp
//and creat a grey palette according to the
//inforhead of the color bmp
BOOL CImage::CreateGreyDib()
{
BYTE y[256];
WORD i, j, w, h;
DWORD dwL;
BOOL bResult = FALSE;
LPBITMAPINFO pBMI;
if ( !m_pDib ) return FALSE;
w = Width();
h = Height();
dwL = w * h;
pBMI = BMInfoPtr();
switch(Bits())
{
case 8:
{
Data();
for (i = 0; i < NumColors() ; i++)
{
y[i] = (BYTE)( float( pBMI->bmiColors[i] . rgbRed) * 0.30
+ float( pBMI->bmiColors[i] . rgbGreen)* 0.59
+ float( pBMI->bmiColors[i] . rgbBlue) * 0.11);
if(y[i] > 255)
y[i] = 255;
}
CreateGreyPalette();
for(DWORD d=0 ; d<dwL ; d++)
{
m_pData[d] = y[m_pData[d]];
}
Dib();
return TRUE;
}
case 24:
{
CImage *pGreyImage;
DWORD t1, t2;
BYTE *pGreyData, *pColData;
pGreyImage = new CImage(CSize(w, h), 256, 8);
pColData = Data();
pGreyData = pGreyImage -> Data();
for(i=0; i<h; i++)
{
t1 = DWORD(i) * w * 3;
for(j=0; j<w; j++)
{
t2 = t1 + 3 * j;
pGreyData [ i * w + j ] = BYTE(
(float)(pColData[ t2 ] * 0.11)
+ (float)(pColData[t2+1] * 0.59)
+ (float)(pColData[t2+2] * 0.30));
}
}
ImageClear();
*this = *pGreyImage;
Dib();
delete pGreyImage;
return TRUE;
}
default:
{
AfxMessageBox("Only convert 8 bits or 24 bits image to grey image");
return FALSE;
}
}
}
///////////////////////////////////////////////////////////////////
BOOL CImage::Display(CDC* pDC, CPoint origin) const
{
// direct to device--bypass the GDI bitmap
LPBITMAPINFOHEADER pBMIH = BMInfoHdPtr();
LPBITMAPINFO pBMI = BMInfoPtr();
if (!m_pDib) {
return FALSE; // nothing to display
}
if (!::SetDIBitsToDevice(pDC->GetSafeHdc(), origin.x, origin.y,
(WORD) pBMIH->biWidth, (WORD) pBMIH->biHeight, 0, 0, 0,
(WORD) pBMIH->biHeight, m_pData, pBMI,
DIB_RGB_COLORS)) {
return FALSE;
}
return TRUE;
}
///////////////////////////////////////////////////////////////////
BOOL CImage::Stretch(CDC* pDC, CPoint origin, CSize size) const
{
// direct to device--bypass the GDI bitmap
LPBITMAPINFOHEADER pBMIH = BMInfoHdPtr();
LPBITMAPINFO pBMI = BMInfoPtr();
if (!m_pDib) {
return FALSE; // nothing to display
}
::SetStretchBltMode (pDC->GetSafeHdc(), COLORONCOLOR);
if (!::StretchDIBits(pDC->GetSafeHdc(), origin.x, origin.y,
size.cx, size.cy, 0, 0, (WORD) pBMIH->biWidth,
(WORD) pBMIH->biHeight, m_pData, pBMI,
DIB_RGB_COLORS, SRCCOPY)) {
return FALSE;
}
return TRUE;
}
///////////////////////////////////////////////////////////////////
WORD CImage::Bits() const
{
ASSERT(m_pDib);
return ((LPBITMAPINFOHEADER)m_pDib)->biBitCount;
}
///////////////////////////////////////////////////////////////////
DWORD CImage::Length() const
{
return m_dwLength;
}
///////////////////////////////////////////////////////////////////
CSize CImage::Size() const
{
ASSERT(m_pDib);
LPBITMAPINFOHEADER pBMIH = BMInfoHdPtr();
return CSize((int) pBMIH->biWidth, (int) pBMIH->biHeight);
}
///////////////////////////////////////////////////////////////////
WORD CImage::Height() const
{
ASSERT(m_pDib);
return (WORD)(((LPBITMAPINFOHEADER)m_pDib)->biHeight);
}
///////////////////////////////////////////////////////////////////
WORD CImage::Width() const
{
ASSERT(m_pDib);
return (WORD) (((LPBITMAPINFOHEADER)m_pDib)->biWidth);
}
///////////////////////////////////////////////////////////////////
//return the number of entries in the color pallete
WORD CImage::NumColors() const
{
ASSERT(m_pDib);
LPBITMAPINFOHEADER pBMIH = BMInfoHdPtr();
if(m_pDib==NULL) return NULL;
if(pBMIH->biClrUsed!=0)
return (WORD)pBMIH->biClrUsed;
switch(pBMIH->biBitCount)
{
case 1:
return 2;
case 4:
return 16;
case 8:
return 256;
default:
return 0;
}
}
///////////////////////////////////////////////////////////////////
LPBITMAPINFOHEADER CImage::BMInfoHdPtr() const
{
return (LPBITMAPINFOHEADER)m_pDib;
}
///////////////////////////////////////////////////////////////////
LPBITMAPINFO CImage::BMInfoPtr() const
{
return (LPBITMAPINFO)m_pDib;
}
///////////////////////////////////////////////////////////////////
RGBQUAD* CImage::BMColorTblPtr() const
{
return (RGBQUAD*)((int)m_pDib+sizeof(BITMAPINFOHEADER));
}
///////////////////////////////////////////////////////////////////
void CImage::SetDIB(BOOL Flag)
{
if(Flag) m_bIsDIB=TRUE;
else m_bIsDIB=FALSE;
}
///////////////////////////////////////////////////////////////////
// To convert the non-DIB to DIB type
BYTE* CImage::Dib()
{
if(!m_pDib) return NULL;
if(m_bIsDIB) return m_pData;
WORD i, j;
BYTE *p1, *p2;
WORD bpp = Bits();
WORD bytepp = bpp / 8;
WORD w = Width();
WORD h = Height();
long lBpl = w * bytepp;
WORD halfline = h / 2;
//reverse the order of scanning
//for(i=0 ; i<halfline-1 ; i++){/// Ms. Yao changed it!
BYTE temp;
p1 = m_pData;
p2 = m_pData + lBpl * h;
for(i=0 ; i<halfline; i++)
{
p2 -= lBpl;
for(j=0; j<lBpl; j++)
{
temp = p1[j];
p1[j] = p2[j];
p2[j] = temp;
}
p1 += lBpl;
}
if(((w * bpp) % 32)==0)
{
SetDIB();
return m_pData;
}
/*otherwise, it is needed to pad data*/
DWORD dwBNFOL = ByteNumForOneLine(w, bpp);
for(i=h-1; i>0; i--)
{
p1 = m_pData + i * dwBNFOL;
p2 = m_pData + i * lBpl;
memmove(p1, p2, lBpl);
memset(p1+lBpl, 0x00, (dwBNFOL - lBpl));
}
SetDIB();
return m_pData;
}
/////////////////////////////////////////
//implement the reverse function of dib()
BYTE* CImage::Data()
{
if(!m_pDib) return NULL;
if(!m_bIsDIB) return m_pData;
WORD i,j;
BYTE *p1, *p2;
WORD bpp = Bits();//bpp
WORD Bytepp = bpp / 8;
WORD w = Width();
WORD h = Height();
WORD halfline= h/2;
LPBITMAPINFOHEADER pBMIH = BMInfoHdPtr( );
if(pBMIH->biCompression!=BI_RGB)
{
AfxMessageBox("Con't process compressed image");
return NULL;
}
if((w * bpp) % 32)
{
long t = w * Bytepp;
DWORD dwBNFOL = ByteNumForOneLine(w, bpp);
p2 = p1 = m_pData;
for(i=0; i<h-1; i++)
{
p1 += dwBNFOL;
p2 += t;
memmove(p2, p1, t);
}
}
/*/
if((w * bpp) % 32)
{
long lbpl = w * Bytepp;
DWORD dwBNFOL = ByteNumForOneLine(w, bpp);
for(i=0; i<h-1; i++)
{
p1 = m_pData + ( i + 1 ) * dwBNFOL;
p2 = m_pData + ( i + 1 ) * lbpl;
memmove(p2, p1, lbpl);
}
}
*/
/*for(i=0 ; i<halfline-1 ; i++)**Ms. Yao changed!**/
long lBytePerLine = w * Bytepp;
p1 = m_pData;
p2 = m_pData + h * lBytePerLine;
BYTE temp;
for(i = 0 ; i < halfline; i++)
{
p2 -= lBytePerLine;
for(j = 0; j < lBytePerLine; j++)
{
temp = p1[j];
p1[j] = p2[j];
p2[j] = temp;
}
p1 += lBytePerLine;
}
SetDIB(FALSE);
return m_pData;
}
///////////////////////////////////////////////////////////////////
CPalette* CImage::Palette() const
{
return m_pPal;
}
///////////////////////////////////////////////////////////////////
UINT CImage::SetPalette(CDC* pDC,BOOL bBackground) const
{
if(!m_pPal->m_hObject) return FALSE;
VERIFY(pDC->SelectPalette(m_pPal,bBackground));
return(pDC->RealizePalette());
}
///////////////////////////////////////////////////////////////////
void CImage::SetMonoColors(DWORD dwForeground, DWORD dwBackground)
{
if (Bits() != 1) {
return;
}
unsigned long far* pPalette = (unsigned long far*)
BMColorTblPtr();
*pPalette = dwForeground;
*(++pPalette) = dwBackground;
return;
}
///////////////////////////////////////////////////////////////////
BOOL CImage::GetMonoColors(DWORD& dwForeground, DWORD& dwBackground)
{
if (Bits() != 1) {
return FALSE;
}
unsigned long far* pPalette = (unsigned long far*)
BMColorTblPtr();
dwForeground = *pPalette;
dwBackground = *(++pPalette);
return TRUE;
}
///////////////////////////////////////////////////////////////////
BOOL CImage::AllocateMemory(BOOL bRealloc) // bRealloc default = FALSE
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -