📄 image.cpp
字号:
pDestByte++;
pByteB++;
*pDestByte = *pByteG;
pDestByte++;
pByteG++;
*pDestByte = *pByteR;
pDestByte++;
pByteR++;
}
delete [] pSrcByteRGB;
delete [] pDestByteRGB;
}
else
{
if((destw < scrw)&&(desth < scrh))
ShrinkImage(img.m_pData, m_pData, scrw, scrh, destw, desth);
else //Magnify the image
MagnifyImage(img.m_pData, m_pData, scrw, scrh, destw, desth);
}
LPBITMAPINFOHEADER pBMIH;
pBMIH=BMInfoHdPtr();
pBMIH->biWidth = destw;
pBMIH->biHeight = desth;
Dib(); img.Dib();
m_pPal=new CPalette; CreateDIBPalette();
}
///////////////////////////////////////////////////////////////////
CImage::~CImage()
{
if(m_dwLength != 0L)
GlobalFreePtr(m_pDib); // free the DIB memory
if(m_pPal)
delete m_pPal;
}
///////////////////////////////////////////////////////////////////
void CImage::Serialize(CArchive& ar)
{
ar.Flush();
if (ar.IsStoring())
{
WriteToFile(ar.GetFile());
}
else
{
ReadFromFile(ar.GetFile());
}
}
///////////////////////////////////////////////////////////////////
BOOL CImage::WriteAsBMP(CFile* pFile)
{
Dib();
BITMAPFILEHEADER bmfHdr; // Header for Bitmap file
LPBITMAPINFOHEADER pBMIH=BMInfoHdPtr(); // Pointer to DIB info structure
if (m_pDib == NULL)
return FALSE;
/* Fill in file type (first 2 bytes must be "BM" for a bitmap) */
bmfHdr.bfType = 0x4d42; // "BM"
// Calculate the file size by adding the DIB size to sizeof(BITMAPFILEHEADER)
bmfHdr.bfSize = m_dwLength + sizeof(BITMAPFILEHEADER);
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + pBMIH->biSize
+ NumColors()*sizeof(RGBQUAD);
WORD hdLength=sizeof(BITMAPINFOHEADER)
+ NumColors()*sizeof(RGBQUAD);
TRY {
// Write the file header
pFile->Write((BYTE*)&bmfHdr, sizeof(BITMAPFILEHEADER));
// Write the DIB header
pFile->Write(m_pDib, hdLength);
// Write the DIB bits
pFile->Write(m_pData, m_dwLength-hdLength);
}
CATCH (CFileException, e) {
AfxMessageBox("Write error--possible disk full condition");
return FALSE;
}
END_CATCH
return TRUE;
}
///////////////////////////////////////////////////////////////////
/* The MakeBitmap()
CDC* pDoc : Device Context
bmSize : Change the parameter and return it
Function: Replaces the DC's old existing bitmap
with the new one construced from this DIB
Return Value: the old bitmap in DC
*/
////////////////////////////////////////////////////////
CBitmap* CImage::MakeBitmap(CDC* pDC, CSize& bmSize)
{
BITMAP bm;
DWORD dwFore, dwBack;
LPBITMAPINFOHEADER pBMIH = BMInfoHdPtr();
LPBITMAPINFO pBMI = BMInfoPtr();
// checks to see whether DIB buffer is properly loaded
if (m_dwLength == 0L) {
bmSize.cx = bmSize.cy = 0;
return NULL;
}
// this code conditions the DC for mono or color
SetPalette(pDC);
int nPlanes = pDC->GetDeviceCaps(PLANES);
int nBitsPixel = pDC->GetDeviceCaps(BITSPIXEL);
CBitmap* pConfigBitmap = new CBitmap;
char bits[100];
if (pBMIH->biBitCount == 1) {
pConfigBitmap->CreateBitmap(1, 1, 1, 1, bits);
}
else {
pConfigBitmap->CreateBitmap(1, 1, nPlanes, nBitsPixel, bits);
}
CBitmap* pOriginalBitmap =
(CBitmap*) pDC->SelectObject(pConfigBitmap);
// CreateDIBitmap "switches bits" for mono bitmaps, depending on colors,
// so we'll fool it
if (GetMonoColors(dwFore, dwBack)) {
SetMonoColors(0L, 0xFFFFFFL);
}
//the following CreateDIBitmap() creates a DDB from this DIB
//#ifdef _WIN32
HBITMAP hBitmap = ::CreateDIBitmap(pDC->GetSafeHdc(), pBMIH,
CBM_INIT, (CONST BYTE*) m_pData, pBMI, DIB_RGB_COLORS);
//#else
// HBITMAP hBitmap = ::CreateDIBitmap(pDC->GetSafeHdc(), pBMIH,
// CBM_INIT, (BYTE*) m_pData, pBMI, DIB_RGB_COLORS);
//#endif
if (hBitmap == NULL) {
TRACE("null bitmap\n");
delete pDC->SelectObject(pOriginalBitmap); // delete config bitmap
return NULL; // untested error logic
}
SetMonoColors(dwFore, dwBack);
// Can't use CBitmap::FromHandle here because we need to
// delete the object later
CBitmap* pBitmap = new CBitmap;
pBitmap->Attach(hBitmap);
pBitmap->GetObject(sizeof(bm), &bm);
bmSize.cx = bm.bmWidth;
bmSize.cy = bm.bmHeight;
delete pDC->SelectObject(pBitmap); // delete configuration bitmap
return pOriginalBitmap;
}
///////////////////////////////////////////////////////////////////
//create a DIBpalette according to the palette info in the inforhead of object
BOOL CImage::CreateDIBPalette()
{
LPLOGPALETTE lpPal; // pointer to a logical palette
LPBITMAPINFO pBMI = BMInfoPtr();
int i; // loop index
WORD wNumColors; // number of colors in color table
BOOL bResult=FALSE;
/* if handle to DIB is invalid, return FALSE */
if (!m_pDib) return FALSE;
/* get the number of colors in the DIB */
Dib();
wNumColors = NumColors();
if (wNumColors != 0)
{
/* allocate memory block for logical palette */
/* 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.3
+ 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.3)
+ (float)(pColData[t2+2] * 0.59));
}
}
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
}
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -