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

📄 cdibimage.cpp

📁 程序在visual c++环境下实现了图像按照输入参数进行平移旋转和在水平垂直方向上的镜像功能。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	{
		BYTE* pRenewData = NULL;
		GetBackBitbuf( pRenewData, dwWidth);
		File.Seek( bfh.bfOffBits, 0);
		for( DWORD i=0;i<m_dwHeight;i++)
		{
			File.Write( pRenewData+nPos, dwWidth);
			File.Seek( skip, 1);
			nPos -= dwWidth;
		}
		delete[] pRenewData;
		pRenewData = NULL;
	}
	char ch = '/0';
	File.Close();
	return;
}
//
//
//
BYTE* CDibImage::GetBackBitbuf( BYTE*& pRenewData, DWORD dwRealWidth)
{
	if( pRenewData ) 
		delete[] pRenewData;
	pRenewData = new BYTE[m_dwHeight*dwRealWidth];

	DWORD i,j;//循环变量
	if(m_wBPP == 1)
	{
		BYTE tmp,bBack;
		for( i=0;i<m_dwHeight;i++)
		for( j=0;j<m_dwWidth;j++)
		{
			bBack = 0;
			for( int k=0;k<8;k++)
			{
				tmp = m_pBitbuf[i*m_dwWidth*4 + j*4];
				if( tmp == 255)
				{
					bBack = bBack | (1<<(7-k));
					j++;
				}
				else j++;
				if( k==7)
				{
					pRenewData[dwRealWidth*i + (int)(j-7)/8] = bBack;
				}
			}
			j = j-1;
		}
	}
	else if(m_wBPP == 4)
	{
		BYTE tmp,bit;//临时变量
		BYTE *pbuf = new BYTE[m_dwWidth*4];
		for( i=0;i<m_dwHeight;i++)
		{
			memcpy( pbuf, m_pBitbuf, m_dwWidth*4);
			tmp = pbuf[0];
			for( j=0;j<m_dwWidth;j++)
			{
				if(j%2)
				{
					bit = pbuf[j*4];
					tmp = tmp | (bit & 0x0f);
					pRenewData[i*dwRealWidth + j/2] = tmp;
					if((j+1)<m_dwWidth)
					{
						tmp = pbuf[(j+1)*4];
					}
				}
				else
				{
					tmp = (tmp<<4) & 0xf0;
				}
			}
		}
	}
	else if(m_wBPP == 8)
	{
		for( i=0;i<m_dwHeight;i++)
		for( j=0;j<m_dwWidth;j++)
		{
			pRenewData[i*dwRealWidth + j] = m_pBitbuf[i*m_dwWidth*4 + j*4];
		}
	}
	else if(m_wBPP == 24)
	{
		for( i=0;i<m_dwHeight;i++)
		for( j=0;j<m_dwWidth;j++)
		{
			pRenewData[i*dwRealWidth + j*3] = m_pBitbuf[i*m_dwWidth*4 + j*4];
			pRenewData[i*dwRealWidth + j*3 + 1] = m_pBitbuf[i*m_dwWidth*4 + j*4 + 1];
			pRenewData[i*dwRealWidth + j*3 + 2] = m_pBitbuf[i*m_dwWidth*4 + j*4 + 2];
		}
	}
	return pRenewData;
}

/*操作图像的函数*********************************************************
*
*
*
************************************************************************/

///////////////////////////////////////////////////////////////////////////////////////
//函数名:
//       Draw2DC()
//参数:
//       CDC *dc-输出的设备上下文dc
//说明:
//       显示已经读取的图像信息
///////////////////////////////////////////////////////////////////////////////////////
void CDibImage::Draw2DC( CDC *dc)
{
	if(!m_pBitbuf) return;
	BITMAPINFO bmi;
	DWORD BytePerPixel = 4;
    DWORD dwSize = m_dwWidth*m_dwHeight*BytePerPixel;//计算图像数据的大小

	//填充位图信息头
	bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmi.bmiHeader.biWidth = m_dwWidth;
	bmi.bmiHeader.biHeight = -m_dwHeight;
	bmi.bmiHeader.biPlanes = 1;
	bmi.bmiHeader.biBitCount = BytePerPixel*8;
	bmi.bmiHeader .biClrImportant = 0;
	bmi.bmiHeader .biSizeImage = dwSize;
	bmi.bmiHeader.biXPelsPerMeter = m_dwWidth;
	bmi.bmiHeader.biYPelsPerMeter = m_dwHeight;
	bmi.bmiHeader.biCompression = 0;
	bmi.bmiHeader .biClrUsed = 0;
	StretchDIBits(dc->GetSafeHdc(),0,0,m_dwWidth,m_dwHeight,
                 0,0,m_dwWidth,m_dwHeight,(UINT *)m_pBitbuf,&bmi,
                 DIB_RGB_COLORS	,SRCCOPY);

}


/////////////////////////////////////////////////////////////////////////
//函数名:
//       RotateAngle()
//参数:
//       double dAngle -指定需要旋转的度数
//说明:
//按照用户指定的度数旋转指定图像
////////////////////////////////////////////////////////////////////////
void CDibImage::RotateAngle( double dAngle)
{
	DWORD dwWidth;      //旋转后新图的宽度
	DWORD dwHeight;     //旋转后新图的高度
    DWORD  i,j,i0,j0;   //循环变量
    float fRotateAngle; //旋转角度(弧度)
	
	BYTE* pNewbuf = NULL;
	float fSina,fCosa;  //旋转角度的正弦和余弦
	//原图的4个叫的坐标(以图像中心为坐标系原点)
	float fSrcX1,fSrcY1,fSrcX2,fSrcY2,fSrcX3,fSrcY3,fSrcX4,fSrcY4;
	//旋转后4个角的坐标(以图像为坐标系原点)
	float fDstX1,fDstY1,fDstX2,fDstY2,fDstX3,fDstY3,fDstX4,fDstY4;
	float f1,f2;
	//将旋转角度转换到弧度
    fRotateAngle = (float)RADIAN(dAngle);
	fSina = (float)sin((double)fRotateAngle);//计算旋转角度的正弦
	fCosa = (float)cos((double)fRotateAngle);//计算旋转角度的余弦

	//计算原图的4个点角的坐标(以图像中心为坐标系原点)
	fSrcX1 = (float)(-((float)m_dwWidth-1)/2);
	fSrcY1 = (float)(((float)m_dwHeight-1)/2);
	fSrcX2 = (float)(((float)m_dwWidth-1)/2);
	fSrcY2 = (float)(((float)m_dwHeight-1)/2);
	fSrcX3 = (float)(-(float)(m_dwWidth-1)/2);
    fSrcY3 = (float)(-(float)(m_dwHeight-1)/2);
	fSrcX4 = (float)((float)(m_dwWidth-1)/2);
    fSrcY4 = (float)(-(float)(m_dwHeight-1)/2);

	//计算新图4个角的坐标(以图像的中心为坐标系原点)
    fDstX1 =  fCosa * fSrcX1 + fSina * fSrcY1;
	fDstY1 = -fSina * fSrcX1 + fCosa * fSrcY1;
	fDstX2 =  fCosa * fSrcX2 + fSina * fSrcY2;
	fDstY2 = -fSina * fSrcX2 + fCosa * fSrcY2;
	fDstX3 =  fCosa * fSrcX3 + fSina * fSrcY3;
	fDstY3 = -fSina * fSrcX3 + fCosa * fSrcY3;
	fDstX4 =  fCosa * fSrcX4 + fSina * fSrcY4;
	fDstY4 = -fSina * fSrcX4 + fCosa * fSrcY4;

    //计算旋转后的图像的实际宽度
    dwWidth = (DWORD)(max(fabs(fDstX4-fDstX1),fabs(fDstX3-fDstX2))+0.5)+100;   
    //计算旋转后新图的高度
    dwHeight = (DWORD)(max(fabs(fDstY4-fDstY1),fabs(fDstY3-fDstY2))+0.5)+100;
   

   //用来计算新图的点在原图的坐标
   f1 = (float)(-0.5*(dwWidth-1)*fCosa-0.5*(dwHeight-1)*fSina+0.5*(dwWidth -1));
   f2 = (float)(0.5*(dwWidth-1)*fSina-0.5*(dwHeight-1)*fCosa+0.5*(dwHeight-1));


   //申请内存空间用来存储旋转后的新图
   pNewbuf = new BYTE[dwWidth*dwHeight*4];
  for(i=0;i<dwHeight;i++)
	  for(j=0;j<dwWidth;j++)
	  {
		  //计算像素在原图中的位置
		  i0 = (DWORD)(-((float)j)*fSina+((float)i)*fCosa+f2+0.5);
		  j0 = (DWORD)(((float)j)*fCosa+((float)i)*fSina+f1+0.5);
		  if((j0>=0)&&(j0<m_dwWidth)&&(i0>=0)&&(i0<m_dwHeight))
		  {
              pNewbuf[i*dwWidth*4+j*4] = m_pBitbuf[i0*m_dwWidth*4+j0*4];
              pNewbuf[i*dwWidth*4+j*4+1] = m_pBitbuf[i0*m_dwWidth*4+j0*4+1];
		      pNewbuf[i*dwWidth*4+j*4+2] = m_pBitbuf[i0*m_dwWidth*4+j0*4+2];
		      pNewbuf[i*dwWidth*4+j*4+3] = m_pBitbuf[i0*m_dwWidth*4+j0*4+3];  
		  }
		  else
		  {
			  pNewbuf[i*dwWidth*4+j*4] = 255;
              pNewbuf[i*dwWidth*4+j*4+1] = 255;
			  pNewbuf[i*dwWidth*4+j*4+2] = 255;
			  pNewbuf[i*dwWidth*4+j*4+3] = 255;
		  }
	  }
	m_dwWidth = dwWidth;
    m_dwHeight = dwHeight;
    delete[] m_pBitbuf;
	m_pBitbuf = pNewbuf;
}
//////////////////////////////////////////////////////////////////////
//函数名:
//       GetImgRect()
//参数:
//       RECT rectDest -指定要获取的图像范围
//       BYTE*& pRect -存放新图像的缓冲区
//说明:
//       获取指定范围内的像素
/////////////////////////////////////////////////////////////////////
void CDibImage::GetImgRect( RECT& rectDest, BYTE*& pRect)
{
	int i,j;//循环变量
	DWORD dwHeight, dwWidth;
	if( rectDest.bottom>m_dwHeight )
	{
		rectDest.bottom = m_dwHeight;
	}
	if( rectDest.right>m_dwWidth)
	{
		rectDest.right = m_dwWidth;
	}
	if( rectDest.left<0 )
	{
		rectDest.left = 0;
	}
	if( rectDest.top<0 )
	{
		rectDest.top = 0;
	}
	dwHeight = rectDest.bottom - rectDest.top;
    dwWidth = rectDest.right - rectDest.left;
	pRect = (BYTE*) new BYTE[dwWidth*dwHeight*4];
	//拷贝像素到指定矩形区域
	for(i=0;i<dwHeight;i++)
	for(j=0;j<dwWidth*4;j++)
	{
		pRect[i*dwWidth*4 + j] = m_pBitbuf[(i+rectDest.top)*m_dwWidth*4 + 
		rectDest.left*4 + j];
	}
}




////////////////////////////////////////////////////////////////////////////////
//
//
////////////////////////////////////////////////////////////////////////////////
void CDibImage::Translation( DWORD dwXOffset, DWORD dwYOffset)
{
	
	int i,j,i0,j0;         //循环变量
	RECT rectDst;    //平移后,剩余图像在原图的位置
  //指向新图的指针
	rectDst.top = rectDst.left = 0;
	rectDst.bottom = m_dwHeight;
	rectDst.right = m_dwWidth;

	rectDst.top += dwYOffset;
	rectDst.bottom += dwYOffset;
	rectDst.left += dwXOffset;
	rectDst.right += dwXOffset;

    BYTE* pNewbuf = new BYTE[m_dwWidth*m_dwHeight*4];//新图显示的位置

	//??????????????????????????????????????????????????????????????????
	if( rectDst.left<-(int)m_dwWidth || rectDst.top<-(int)m_dwHeight//?????????????????
		 || rectDst.right>2*m_dwWidth || rectDst.bottom>2*m_dwHeight )
	{
		for(i=0;i<m_dwHeight;i++)
		for(j=0;j<m_dwWidth*4;j++)
		{
			pNewbuf[i*m_dwWidth*4 + j] = 255;
		}
	}
	else 
	{
		for(i=0;i<m_dwHeight;i++)
		for(j=0;j<m_dwWidth;j++)
		{
			i0 = i - dwYOffset;
            j0 = j - dwXOffset;
			if( i>= rectDst.top && i<rectDst.bottom &&
				 j>= rectDst.left && j<rectDst.right )
			{
				pNewbuf[i*m_dwWidth*4 + j*4] = m_pBitbuf[i0*m_dwWidth*4 + j0*4];
				pNewbuf[i*m_dwWidth*4 + j*4 + 1] = m_pBitbuf[i0*m_dwWidth*4 + j0*4 + 1];
				pNewbuf[i*m_dwWidth*4 + j*4 + 2] = m_pBitbuf[i0*m_dwWidth*4 + j0*4 + 2];
				pNewbuf[i*m_dwWidth*4 + j*4 + 3] = m_pBitbuf[i0*m_dwWidth*4 + j0*4 + 3];
			}
			else 
			{
				pNewbuf[i*m_dwWidth*4 + j*4] = 255;
				pNewbuf[i*m_dwWidth*4 + j*4 + 1] = 255;
				pNewbuf[i*m_dwWidth*4 + j*4 + 2] = 255;
				pNewbuf[i*m_dwWidth*4 + j*4 + 3] = 255;
			}
		}
	}
	delete[] m_pBitbuf;
	m_pBitbuf = NULL;
	m_pBitbuf = pNewbuf;
}


/////////////////////////////////////////////////////////////////////////////////
//函数名:
//       Mirror()
//参数:
//       bool bDirection -镜像的方式
//说明:
//       把图像按照指定的方式进行镜像
///////////////////////////////////////////////////////////////////////////////////
void CDibImage::Mirror(bool bDrcHorV)
{
	if(IsBufferValid() == false) return;
	BYTE* pChange = new BYTE[4];
	DWORD i,j;         //循环变量
	BYTE* pTmp;
	if(bDrcHorV)
	{
		for(i=0;i<m_dwHeight;i++)
		for(j=0;j<m_dwWidth/2;j++)
		{
			pTmp = &m_pBitbuf[i*m_dwWidth*4 + j*4];//指向前面的像素点
			memcpy( pChange, pTmp, 4);
			memcpy( pTmp, &m_pBitbuf[(i+1)*m_dwWidth*4 - (j+1)*4], 4);
			memcpy( &m_pBitbuf[(i+1)*m_dwWidth*4 - (j+1)*4], pChange, 4);
		}
	}
	else
	{
		BYTE* pLineBytes = new BYTE[m_dwWidth*4];
		DWORD dwLineSize = m_dwWidth*4;
		for(i=0;i<m_dwHeight/2;i++)
		{
			memcpy( pLineBytes, &m_pBitbuf[i*m_dwWidth*4], dwLineSize);
			memcpy( &m_pBitbuf[i*m_dwWidth*4], &m_pBitbuf[(m_dwHeight-i-1)*dwLineSize], dwLineSize); 
			memcpy( &m_pBitbuf[(m_dwHeight-i-1)*dwLineSize], pLineBytes, dwLineSize);
		}
	}
	delete[] pChange;
	pChange = NULL;
}

⌨️ 快捷键说明

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