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

📄 image.cpp

📁 图像标注程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/***************************************************************/
/*文件名:     image.cpp               				           */
/*文件描述:                                                   */
/*相关文件:   global.h, global.cpp, image.h	               */
/*主要函数:                                                   */
/*提交日期:                        作  者:刘岩、山世光       */
/*编 辑 器: Visual C++                                        */
/*版权:哈尔滨工业大学智能接口实验室 中科院计算所数字媒体实验室*/
/*版权说明:任何使用必须保留版权信息和历史纪录信息			   */
/*修改纪录:												   */
/*日  期        版本        修改人         修改内容            */
/*03/22/1999    2.0         山世光         ---------           */
/*05/22/2000    3.0         山世光         ---------           */
/***************************************************************/

#include "stdafx.h"
#include "math.h"
#include "ijl.h"
#include "image.h"
#include "globalfunc.h"

#include <math.h>  // for sqrt()
#include <windowsx.h>  // for GlobalAllocPtr

#define		MAXIMAGESIZE    (3 * 65536) //
const int CImage::GREY=256;

IMPLEMENT_SERIAL(CImage, CObject, 0)

///////////////////////////////////////////////////////////////////
CImage::CImage(): m_bIsDIB(TRUE),m_dwLength(0L),
m_pDib (NULL),m_pData(NULL)
{
	m_pPal	=new CPalette;
}

///////////////////////////////////////////////////////////////////
CImage::CImage(const CImage& img)//copy constructor
{
	m_bIsDIB=img.m_bIsDIB;
	m_dwLength=img.m_dwLength;
	m_pDib=0;
	if(img.m_pDib){
		//m_pDib=(BYTE*) GlobalAllocPtr(GHND, m_dwLength);
		m_pDib = new BYTE[m_dwLength]; 
		if(!m_pDib)
		{
			AfxMessageBox("Unable to allocate DIB memory");
			return;
		}
		memcpy(m_pDib,img.m_pDib,m_dwLength);
		m_pData = (BYTE*) m_pDib + sizeof(BITMAPINFOHEADER) +
			sizeof(RGBQUAD) * img.NumColors();
	}
	m_pPal=new CPalette;
	CreateDIBPalette();
}

///////////////////////////////////////////////////////////////////
CImage::CImage(CImage& img,	CPoint start,	CSize size)
{
	int		bpp;
	int		bytepp;
	long	hdlen;/*size of the DIB header info*/
	LPBITMAPINFOHEADER pBMIH;
	
	ASSERT(img.m_pDib);
	WORD dww=img.Width();
	WORD dwh=img.Height();
	if(( (size.cx+start.x)>dww )||( (size.cy+start.y)>dwh )){
		AfxMessageBox("Image size is too large!");
		return;
	}
	img.Data();
	
	m_bIsDIB = FALSE;
    hdlen = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * img.NumColors();
	
	bpp		= img.Bits();
	bytepp	= bpp / 8;
	
	ASSERT(bpp != 16 && bpp != 32);
	
    DWORD bypeinoneline = ByteNumForOneLine((WORD)size.cx, bpp);//Bytes per line
	
    m_dwLength = hdlen + bypeinoneline * size.cy;
	
    if (!AllocateMemory( )){
		return;
	}
	memcpy(m_pDib, img.m_pDib, hdlen);
	
    pBMIH = BMInfoHdPtr();
    pBMIH->biWidth = size.cx;
    pBMIH->biHeight = size.cy;
    pBMIH->biSizeImage = size.cx * size.cy * bytepp;
	
    m_pData =  (BYTE*)(m_pDib + hdlen);
	
	BYTE* p1, *p2;
	long  t1, t2;
	t1 = dww * bytepp;
	t2 = size.cx * bytepp;
	p1 = ( BYTE* ) ( img.m_pData + (start.y * dww + start.x) * bytepp);
	p2 = m_pData;
	for(int i=0 ; i<(int)size.cy; i++)
	{
		memcpy(p2 , p1 , t2);
		p1 += t1;
		p2 += t2;
	}
	
	Dib();	
	img.Dib();
	m_pPal=new CPalette;
	CreateDIBPalette();
}
///////////////////////////////////////////////
/*the constructor used to create a DIB of size 'size'
with no initializing image data*/
CImage::CImage(CSize size,int NumColor,int Bits)
{
    LPBITMAPINFOHEADER pBMIH;
    m_dwLength = sizeof(BITMAPINFOHEADER) + 
		sizeof(RGBQUAD) * NumColor;
    if (!AllocateMemory()) return;
	DWORD dwBytes = Transform((WORD)size.cx);
	
    m_dwLength += dwBytes * size.cy * Bits / 8;
    if (!AllocateMemory(TRUE)){
		return;
	}
    pBMIH=BMInfoHdPtr();
	pBMIH->biSize = sizeof(BITMAPINFOHEADER);
    pBMIH->biWidth = size.cx;
    pBMIH->biHeight = size.cy;
    pBMIH->biSizeImage = size.cx*size.cy;
    pBMIH->biPlanes = 1;
    pBMIH->biBitCount = Bits; // 1, 4, 8, or 24
    pBMIH->biCompression = BI_RGB;
    pBMIH->biXPelsPerMeter = 0;
    pBMIH->biYPelsPerMeter = 0;
    pBMIH->biClrUsed = 0;
    pBMIH->biClrImportant = 0;
    m_pData =  (BYTE*)(m_pDib + sizeof(BITMAPINFOHEADER) +
		sizeof(RGBQUAD) * NumColor);
	SetDIB();
	m_pPal=new CPalette;
	CreateGreyPalette();
}

///////////////////////////////////////////////////////////////////
//part copy constructor
CImage& CImage::operator=(const CImage& img)
{
	m_bIsDIB=img.m_bIsDIB;
	m_dwLength=img.m_dwLength;
	if(img.m_pDib){
		TRY	{
			if(m_pDib){
			/*	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]; 
			}
		}
		CATCH (CMemoryException, e) {
			AfxMessageBox("Unable to allocate DIB memory");
			return *this;
		}
		END_CATCH
			
			memcpy(m_pDib,img.m_pDib,m_dwLength);
		m_pData = (BYTE*)((BYTE*) m_pDib + sizeof(BITMAPINFOHEADER) +
			sizeof(RGBQUAD) * img.NumColors());
	}else
	{
		GlobalFree(m_pDib);
		m_pDib=0;
	}
	if(m_pPal) delete m_pPal;
	m_pPal=new CPalette;
	CreateDIBPalette();
	return *this;
}

///////////////////////////////////////////////////////////////////
CImage::CImage(CDC* pDC, int nBt, BOOL bCompr):m_bIsDIB(TRUE)
/* pDC is memory DC ptr	and  Cbitmap object has been selected into it 
nBt is color bits per pixel (default = 0)
bCompr is compression (default = TRUE)
*/
{
	// constructs a DIB from the contents of a bitmap
    BITMAP bm;
    int    nPaletteSize,wBits;
	LPBITMAPINFOHEADER pBMIH;
	LPBITMAPINFO pBMI;
	
    CBitmap* pEmptyBitmap = new CBitmap;
    pEmptyBitmap->CreateCompatibleBitmap(pDC, 0, 0);
    CBitmap* pBitmap = (CBitmap*) (pDC->SelectObject(pEmptyBitmap));
    pBitmap->GetObject(sizeof(bm), &bm);
    if ((nBt == 1) || (nBt == 4) || (nBt == 8) || (nBt == 24)) {
        wBits = nBt;
    }
    else {   // nBt = 0
        wBits = bm.bmPlanes * bm.bmBitsPixel; // color bits per pixel
    }
    if (wBits == 1) {
        nPaletteSize = 2;
    }
    else {
        if (wBits == 4) {
            nPaletteSize = 16;
        }
        else {
            if (wBits == 8) {
                nPaletteSize = 256;
            }
            else {
                nPaletteSize = 0; // no palette for 24-bit display
            } 
        }
    }
    // fills out row to 4-byte boundary
    DWORD dwBytes = ((DWORD) bm.bmWidth * wBits) / 32;
    if (((DWORD) bm.bmWidth * wBits) % 32) {
        dwBytes ++;
    }
    dwBytes *= 4;//pixels per line
	
    m_dwLength = sizeof(BITMAPINFOHEADER) + 
		sizeof(RGBQUAD) * nPaletteSize;
    if (!AllocateMemory()) return;
    
    pBMIH=BMInfoHdPtr();
	pBMIH->biSize = sizeof(BITMAPINFOHEADER);
    pBMIH->biWidth = bm.bmWidth;
    pBMIH->biHeight = bm.bmHeight;
    pBMIH->biPlanes = 1;
    pBMIH->biBitCount = wBits; // 1, 4, 8, or 24
    if (bCompr && (wBits == 4)) {
        pBMIH->biCompression = BI_RLE4;
    }
    else {
        if (bCompr && (wBits == 8)) { 
            pBMIH->biCompression = BI_RLE8;
        }
        else {
            pBMIH->biCompression = BI_RGB;
        } 
    }
    pBMIH->biSizeImage = 0;
    pBMIH->biXPelsPerMeter = 0;
    pBMIH->biYPelsPerMeter = 0;
    pBMIH->biClrUsed = 0;
    pBMIH->biClrImportant = 0;
	
    // calls GetDIBits with null data pointer to get size of DIB
    pBMI=BMInfoPtr();
	::GetDIBits(pDC->GetSafeHdc(), (HBITMAP) pBitmap->GetSafeHandle(),
		0, (WORD) bm.bmHeight, NULL, pBMI, DIB_RGB_COLORS);
	
    if (pBMIH->biSizeImage == 0) {//pBMIH????orpBMI
        m_dwLength += dwBytes * bm.bmHeight;
        pBMIH->biCompression = BI_RGB;
        // escape route for device drivers that don't do compression
        TRACE("Can't do compression\n");
    }
    else {
        m_dwLength += pBMIH->biSizeImage;
    }
    if (!AllocateMemory(TRUE)) {
        return;
    }
    pBMIH=BMInfoHdPtr();
    pBMI=BMInfoPtr();
    m_pData = (BYTE*) pBMIH + sizeof(BITMAPINFOHEADER) +
		sizeof(RGBQUAD) * nPaletteSize;
	
    // second GetDIBits call to make DIB
    if (!::GetDIBits(pDC->GetSafeHdc(), (HBITMAP)
        pBitmap->GetSafeHandle(), 0, (WORD) bm.bmHeight, m_pData,
        pBMI, DIB_RGB_COLORS)) {
        m_dwLength = 0L;
    }
    delete pDC->SelectObject(pBitmap); // delete pEmptyBitmap
	Dib();
	m_pPal=new CPalette;
	CreateDIBPalette();
}

///////////////////////////////////////////////////////////////////
CImage::CImage(CImage& img, float scale)
{
	WORD scrw,scrh,destw,desth;
	DWORD dwDIBHeadLength;
	
	img.Data();
	m_bIsDIB = img.m_bIsDIB;
	
	scrw  = img.Width();
	scrh  = img.Height();
	destw = (WORD) (scrw * scale);
	desth = (WORD) (scrh * scale);
	
	dwDIBHeadLength = sizeof(BITMAPINFOHEADER) + 
		sizeof(RGBQUAD) * img.NumColors();
	DWORD dwBytes = Transform(destw);
	m_dwLength = dwDIBHeadLength + (DWORD) dwBytes * desth;
	
	m_pDib = NULL;
	if(img.m_pDib)
	{
//		m_pDib=(BYTE*) GlobalAllocPtr(GHND, m_dwLength);
		m_pDib = new BYTE[m_dwLength]; 
		if(!m_pDib){
			AfxMessageBox("Unable to allocate DIB memory");
			return;
		}
		memcpy(m_pDib, img.m_pDib, dwDIBHeadLength);
		m_pData = (BYTE*) m_pDib + sizeof(BITMAPINFOHEADER) +
			sizeof(RGBQUAD) * img.NumColors();
	}
	//shrink the image
	ResizeImage(img.m_pData, scrw, scrh, m_pData, destw, desth);
	
    LPBITMAPINFOHEADER pBMIH;
    pBMIH=BMInfoHdPtr();
    pBMIH->biWidth = destw;
    pBMIH->biHeight = desth;
	
	Dib();						img.Dib();
	m_pPal=new CPalette;		CreateDIBPalette();		
}

///////////////////////////////////////////////////////////////////
//before usere call this construction, 
//must guarentee img.Bits() == 8
CImage::CImage(CImage & img, CSize newSize)
{	
	int		bpp, byteperline;
	WORD	scrw,	scrh,	destw,	desth;
	DWORD	dwDIBHeadLength;
	
	img.Data();
	m_bIsDIB = img.m_bIsDIB;
	
	bpp = img.Bits(); 
	if(bpp != 8)
		return;
	destw  = (WORD) newSize.cx;
	desth  = (WORD) newSize.cy;
	scrw   = img.Width();
	scrh   = img.Height();
	
	if((destw-scrw)*(desth-scrh) < 0)
	{
		//AfxMessageBox("Current version only support!");
		//return;
	}
	byteperline = ByteNumForOneLine(destw, bpp);
	
	dwDIBHeadLength = sizeof(BITMAPINFOHEADER) + 
		sizeof(RGBQUAD) * img.NumColors();
	
	m_dwLength = dwDIBHeadLength + (DWORD) byteperline * desth;
	
	m_pDib = NULL;
	if(img.m_pDib)
	{
//		m_pDib=(BYTE*) GlobalAllocPtr(GHND, m_dwLength);
		m_pDib = new BYTE[m_dwLength]; 
		if(!m_pDib){
			AfxMessageBox("Unable to allocate DIB memory");
			return;
		}
		memcpy(m_pDib, img.m_pDib, dwDIBHeadLength);
		m_pData = (BYTE*) m_pDib + sizeof(BITMAPINFOHEADER) +
			sizeof(RGBQUAD) * img.NumColors();
	}
	
	Data();
	ResizeImage(img.Data(), scrw, scrh, m_pData, 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) 
       // delete []m_pDib;  // free the DIB memory
	   delete []m_pDib;
    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);
	

⌨️ 快捷键说明

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