2009年8月10日 星期一

Multi-Touch Application - Photo Viewer

之前的文章有提到 WPF提供2D Transform的功能, 而這樣的功能很適合發展應用程式的手勢(Gesture)操控, 下面, 我就舉一個簡單的圖片瀏覽應用程式, 透過一些手勢操作, 來對圖片進行放大, 縮小, 旋轉, 翻轉和平移.

環境設定:
以下是我的環境設定:

  • 觸控裝置 - Quanta Optical Touch Monitor
  • Touch API - OTMUT(Optical Touch Monitor Utility Toolkit), 這隻Touch API是我們自行撰寫的dll, 主要用來取得觸控點和手勢的資料, 功能類似Windows 7 Touch SDK
當然, 你也可以自行使用一台具有觸控功能的電腦或螢幕, 然後搭配Windows 7 Touch SDK 來開發此程式.

視窗和控制項的設定:

開啟一個WPF專案, 然後從Toolbox中將一個Image的控制項拉到視窗中, 如下圖所示:


[圖 1] 新增Image control

在專案中新增一個Image的資料夾,並把要顯示圖片放進去, 然後在XAML檔中設定圖片的路徑, 如下所示:


[圖2] 設定圖片路徑
<Grid Background="Beige">
<Image Margin="150"
Name="image1"
Stretch="Fill"
Source="Image\Koala.jpg">

</Image>
</Grid>


設定Image 2D Transform:

我們在XAML檔中, 先設定ImageRotaeTransform, ScaleTransformTranslateTransform, 程式碼如下所示:

<Grid Background="Beige">
<Image Margin="150" Name="image1"
Stretch="Fill"
Source="Image\Koala.jpg"
RenderTransformOrigin=".5,.5">
<Image.RenderTransform>
<TransformGroup>
<RotateTransform x:Name="_rotate" Angle="0">
</RotateTransform>

<ScaleTransform x:Name="_scale"
ScaleX="1"
ScaleY="1">    
</ScaleTransform>

<TranslateTransform x:Name="_translate"
X="0"
Y="0">                        
</TranslateTransform>
</TransformGroup>
</Image.RenderTransform>
</Image>
</Grid>



Gesture Function:
我們在.cs檔中加入OTMUT 的 callback function, 當有偵測到Zoom In/Out, Rotate和 Pan手勢作用時, 則對圖片作transform, 如下所示:
void GestureFunction(tOTM_Gesture gesture)
{
double k;

switch (gesture.GestureType)
{
// Detect Pan gesture
case (int)tOTM_GestureType.OTM_GT_PAN:
{
// Display gesture type in console mode
System.Console.WriteLine("Pan");


if (gesture.GestureState == (int)tOTM_GestureState.OTM_GS_BEGIN)
{
g_FirstX = gesture.ActivePoint.X;
g_FirstY = gesture.ActivePoint.Y;
}
else
{
g_SecondX = gesture.ActivePoint.X;
g_SecondY = gesture.ActivePoint.Y;


// translate the image
_translate.X += g_SecondX - g_FirstX;
_translate.Y += g_SecondY - g_FirstY;


// We have to copy second point into first one to prepare
// for next pan message.
g_FirstX = g_SecondX;
g_FirstY = g_SecondY;
}

};
break;

// Detect zoom gesture
case (int)tOTM_GestureType.OTM_GT_ZOOM:
{
// Display gesture type in console mode
System.Console.WriteLine("Zoom");

if (gesture.GestureState == (int)tOTM_GestureState.OTM_GS_BEGIN)
{
g_bBeginZoom = true;
}
else if (gesture.GestureState == (int)tOTM_GestureState.OTM_GS_INERTIA)
{
if (g_bBeginZoom)
{
g_fGEArguments = gesture.Argument1;
g_bBeginZoom = false;
}
else
{
k = (double)gesture.Argument1 / g_fGEArguments;

// Zoom in/out the image
_scale.ScaleX *= (float)k;
_scale.ScaleY *= (float)k;
}
g_fGEArguments = gesture.Argument1;
}

};
break;

// Detect rotate gesture
case (int)tOTM_GestureType.OTM_GT_ROTATE:
{

// Display gesture type in console mode
System.Console.WriteLine("Rotate");

if (gesture.GestureState == (int)tOTM_GestureState.OTM_GS_BEGIN)
{
g_bBeginRotate = true;
}
else
{
if (g_bBeginRotate)
{
_rotate.Angle = gesture.Argument1;
}
else
{
k = (float)(gesture.Argument1 - g_fGEArguments);

// Rotate the image
_rotate.Angle += k;

}
g_fGEArguments = gesture.Argument1;
}
};
break;

// Detect the Press and Tap
case (int)tOTM_GestureType.OTM_GT_PRESS_TAP:
{
// Display gesture type in console mode
System.Console.WriteLine("Press and Tap");

// Flip the image
_scale.ScaleX *= -1;
};
break;

default:
break;
}
}

下面為程式的demo結果


[圖3] 初始畫面


[圖4] 縮小



[圖5] 放大



[圖6] 旋轉


[圖7] 平移



[圖7] 翻轉



沒有留言:

張貼留言