📄 geotrans.cpp
字号:
//获得图像宽度和高度
int nWidth = m_pDibObject->GetWidth();
int nHeight = m_pDibObject->GetHeight();
//定义变量
unsigned char *pOldBuffer;
unsigned char *pOldBits, *pNewBits;
unsigned char *pOldTemp, *pNewTemp;
unsigned char *pTemp1, *pTemp2;
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;
}
//判断镜像方式
if (bDirection)
{
//水平镜像
//垂直中轴坐标
int nMiddleX = nWidth / 2;
//针对图像每行进行操作
for(y = 0; y < nHeight; y++)
{
//指向图像的倒数第y行
pOldTemp = pOldBits;
pOldTemp += y * nWidthBytes;
pNewTemp = pNewBits;
pNewTemp += y * nWidthBytes;
//针对每行图像左半部分进行操作
for(x = 0; x <= nMiddleX; x++)
{
//将源图像第x个像素复制到新图像倒数第x个像素
pTemp1 = pOldTemp + x * nMovedBits;
pTemp2 = pNewTemp + (nWidth -1 - x) * nMovedBits;
memcpy(pTemp2, pTemp1, nMovedBits);
//将源图像倒数第x个像素复制到新图像第x个像素
pTemp1 = pOldTemp + (nWidth -1 - x) * nMovedBits;
pTemp2 = pNewTemp + x * nMovedBits;
memcpy(pTemp2, pTemp1, nMovedBits);
}
}
}
else
{
//垂直镜像
//水平中轴坐标
int nMiddleY = nHeight / 2;
//针对上半图像进行操作
for(y = 0; y <= nMiddleY; y++)
{
//指向源图像倒数第y行像素起点的指针
pOldTemp = pOldBits;
pOldTemp += y * nWidthBytes;
//指向新图像第y行像素起点的指针
pNewTemp = pNewBits;
pNewTemp += (nHeight - 1 - y) * nWidthBytes;
//将源图像倒数第y行像素复制到新图像第y行
memcpy(pNewTemp, pOldTemp, nWidthBytes);
//指向源图像第y行像素起点的指针
pOldTemp = pOldBits;
pOldTemp += (nHeight - 1 - y) * nWidthBytes;
//指向新图像倒数第y行像素起点的指针
pNewTemp = pNewBits;
pNewTemp += y * nWidthBytes;
//将源图像第y行像素复制到新图像倒数第y行
memcpy(pNewTemp, pOldTemp, nWidthBytes);
}
}
//用新图像数据填充原图像数据区
memcpy( pOldBits, pNewBits, nWidthBytes * nHeight );
::GlobalFree( hNewDibBits );
::GlobalUnlock( m_pDibObject->GetDib() );
return TRUE;
}
/**********************************************************************
* 函数名称:BOOL Transpose()
* 基本功能:本函数对传入的CDibObject对象中的图像进行转置操作。如果进行此
* 调整之前没有指定一个CDibObject对象指针,则必须在调整时加以指定。
* 参数说明:CDibObject *pDibObject, 默认为NULL
* 返回值: BOOL - 转置成功返回TRUE,否则返回FALSE。
**********************************************************************/
BOOL CGeoTrans::Transpose(CDibObject *pDibObject)
{
if( pDibObject != NULL ) m_pDibObject = pDibObject;
//无CDibObject对象, 返回FALSE
if( m_pDibObject == NULL ) return( FALSE );
//获得图像宽度和高度
int nOldWidth = m_pDibObject->GetWidth();
int nOldHeight = m_pDibObject->GetHeight();
//转置后图像的宽度和高度
int nNewWidth = nOldHeight;
int nNewHeight = nOldWidth;
//定义变量
unsigned char *pOldBuffer, *pNewBuffer;
unsigned char *pOldBits, *pNewBits;
unsigned char *pOldTemp, *pNewTemp;
BITMAPFILEHEADER *pOldBFH, *pNewBFH;
BITMAPINFOHEADER *pOldBIH, *pNewBIH;
RGBQUAD *pOldPalette, *pNewPalette;
int nOldWidthBytes, nNewWidthBytes, nNumColors, x, y;
//原图像指针
pOldBuffer = (unsigned char *)
m_pDibObject->GetDIBPointer( &nOldWidthBytes,
m_pDibObject->GetNumBits(),
&nNewWidthBytes, nNewWidth );
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 hNewDib;
//新图像大小(包括文件头、信息头、调色板和图像数据)
dwNewSize = (DWORD) nNumColors * sizeof( RGBQUAD ) +
sizeof( BITMAPFILEHEADER ) +
sizeof( BITMAPINFOHEADER ) +
nNewWidthBytes * nNewHeight;
//为新图像分配内存
hNewDib = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwNewSize );
if( hNewDib == NULL )
{
m_pDibObject->m_nLastError = IMAGELIB_MEMORY_ALLOCATION_ERROR;
::GlobalUnlock( m_pDibObject->GetDib() );
return( FALSE );
}
//新图像指针
pNewBuffer = (unsigned char *) ::GlobalLock( hNewDib );
if( pNewBuffer == NULL )
{
::GlobalFree( hNewDib );
m_pDibObject->m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR;
::GlobalUnlock( m_pDibObject->GetDib() );
return( FALSE );
}
//新图像文件头指针
pNewBFH = (BITMAPFILEHEADER *) pNewBuffer;
//新图像信息头指针
pNewBIH = (BITMAPINFOHEADER *) &pNewBuffer[sizeof(BITMAPFILEHEADER)];
//新图像调色板指针
pNewPalette = (RGBQUAD *) &pNewBuffer[sizeof(BITMAPFILEHEADER)
+sizeof(BITMAPINFOHEADER)];
//新图像数据指针
pNewBits = (unsigned char *) &pNewBuffer[sizeof(BITMAPFILEHEADER)
+sizeof(BITMAPINFOHEADER)
+nNumColors*sizeof(RGBQUAD)];
//用255(白色)填充新图像数据区
memset(pNewBits, (BYTE)255, nNewWidthBytes * nNewHeight );
//用原图像文件头数据填充新图像文件头
memcpy( pNewBFH, pOldBFH, sizeof(BITMAPFILEHEADER) );
//用原图像信息头数据填充新图像信息头
memcpy( pNewBIH, pOldBIH, sizeof(BITMAPINFOHEADER) );
//调整文件总字节数
pNewBFH->bfSize = dwNewSize;
//调整新图像的宽度和高度
pNewBIH->biWidth = nNewWidth;
pNewBIH->biHeight = nNewHeight;
//pNewBIH->biBitCount = nNewBitsPerPixel;
pNewBIH->biSizeImage = nNewWidthBytes * nNewHeight;
pNewBIH->biClrUsed = nNumColors;
pNewBFH->bfSize = sizeof( BITMAPFILEHEADER )
+ sizeof( BITMAPINFOHEADER )
+ nNumColors * sizeof( RGBQUAD )
+ pNewBIH->biSizeImage;
pNewBFH->bfOffBits = sizeof( BITMAPFILEHEADER )
+ sizeof( BITMAPINFOHEADER )
+ nNumColors * sizeof( RGBQUAD );
//用原图像调色板填充新图像调色板
if(nNumColors != 0)
memcpy( pNewPalette, pOldPalette, nNumColors*sizeof(RGBQUAD) );
//由图像位数确定的移动字节数
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 < nOldHeight; y++)
{
//指向源图像第y行
pOldTemp = pOldBits;
pOldTemp += (nOldHeight - 1 -y) * nOldWidthBytes;
// 针对每行图像每列进行操作
for(x = 0; x < nOldWidth; x++)
{
//指向转置后的图像第x行,第y个像素的指针
//注意此处宽度和高度应该互换
pNewTemp = pNewBits;
pNewTemp += (nNewHeight - 1 - x) * nNewWidthBytes;
pNewTemp += y * nMovedBits;
//复制像素
memcpy(pNewTemp, pOldTemp, nMovedBits);
pOldTemp += nMovedBits;
}
}
//将内存解锁和将不再使用的内存释放
::GlobalUnlock( m_pDibObject->GetDib() );
::GlobalFree( m_pDibObject->GetDib() );
::GlobalUnlock( hNewDib );
//将新图像设置为当前图像
m_pDibObject->SetDib( hNewDib );
m_pDibObject->ProcessImageHeader();
return TRUE;
}
////////////////////////////////////////////////////////////////////////
//BOOL ZoomImage()
//----------------------------------------------------------------------
//基本功能:本函数对传入的CDibObject对象中的图像进行缩放操作。如果进行
// 此调整之前没有指定一个CDibObject对象指针,则必须在调整时加
// 以指定。
//----------------------------------------------------------------------
//参数说明:float fXZoomRatio - X轴方向缩放比率
// float fYZoomRatio - Y轴方向缩放比率
// BOOL bBilinear - TRUE为双线性插值,FALSE为最邻近插值
// CDibObject *pDibObject, 默认为NULL
//----------------------------------------------------------------------
//返回:BOOL:成功返回TRUE,失败返回FALSE。
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
BOOL CGeoTrans::ZoomImage(float fXZoomRatio,
float fYZoomRatio,
BOOL bBilinear,
CDibObject *pDibObject)
{
if( pDibObject != NULL ) m_pDibObject = pDibObject;
//无CDibObject对象, 返回FALSE
if( m_pDibObject == NULL ) return( FALSE );
//获得图像宽度和高度
int nOldWidth = m_pDibObject->GetWidth();
int nOldHeight = m_pDibObject->GetHeight();
// 计算缩放后的图像实际宽度
int nNewWidth, nNewHeight;
// 此处直接加0.5是由于强制类型转换时不四舍五入,而是直接截去小数部分
nNewWidth = (int)(nOldWidth * fXZoomRatio + 0.5);
// 计算缩放后的图像高度
nNewHeight = (int)(nOldHeight * fYZoomRatio + 0.5);
//定义变量
unsigned char *pOldBuffer, *pNewBuffer;
unsigned char *pOldBits, *pNewBits;
unsigned char *pOldTemp, *pNewTemp;
BITMAPFILEHEADER *pOldBFH, *pNewBFH;
BITMAPINFOHEADER *pOldBIH, *pNewBIH;
RGBQUAD *pOldPalette, *pNewPalette;
int nOldWidthBytes, nNewWidthBytes, nNumColors, x, y;
//原图像指针
pOldBuffer = (unsigned char *)
m_pDibObject->GetDIBPointer( &nOldWidthBytes,
m_pDibObject->GetNumBits(),
&nNewWidthBytes, nNewWidth );
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 hNewDib;
//新图像大小(包括文件头、信息头、调色板和图像数据)
dwNewSize = (DWORD) nNumColors * sizeof( RGBQUAD ) +
sizeof( BITMAPFILEHEADER ) +
sizeof( BITMAPINFOHEADER ) +
nNewWidthBytes * nNewHeight;
//为新图像分配内存
hNewDib = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwNewSize );
if( hNewDib == NULL )
{
m_pDibObject->m_nLastError = IMAGELIB_MEMORY_ALLOCATION_ERROR;
::GlobalUnlock( m_pDibObject->GetDib() );
return( FALSE );
}
//新图像指针
pNewBuffer = (unsigned char *) ::GlobalLock( hNewDib );
if( pNewBuffer == NULL )
{
::GlobalFree( hNewDib );
m_pDibObject->m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR;
::GlobalUnlock( m_pDibObject->GetDib() );
return( FALSE );
}
//新图像文件头指针
pNewBFH = (BITMAPFILEHEADER *) pNewBuffer;
//新图像信息头指针
pNewBIH = (BITMAPINFOHEADER *) &pNewBuffer[sizeof(BITMAPFILEHEADER)];
//新图像调色板指针
pNewPalette = (RGBQUAD *) &pNewBuffer[sizeof(BITMAPFILEHEADER)
+sizeof(BITMAPINFOHEADER)];
//新图像数据指针
pNewBits = (unsigned char *) &pNewBuffer[sizeof(BITMAPFILEHEADER)
+sizeof(BITMAPINFOHEADER)
+nNumColors*sizeof(RGBQUAD)];
//用255(白色)填充新图像数据区
memset(pNewBits, (BYTE)255, nNewWidthBytes * nNewHeight );
//用原图像文件头数据填充新图像文件头
memcpy( pNewBFH, pOldBFH, sizeof(BITMAPFILEHEADER) );
//用原图像信息头数据填充新图像信息头
memcpy( pNewBIH, pOldBIH, sizeof(BITMAPINFOHEADER) );
//调整文件总字节数
pNewBFH->bfSize = dwNewSize;
//调整新图像的宽度和高度
pNewBIH->biWidth = nNewWidth;
pNewBIH->biHeight = nNewHeight;
//pNewBIH->biBitCount = nNewBitsPerPixel;
pNewBIH->biSizeImage = nNewWidthBytes * nNewHeight;
pNewBIH->biClrUsed = nNumColors;
pNewBFH->bfSize = sizeof( BITMAPFILEHEADER )
+ sizeof( BITMAPINFOHEADER )
+ nNumColors * sizeof( RGBQUAD )
+ pNewBIH->biSizeImage;
pNewBFH->bfOffBits = sizeof( BITMAPFILEHEADER )
+ sizeof( BITMAPINFOHEADER )
+ nNumColors * sizeof( RGBQUAD );
//用原图像调色板填充新图像调色板
if(nNumColors != 0)
memcpy( pNewPalette, pOldPalette, nNumColors*sizeof(RGBQUAD) );
//由图像位数确定的移动字节数
int nMovedBits = 1;
switch( m_pDibObject->GetNumBits() )
{
case 8:
nMovedBits = 1;
break;
case 16:
nMovedBits = 2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -