📄 geotrans.cpp
字号:
// GeoTrans.cpp: implementation of the CGeoTrans class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "GeoTrans.h"
#include "math.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
IMPLEMENT_DYNCREATE(CGeoTrans, CObject)
//Diagnostics and dump member functions, overridden
#ifdef _DEBUG
void CGeoTrans::Dump(CDumpContext &dc) const
{
//call base class function first
CObject::Dump(dc);
}
#endif
#ifdef _DEBUG
void CGeoTrans::AssertValid() const
{
//call inherited AssertValid first
CObject::AssertValid();
//Check CDibObject members...
ASSERT(m_pDibObject != NULL); //Must exist
}
#endif
/***********************************************************************
* *
* 几何处理类 *
* *
***********************************************************************/
////////////////////////////////////////////////////////////////////////
//构造函数CGeoTrans()
//----------------------------------------------------------------------
//基本功能:构造一个CGeoTrans类的对象,如不传入CDibObject对象。第
// 一次调用某一个处理函数时必须给出一个CDibObject对象指针。
//----------------------------------------------------------------------
//参数说明:无
//----------------------------------------------------------------------
//返 回:无
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
CGeoTrans::CGeoTrans()
{
}
////////////////////////////////////////////////////////////////////////
//构造函数CGeoTrans()
//----------------------------------------------------------------------
//基本功能:构造一个CGeoTrans类的对象并传入CDibObject对象。所有的
// 操作都针对该对象,直到另一个对象作为参数被传给图像处理函数。
//----------------------------------------------------------------------
//参数说明:无
//----------------------------------------------------------------------
//返 回:无
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
CGeoTrans::CGeoTrans( CDibObject *pDibObject )
{
m_pDibObject = pDibObject;
}
CGeoTrans::~CGeoTrans()
{
}
////////////////////////////////////////////////////////////////////////
//void SetDibObjectClass(CDibObject *pDibObject)
//----------------------------------------------------------------------
//基本功能:本函数为CGeoTrans类对象指定一个CDibObject对象指针
//----------------------------------------------------------------------
//参数说明:CDibObject *pDibObject, 默认为NULL。
//----------------------------------------------------------------------
//返 回:无。
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
void CGeoTrans::SetDibObjectClass( CDibObject *pDibObject )
{
m_pDibObject = pDibObject;
}
////////////////////////////////////////////////////////////////////////
//BOOL TranslationPixel()
//----------------------------------------------------------------------
//基本功能:本函数对传入的CDibObject对象中的图像进行平移操作。如果进行
// 此调整之前没有指定一个CDibObject对象指针,则必须在调整时加
// 以指定。
//----------------------------------------------------------------------
//参数说明:long lXOffset - X轴平移量(像素数)
// long lYOffset - Y轴平移量(像素数)
// CDibObject *pDibObject, 默认为NULL
//----------------------------------------------------------------------
//返回:BOOL:成功返回TRUE,失败返回FALSE。
//----------------------------------------------------------------------
//注 意:该函数用来水平移动DIB图像。函数不会改变图像的大小,移出的部分
// 图像将截去,空白部分用白色填充。该函数逐点移动图像。
////////////////////////////////////////////////////////////////////////
BOOL CGeoTrans::TranslationPixel(long lXOffset,
long lYOffset,
CDibObject *pDibObject)
{
//使用传入的CDibObject对象
if( pDibObject != NULL ) m_pDibObject = pDibObject;
//无CDibObject对象, 返回FALSE
if( m_pDibObject == NULL ) return( FALSE );
//获得图像宽度和高度
int nWidth = m_pDibObject->GetWidth();
int nHeight = m_pDibObject->GetHeight();
//定义变量
unsigned char *pOldBuffer;
unsigned char *pOldBits, *pNewBits;
unsigned char *pOldTemp, *pNewTemp;
BITMAPFILEHEADER *pOldBFH;
BITMAPINFOHEADER *pOldBIH;
RGBQUAD *pOldPalette;
int nWidthBytes, nNumColors, x, y;
//原图像指针
pOldBuffer = (unsigned char *) m_pDibObject->GetDIBPointer( &nWidthBytes,
m_pDibObject->GetNumBits() );
if( pOldBuffer == NULL ) return( FALSE );
//原图像文件头指针
pOldBFH = (BITMAPFILEHEADER *) pOldBuffer;
//原图像信息头指针
pOldBIH = (BITMAPINFOHEADER *) &pOldBuffer[sizeof(BITMAPFILEHEADER)];
//原图像颜色数
nNumColors = m_pDibObject->GetNumColors();
//原图像调色板指针
pOldPalette = (RGBQUAD *) &pOldBuffer[sizeof(BITMAPFILEHEADER)
+sizeof(BITMAPINFOHEADER)];
//原图像数据指针
pOldBits = (unsigned char *) &pOldBuffer[sizeof(BITMAPFILEHEADER)
+sizeof(BITMAPINFOHEADER)
+nNumColors*sizeof(RGBQUAD)];
//为新图像数据区分配内存
DWORD dwNewSize;
HGLOBAL hNewDibBits;
//新图像数据区大小
dwNewSize = nWidthBytes * nHeight;
//为新图像分配内存
hNewDibBits = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwNewSize );
if( hNewDibBits == NULL )
{
m_pDibObject->m_nLastError = IMAGELIB_MEMORY_ALLOCATION_ERROR;
::GlobalUnlock( m_pDibObject->GetDib() );
return( FALSE );
}
//新图像指针
pNewBits = (unsigned char *) ::GlobalLock( hNewDibBits );
if( pNewBits == NULL )
{
::GlobalFree( hNewDibBits );
m_pDibObject->m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR;
::GlobalUnlock( m_pDibObject->GetDib() );
return( FALSE );
}
//用255(白色)填充新图像数据区
memset(pNewBits, (BYTE)255, nWidthBytes * nHeight );
//由图像位数确定的移动字节数
int nMovedBits = 1;
switch( m_pDibObject->GetNumBits() )
{
case 8:
nMovedBits = 1;
break;
case 16:
nMovedBits = 2;
break;
case 24:
nMovedBits = 3;
break;
case 32:
nMovedBits = 4;
break;
}
//每行
for(y = 0; y < nHeight; y++)
{
pNewTemp = pNewBits;
//注意由于DIB中图像第一行其实保存在最后一行的位置。
pNewTemp += (nHeight - 1 - y) * nWidthBytes;
//每列
for(x = 0; x < nWidth; x++)
{
//指向新DIB第y行,第x个像素的指针
//计算该像素在源DIB中的坐标
int x0 = x - lXOffset;
int y0 = y - lYOffset;
//判断是否在源图范围内
if( (x0 >= 0) && (x0 < nWidth)
&& (y0 >= 0) && (y0 < nHeight))
{
//指向源DIB第y0行,第x0个像素的指针
//同样要注意DIB上下倒置的问题
pOldTemp = pOldBits;
pOldTemp += (nHeight - 1 - y0) * nWidthBytes;
pOldTemp += x0 * nMovedBits;
//复制像素
memcpy( pNewTemp, pOldTemp, nMovedBits );
}
pNewTemp += nMovedBits;
}
}
//用新图像数据填充原图像数据区
memcpy( pOldBits, pNewBits, nWidthBytes * nHeight );
::GlobalFree( hNewDibBits );
::GlobalUnlock( m_pDibObject->GetDib() );
return TRUE;
}
////////////////////////////////////////////////////////////////////////
//BOOL TranslationLine()
//----------------------------------------------------------------------
//基本功能:本函数对传入的CDibObject对象中的图像进行平移操作。如果进行
// 此调整之前没有指定一个CDibObject对象指针,则必须在调整时加
// 以指定。
//----------------------------------------------------------------------
//参数说明:long lXOffset - X轴平移量(像素数)
// long lYOffset - Y轴平移量(像素数)
// CDibObject *pDibObject, 默认为NULL
//----------------------------------------------------------------------
//返回:BOOL:成功返回TRUE,失败返回FALSE。
//----------------------------------------------------------------------
//注 意:该函数用来水平移动DIB图像。函数不会改变图像的大小,移出的部分
// 图像将截去,空白部分用白色填充。该函数逐行移动图像。
////////////////////////////////////////////////////////////////////////
BOOL CGeoTrans::TranslationLine(long lXOffset,
long lYOffset,
CDibObject *pDibObject)
{
//使用传入的CDibObject对象
if( pDibObject != NULL ) m_pDibObject = pDibObject;
//无CDibObject对象, 返回FALSE
if( m_pDibObject == NULL ) return( FALSE );
//获得图像宽度和高度
int nWidth = m_pDibObject->GetWidth();
int nHeight = m_pDibObject->GetHeight();
//定义变量
unsigned char *pOldBuffer;
unsigned char *pOldBits, *pNewBits;
unsigned char *pOldTemp, *pNewTemp;
BITMAPFILEHEADER *pOldBFH;
BITMAPINFOHEADER *pOldBIH;
RGBQUAD *pOldPalette;
int nWidthBytes, nNumColors, i;
//原图像指针
pOldBuffer = (unsigned char *) m_pDibObject->GetDIBPointer( &nWidthBytes,
m_pDibObject->GetNumBits() );
if( pOldBuffer == NULL ) return( FALSE );
//原图像文件头指针
pOldBFH = (BITMAPFILEHEADER *) pOldBuffer;
//原图像信息头指针
pOldBIH = (BITMAPINFOHEADER *) &pOldBuffer[sizeof(BITMAPFILEHEADER)];
//原图像颜色数
nNumColors = m_pDibObject->GetNumColors();
//原图像调色板指针
pOldPalette = (RGBQUAD *) &pOldBuffer[sizeof(BITMAPFILEHEADER)
+sizeof(BITMAPINFOHEADER)];
//原图像数据指针
pOldBits = (unsigned char *) &pOldBuffer[sizeof(BITMAPFILEHEADER)
+sizeof(BITMAPINFOHEADER)
+nNumColors*sizeof(RGBQUAD)];
//为新图像数据区分配内存
DWORD dwNewSize;
HGLOBAL hNewDibBits;
//新图像数据区大小
dwNewSize = nWidthBytes * nHeight;
//为新图像分配内存
hNewDibBits = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwNewSize );
if( hNewDibBits == NULL )
{
m_pDibObject->m_nLastError = IMAGELIB_MEMORY_ALLOCATION_ERROR;
::GlobalUnlock( m_pDibObject->GetDib() );
return( FALSE );
}
//新图像指针
pNewBits = (unsigned char *) ::GlobalLock( hNewDibBits );
if( pNewBits == NULL )
{
::GlobalFree( hNewDibBits );
m_pDibObject->m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR;
::GlobalUnlock( m_pDibObject->GetDib() );
return( FALSE );
}
//用255(白色)填充新图像数据区
memset(pNewBits, (BYTE)255, nWidthBytes * nHeight );
//由图像位数确定的移动字节数
int nMovedBits = 1;
switch( m_pDibObject->GetNumBits() )
{
case 8:
nMovedBits = 1;
break;
case 16:
nMovedBits = 2;
break;
case 24:
nMovedBits = 3;
break;
case 32:
nMovedBits = 4;
break;
}
//平移后剩余图像在源图像中的位置(矩形区域)
CRect rectSrc;
//平移后剩余图像在新图像中的位置(矩形区域)
CRect rectDst;
//指明图像是否全部移去可视区间
BOOL bVisible;
//赋初值
bVisible = TRUE;
//计算rectSrc和rectDst的X坐标
if (lXOffset <= -nWidth)
{
//X轴方向全部移出可视区域
bVisible = FALSE;
}
else if (lXOffset <= 0)
{
//移动后,有图区域左上角X坐标为0
rectDst.left = 0;
//移动后,有图区域右下角X坐标为
//lWidth - |lXOffset| = lWidth + lXOffset
rectDst.right = nWidth + lXOffset;
}
else if (lXOffset < nWidth)
{
//移动后,有图区域左上角X坐标为lXOffset
rectDst.left = lXOffset;
//移动后,有图区域右下角X坐标为lWidth
rectDst.right = nWidth;
}
else
{
//X轴方向全部移出可视区域
bVisible = FALSE;
}
//平移后剩余图像在源图像中的X坐标
rectSrc.left = rectDst.left - lXOffset;
rectSrc.right = rectDst.right - lXOffset;
//计算rectSrc和rectDst的Y坐标
if (lYOffset <= -nHeight)
{
//Y轴方向全部移出可视区域
bVisible = FALSE;
}
else if (lYOffset <= 0)
{
//移动后,有图区域左上角Y坐标为0
rectDst.top = 0;
//移动后,有图区域右下角Y坐标为
//lHeight - |lYOffset| = lHeight + lYOffset
rectDst.bottom = nHeight + lYOffset;
}
else if (lYOffset < nHeight)
{
//移动后,有图区域左上角Y坐标为lYOffset
rectDst.top = lYOffset;
//移动后,有图区域右下角Y坐标为lHeight
rectDst.bottom = nHeight;
}
else
{
//X轴方向全部移出可视区域
bVisible = FALSE;
}
//平移后剩余图像在源图像中的Y坐标
rectSrc.top = rectDst.top - lYOffset;
rectSrc.bottom = rectDst.bottom - lYOffset;
//如果有部分图像可见
if (bVisible)
{
//平移图像
for(i = 0; i < (rectSrc.bottom - rectSrc.top); i++)
{
//要复制区域的起点,注意由于DIB图像内容是上下倒置的,
//第一行内容是保存在最后一行,因此复制区域的起点不是
//pOldBits + nWidthBytes * (i + rectSrc.top) +
//rectSrc.left,
//而是 pOldBits + nWidthBytes * (nHeight - i - rectSrc.top
//- 1) + rectSrc.left。
//定位新图像指针
pNewTemp = pNewBits;
pNewTemp += (nHeight - i - rectDst.top - 1) * nWidthBytes
+ rectDst.left * nMovedBits;
//定位源图像指针
pOldTemp = pOldBits;
pOldTemp += (nHeight - i - rectSrc.top - 1) * nWidthBytes
+ rectSrc.left * nMovedBits;
//拷贝每一行,宽度为rectSrc.right - rectSrc.left
memcpy( pNewTemp, pOldTemp, (rectSrc.right - rectSrc.left) * nMovedBits );
}
}
//用新图像数据填充原图像数据区
memcpy( pOldBits, pNewBits, nWidthBytes * nHeight );
::GlobalFree( hNewDibBits );
::GlobalUnlock( m_pDibObject->GetDib() );
return TRUE;
}
////////////////////////////////////////////////////////////////////////
//BOOL Mirror()
//----------------------------------------------------------------------
//基本功能:本函数对传入的CDibObject对象中的图像进行镜像操作。如果进行
// 此调整之前没有指定一个CDibObject对象指针,则必须在调整时加
// 以指定。
//----------------------------------------------------------------------
//参数说明:BOOL bDirection 镜像的方向,TRUE表示水平镜像,FALSE表示
// 垂直镜像
// CDibObject *pDibObject, 默认为NULL
//----------------------------------------------------------------------
//返回:BOOL:成功返回TRUE,失败返回FALSE。
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
BOOL CGeoTrans::Mirror(BOOL bDirection,
CDibObject *pDibObject)
{
//使用传入的CDibObject对象
if( pDibObject != NULL ) m_pDibObject = pDibObject;
//无CDibObject对象, 返回FALSE
if( m_pDibObject == NULL ) return( FALSE );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -