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

📄 image.cpp

📁 图像标注程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	// 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.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
{
    if (bRealloc) {  
        /*m_pDib = (BYTE*) GlobalReAllocPtr(m_pDib,
			m_dwLength, GHND);*/
		delete []m_pDib;
		m_pDib = new BYTE[m_dwLength];
    }
    else {
        //m_pDib = (BYTE*) GlobalAllocPtr(GHND, m_dwLength);
		m_pDib = new BYTE[m_dwLength];
    }
    if (!m_pDib) {
        AfxMessageBox("Unable to allocate DIB memory");
        m_dwLength = 0L;
        return FALSE;
    }
    return TRUE;
}
/*Record of Modify
*	Date		Operator	Modify			
* 1999.4.9		S.S.G		if the width of the bitmap can not be inter-divided by 8
*							We must alloc enough additional memory!! and some situations
*							must be processed
*/
BOOL CImage::ReadFromBMP(CFile * pFile)
{
	BITMAPFILEHEADER bmfHdr; // Header for Bitmap file
	BITMAPINFOHEADER bmhdr;	 //header for bitmap info

⌨️ 快捷键说明

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