📄 imageobject.cpp
字号:
{
if( ucRed > pRGBPalette[ i ].rgbRed )
dwRed = ( DWORD )( pRGBPalette[ i ].rgbRed - ucRed );
else
dwRed = ( DWORD )( ucRed - pRGBPalette[ i ].rgbRed );
if( ucGreen > pRGBPalette[ i ].rgbGreen )
dwGreen = ( DWORD )( pRGBPalette[ i ].rgbGreen - ucGreen );
else
dwGreen = ( DWORD )( ucGreen - pRGBPalette[ i ].rgbGreen );
if( ucBlue > pRGBPalette[ i ].rgbBlue )
dwBlue = ( DWORD )( pRGBPalette[ i ].rgbBlue - ucBlue );
else
dwBlue = ( DWORD )( ucBlue - pRGBPalette[ i ].rgbBlue );
NewDiff = ( dwRed * dwRed ) + ( dwGreen * dwGreen ) + ( dwBlue * dwBlue );
if( NewDiff < Diff )
{
if( NewDiff <= 1 )
return( i );
Diff = NewDiff;
Index = i;
}
}
return( Index );
}
void CImageObject::CreatePaletteFromDIB( RGBQUAD *pRGBPalette, int nColors )
{
if( pRGBPalette != NULL )
{
LOGPALETTE *pPalette;
pPalette = CreateLogPalette( pRGBPalette, nColors );
if( pPalette != NULL )
{
m_Palette.CreatePalette( pPalette );
delete[] pPalette;
}
else
m_nLastError = GL_LOGICAL_PALETTE_CREATION_ERROR;
}
}
LOGPALETTE *CImageObject::CreatePaletteFromBitmap( int nColors, unsigned char *pBits, int nBits, int nWidth, int nHeight )
{
RGBQUAD *pRGBPalette;
if( nBits != 8 && m_nPaletteCreationType == JGPT_POPULARITY_PALETTE )
pRGBPalette = GeneratePopularityPalette( nColors, pBits, nBits, nWidth, nHeight );
else if( nBits != 8 && m_nPaletteCreationType == JGPT_MEDIAN_CUT_PALETTE )
pRGBPalette = GenerateMedianCutPalette( nColors, pBits, nBits, nWidth, nHeight );
else if( m_nPaletteCreationType == JGPT_FIXED_PALETTE )
pRGBPalette = GenerateFixedPalette( nColors );
if( pRGBPalette == NULL )
return( NULL );
LOGPALETTE *pLogPalette = CreateLogPalette( pRGBPalette, nColors );
delete[] pRGBPalette;
return( pLogPalette );
}
RGBQUAD *CImageObject::GeneratePopularityPalette( int nColors, unsigned char *pBits, int nBits, int nWidth, int nHeight )
{
RGBQUAD *pRGBQuad = new RGBQUAD[ nColors ];
if( pRGBQuad == NULL )
return( GenerateFixedPalette( nColors ) );
memset( pRGBQuad, 0, nColors * sizeof( RGBQUAD ) );
BYTE bzColorMap[ 256 ][ 3 ];
if( !::Popularity( pBits, nBits, nWidth, nHeight, bzColorMap ) )
{
delete[] pRGBQuad;
return( GenerateFixedPalette( nColors ) );
}
for( int i=0; i<nColors; i++ )
{
pRGBQuad[ i ].rgbRed = bzColorMap[ i ][ 0 ];
pRGBQuad[ i ].rgbGreen = bzColorMap[ i ][ 1 ];
pRGBQuad[ i ].rgbBlue = bzColorMap[ i ][ 2 ];
}
return( pRGBQuad );
}
RGBQUAD *CImageObject::GenerateMedianCutPalette( int nColors, unsigned char *pBits, int nBits, int nWidth, int nHeight )
{
RGBQUAD *pRGBQuad = new RGBQUAD[ nColors ];
if( pRGBQuad == NULL )
return( GenerateFixedPalette( nColors ) );
memset( pRGBQuad, 0, nColors * sizeof( RGBQUAD ) );
BYTE bzColorMap[ 256 ][ 3 ];
WORD *Hist = new WORD[ 32768 ];
if( Hist == NULL )
{
delete [] pRGBQuad;
return( GenerateFixedPalette( nColors ) );
}
memset( Hist, 0, 32768 * sizeof( WORD ) );
int nWidthBytes = GetWidthInBytes( nBits, nWidth );
for( int y=0; y<nHeight; y++ )
{
unsigned char *pData = pBits;
unsigned char ucRed, ucGreen, ucBlue;
WORD wColor;
pData += ( y * nWidthBytes );
for( int x=0; x<nWidth; x++ )
{
switch( nBits )
{
case 16:
GET_RGB_16( ucRed, ucGreen, ucBlue, &pData[ 2*x ] );
break;
case 24:
ucRed = pData[ 3*x + 2 ];
ucGreen = pData[3*x + 1 ];
ucBlue = pData[ 3*x ];
break;
case 32:
GET_RGB_32( ucRed, ucGreen, ucBlue, &pData[ 4*x ] );
break;
}
wColor = _RGB( ucRed, ucGreen, ucBlue );
if( Hist[ wColor ] < 65535 )
Hist[ wColor ]++;
}
}
::MedianCut( Hist, bzColorMap, ( int )256 );
for( int i=0; i<nColors; i++ )
{
pRGBQuad[ i ].rgbRed = bzColorMap[ i ][ 0 ];
pRGBQuad[ i ].rgbGreen = bzColorMap[ i ][ 1 ];
pRGBQuad[ i ].rgbBlue = bzColorMap[ i ][ 2 ];
}
delete[] Hist;
return( pRGBQuad );
}
RGBQUAD *CImageObject::GenerateFixedPalette( int nColors )
{
RGBQUAD *pRGBQuad = new RGBQUAD[ nColors ];
if( pRGBQuad == NULL )
return( NULL );
static int nzColors[] = { 255, 255, 255, 0, 0, 0, 255, 0, 0, 0, 0, 255,
0, 255, 0, 150, 150, 150, 255, 255, 0, 0, 150, 150,
150, 0, 150, 150, 150, 0, 0, 255, 255, 255, 0, 255,
255, 120, 120, 120, 255, 120, 120, 120, 255, 90, 90, 90 };
int nSteps = ( ( nColors + 15 ) / 16 );
for( int i=0; i<nSteps; i++ )
{
for( int j=0; j<16; j++ )
{
if( i * 16 + j < nColors )
{
int r, g, b;
r = nzColors[ 3*j ];
g = nzColors[ 3*j + 1 ];
b = nzColors[ 3*j + 2 ];
r = ( ( nSteps - i ) * r ) / nSteps;
g = ( ( nSteps - i ) * g ) / nSteps;
b = ( ( nSteps - i ) * b ) / nSteps;
pRGBQuad[ 16*i + j ].rgbRed = ( unsigned char )r;
pRGBQuad[ 16*i + j ].rgbGreen = ( unsigned char )g;
pRGBQuad[ 16*i + j ].rgbBlue = ( unsigned char )b;
}
}
}
return( pRGBQuad );
}
// Diagnostics and dump member functions, overrided
#ifdef _DEBUG
void CImageObject::Dump( CDumpContext& dc ) const
{
// call base class function first
CObject::Dump( dc );
// now do the stuff for our specific class
// dc << "last name: " << m_lastName << "\n" << "first name: " << m_firstName << "\n";
}
void CImageObject::AssertValid() const
{
// call inherited AssertValid first
CObject::AssertValid();
// check CImageObject members...
// ASSERT( !m_strName.IsEmpty()); // Must have a name
// ASSERT( m_salary > 0 ); // Must have an income
}
#endif
/***********************************************************************
* Description: this function was added by maple,2004.3.18
*
* 函数名称:LoadDIBTOBuf
*
* 参数: BYTE * buf -- 传入的用于放置象素值的区域的指针
*
* 返回值: bool
*
* 说明: 该函数将图象DIB中对应的象素值转移到m_buf中,变成同一格式,
* 便于处理。
************************************************************************/
bool CImageObject::LoadDIBToBuf(BYTE * buf)
{
if(m_hDib == NULL)
return FALSE;
RGBQUAD color ;
COLORREF colorref;
if(m_pDib)
m_pDib = (BYTE *)::GlobalUnlock(m_hDib);
m_pDib = (BYTE *)::GlobalLock(m_hDib);
if(m_pDib!=NULL)
{
for( int j=0; j<m_nHeight; j++)
for(int i=0; i<m_nWidth; i++)
{
color = GetPixelColor( i, j );
colorref =RGB(color.rgbRed, color.rgbGreen, color.rgbBlue);
unsigned long temp=(long)j*(long)m_nWidth*3+(long)i*3;
*(buf+temp)=GetBValue(colorref);
*(buf+temp+1)=GetGValue(colorref);
*(buf+temp+2)=GetRValue(colorref);
}
}
::GlobalUnlock(m_hDib);
return TRUE;
}
/***********************************************************************
* Description: this function was added by maple,2004.3.18
*
* 函数名称:UpdateDIB
*
* 参数: int nNewWidth -- 图象经过处理后新的宽度
* int nNewHeight -- 图象经过处理后新的高度
*
* 返回值: bool
*
* 说明: 该函数用处理后的buf中的象素值来更新DIB,
* 并根据传入的新的高度和宽度来决定是否新建一DIB。
************************************************************************/
bool CImageObject::UpdateDIB(int nNewWidth,int nNewHeight,BYTE * buf)
{
// if the size of the image has no change,
// we only need to update the old DIB.
if(nNewWidth == m_nWidth && nNewHeight == m_nHeight)
{
RGBQUAD color ;
if(m_pDib!=NULL)
::GlobalUnlock(m_hDib);
m_pDib = (BYTE *)::GlobalLock(m_hDib);
if(m_pDib!=NULL)
{
for( int j=0; j<m_nHeight; j++)
for( int i=0; i<m_nWidth; i++)
{
unsigned long temp=(long)j*(long)m_nWidth*3+(long)i*3;
BYTE r,g,b;
b=*(buf+temp);
g=*(buf+temp+1);
r=*(buf+temp+2);
color.rgbRed = r ;
color.rgbGreen = g;
color.rgbBlue = b;
SetPixelColor( i, j, color ) ;
}
::GlobalUnlock(m_hDib);
return(true);
}
else
{
::GlobalUnlock(m_hDib);
return(false);
}
}
// the size of the image has been changed
// we must create a new DIb to replace the old one.
else
{
RGBQUAD color ;
HGLOBAL hNewDib;
DWORD dwNewSize;
BYTE * pNewBuf;
BYTE * pNewBits;
BITMAPFILEHEADER *pOldBFH,*pNewBFH;
BITMAPINFOHEADER *pOldBIH,*pNewBIH;
RGBQUAD *pOldPalette,*pNewPalette;
if(m_pDib!=NULL)
::GlobalUnlock(m_hDib);
m_pDib = (BYTE *)::GlobalLock(m_hDib);
if(m_pDib==NULL)
{
::GlobalUnlock(m_hDib);
return(false);
}
dwNewSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)
+m_nColors*sizeof(RGBQUAD)+GetWidthInBytes(m_nBits,nNewWidth)*nNewHeight;
hNewDib = :: GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,dwNewSize);
if(hNewDib==NULL)
{
::GlobalUnlock(m_hDib);
return (false);
}
pNewBuf = (BYTE *)::GlobalLock(hNewDib);
if(pNewBuf==NULL)
{
::GlobalFree(hNewDib);
::GlobalUnlock(m_hDib);
return (false);
}
pOldBFH = (BITMAPFILEHEADER *)m_pDib;
pOldBIH = (BITMAPINFOHEADER *)(m_pDib+sizeof(BITMAPFILEHEADER));
pOldPalette = (RGBQUAD *)(m_pDib+sizeof(BITMAPFILEHEADER)+
sizeof(BITMAPINFOHEADER));
pNewBFH = (BITMAPFILEHEADER *) pNewBuf;
pNewBIH = (BITMAPINFOHEADER *) (pNewBuf+sizeof(BITMAPFILEHEADER));
pNewPalette = (RGBQUAD *)(pNewBuf+sizeof(BITMAPFILEHEADER)+
sizeof(BITMAPINFOHEADER));
pNewBits = pNewBuf+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)
+m_nColors*sizeof(RGBQUAD);
*pNewBFH = *pOldBFH;
*pNewBIH = *pOldBIH;
pNewBFH->bfSize = dwNewSize;
pNewBIH->biWidth = (LONG)nNewWidth;
pNewBIH->biHeight = (LONG)nNewHeight;
pNewBIH->biSizeImage = (DWORD)GetWidthInBytes(m_nBits,nNewWidth)*nNewHeight;
for(int k=0;k<m_nColors;k++)
pNewPalette[k] = pOldPalette[k];
// very important!!
// if we miss the following two lines,the display of the image
m_nWidth = nNewWidth;
m_nHeight = nNewHeight;
m_nPlanes = pNewBIH->biPlanes;
m_nBits = pNewBIH->biBitCount;
m_nColors = pNewBIH->biClrUsed;
m_nPaletteInBytes = m_nColors*sizeof(RGBQUAD);
// will be wrong!
::GlobalUnlock(m_hDib);
::GlobalFree(m_hDib);
::GlobalUnlock(hNewDib);
SetDib(hNewDib);
if(m_pDib)
m_pDib = (BYTE *)::GlobalUnlock(m_hDib);
m_pDib = (BYTE *)::GlobalLock(m_hDib);
if(m_pDib!=NULL)
{
for( int j=0; j<m_nHeight; j++)
for( int i=0; i<m_nWidth; i++)
{
unsigned long temp=(long)j*(long)m_nWidth*3+(long)i*3;
BYTE r,g,b;
b=*(buf+temp);
g=*(buf+temp+1);
r=*(buf+temp+2);
color.rgbRed = r ;
color.rgbGreen = g;
color.rgbBlue = b;
SetPixelColor( i, j, color ) ;
}
::GlobalUnlock(m_hDib);
return TRUE;
}
else
{
::GlobalUnlock(m_hDib);
return(false);
}
}
}
/***********************************************************************
* Description: this function was added by maple,2004.3.22
*
* 函数名称:CreatDIBFromBits
*
* 参数: int nWidth -- 要新建的图象的宽度
* int nHeight -- 要新建的图象的高度
* BYTE * buf -- 存放象素值的内存区域指针
*
* 返回值: bool
*
* 说明: 该函数利用一块存放象素值的内存区域来创建一个DIB,所
* 创建的图象是24位位图。
************************************************************************/
bool CImageObject::CreateDIBFromBits(int nWidth,int nHeight,BYTE * buf)
{
RGBQUAD color;
HGLOBAL hDib;
DWORD dwSize;
BYTE * pBuf;
BITMAPFILEHEADER *pBFH;
BITMAPINFOHEADER *pBIH;
dwSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)
+GetWidthInBytes(24,nWidth)*nHeight;
hDib = :: GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,dwSize);
if(hDib==NULL)
{
return (false);
}
pBuf = (BYTE *)::GlobalLock(hDib);
if(pBuf==NULL)
{
::GlobalFree(hDib);
return (false);
}
pBFH = (BITMAPFILEHEADER *) pBuf;
pBIH = (BITMAPINFOHEADER *) (pBuf+sizeof(BITMAPFILEHEADER));
pBFH->bfType = (WORD)19778;
pBFH->bfSize = (DWORD)dwSize;
pBFH->bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
pBIH->biSize = (DWORD)40;
m_nWidth = pBIH->biWidth = (LONG)nWidth;
m_nHeight = pBIH->biHeight = (LONG)nHeight;
m_nPlanes = pBIH->biPlanes = (WORD)1;
m_nBits = pBIH->biBitCount = (WORD)24;
pBIH->biCompression = BI_RGB;
pBIH->biSizeImage = (DWORD)GetWidthInBytes(24,nWidth)*nHeight;
// pBIH->biXPelsPerMeter = (LONG)4724;
// pBIH->biYPelsPerMeter = (LONG)4724;
m_nColors = pBIH->biClrUsed = (DWORD)0;
pBIH->biClrImportant = (DWORD)0;
m_nPaletteInBytes = 0; // used in Draw()
::GlobalUnlock(hDib);
SetDib(hDib);
if(m_pDib)
m_pDib = (BYTE *)::GlobalUnlock(m_hDib);
m_pDib = (BYTE *)::GlobalLock(m_hDib);
if(m_pDib!=NULL)
{
BYTE * pBits = m_pDib+sizeof(BITMAPFILEHEADER)
+sizeof(BITMAPINFOHEADER);
for( int k=0; k<GetWidthInBytes(24,nWidth)*nHeight; k++)
pBits[k] = 0;
for( int j=0; j<m_nHeight; j++)
for( int i=0; i<m_nWidth; i++)
{
unsigned long temp=(long)j*(long)m_nWidth*3+(long)i*3;
BYTE r,g,b;
b=*(buf+temp);
g=*(buf+temp+1);
r=*(buf+temp+2);
color.rgbRed = r ;
color.rgbGreen = g;
color.rgbBlue = b;
SetPixelColor( i, j, color ) ;
}
::GlobalUnlock(m_hDib);
return TRUE;
}
else
{
::GlobalUnlock(m_hDib);
return(false);
}
}
/***********************************************************************
* Description: this function was added by maple,2004.3.22
*
* 函数名称:CreatFromHANDLE
*
* 参数: HANDLE handle -- 要新建的图象的宽度
*
* 返回值: bool
*
* 说明: 该函数利用从剪贴板获得的标准DIB句柄创建一个用于
* 该ImageObject的包含BITMAPFILEHEADER的DIB。
************************************************************************/
bool CImageObject::CreateFromHANDLE(HANDLE handle)
{
HANDLE hDib;
BYTE * pBuf,*pTemp;
BITMAPFILEHEADER *pBFH;
BITMAPINFOHEADER *pBIH;
DWORD size = ::GlobalSize(handle);
DWORD dwSize = ::GlobalSize(handle)+sizeof(BITMAPFILEHEADER);
hDib = :: GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,dwSize);
if(hDib==NULL)
{
return (false);
}
pBuf = (BYTE *)::GlobalLock(hDib);
if(pBuf==NULL)
{
::GlobalFree(hDib);
return(false);
}
pTemp = (BYTE *)::GlobalLock(handle);
if(pTemp==NULL)
{
return (false);
}
pBFH = (BITMAPFILEHEADER *)pBuf;
pBFH->bfType = (WORD)19778;
pBFH->bfSize = (DWORD)dwSize;
pBFH->bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
memcpy(pBuf+sizeof(BITMAPFILEHEADER),pTemp,size);
pBIH = (BITMAPINFOHEADER *)(pBuf+sizeof(BITMAPFILEHEADER));
m_nWidth = pBIH->biWidth;
m_nHeight = pBIH->biHeight;
m_nPlanes = pBIH->biPlanes;
m_nBits = pBIH->biBitCount;
m_nColors = pBIH->biClrUsed;
m_nPaletteInBytes = m_nColors*sizeof(RGBQUAD);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -