本文主要介绍“图像的操作:移动、缩放、旋转”.
本文为了简明体现整个操作过程,因此程序框架及软件设计并不规范,所以代码仅供参考。
上一篇介绍了图像坐标系的转换,见:连载:徒手写一个DICOM阅图软件(003)之图像坐标系转换-CSDN博客
上篇中,我们创建了一个从原始图像到窗口图像的转换矩阵,而针对图像的操作,我们只需要针对这个矩阵( mDicomToScreen )进行操作就能达到效果了。
因为图像操作都是由鼠标拖动来完成,因此我们需要当前的工作状态来完成相应的操作。所有操作都在鼠标的MOVE消息中完成。
代码如下:
int ShowWork::OnMouseMove( UINT nFlags, CPoint point )
{
if ( !( nFlags & VK_LBUTTON ) )
return 0;
int re = 0;
switch( mWorkState )
{
case EWorkState_Move: // 移动操作
{
CPoint subPos = point - mLastMouseMovePos; // 当前位置减上一次位置
M3DMatrix44f m1, m2;
m3dTranslationMatrix44( m1, float( subPos.x ), float( subPos.y), 0 );
m3dMatrixMultiply44( m2, m1, mDicomToScreen ); // mDicomToScreen 添加上位移
m3dCopyMatrix44( mDicomToScreen, m2 );
re = 1;
}
break;
case EWorkState_Scale: // 缩放操作
{
float s = 1.0f;
if ( point.y > mLastMouseMovePos.y ) // 鼠标往下移动,缩小
{
s -= 0.05f;
}
else if ( point.y < mLastMouseMovePos.y )
{
s += 0.05f;
}
// 以鼠标按下位置为缩放中心进行缩放
M3DMatrix44f m1, m2, m3;
m3dTranslationMatrix44( m1, -float( mLButtonDownPos.x ), -float( mLButtonDownPos.y ), 0 );
m3dScaleMatrix44( m2, s, s, 1 );
m3dMatrixMultiply44( m3, m2, m1 );
m3dTranslationMatrix44( m1, float( mLButtonDownPos.x ), float( mLButtonDownPos.y ), 0 );
m3dMatrixMultiply44( m2, m1, m3 );
m3dMatrixMultiply44( m1, m2, mDicomToScreen );
m3dCopyMatrix44( mDicomToScreen, m1 );
re = 1;
}
break;
case EWorkState_Rotate: // 旋转操作
{
float r = 0;
if ( point.y > mLastMouseMovePos.y ) // 鼠标往下移动,正转
{
r -= 1.0f;
}
else if ( point.y < mLastMouseMovePos.y )
{
r += 1.0f;
}
float v = float( r * 0.017453292f ); // 角度转弧度
M3DMatrix44f m1, m2, m3;
m3dTranslationMatrix44( m1, -float( mLButtonDownPos.x ), -float( mLButtonDownPos.y ), 0 );
m3dRotationMatrix44( m2, v, 0, 0, 1 );
m3dMatrixMultiply44( m3, m2, m1 );
m3dTranslationMatrix44( m1, float( mLButtonDownPos.x ), float( mLButtonDownPos.y ), 0 );
m3dMatrixMultiply44( m2, m1, m3 );
m3dMatrixMultiply44( m1, m2, mDicomToScreen );
m3dCopyMatrix44( mDicomToScreen, m1 );
re = 1;
}
break;
}
mLastMouseMovePos = point;
return re;
}
看下效果:
下一篇: