之前的文章有提到 WPF提供2D Transform的功能, 而這樣的功能很適合發展應用程式的手勢(Gesture)操控, 下面, 我就舉一個簡單的圖片瀏覽應用程式, 透過一些手勢操作, 來對圖片進行放大, 縮小, 旋轉, 翻轉和平移.
環境設定:
以下是我的環境設定:
- 觸控裝置 - Quanta Optical Touch Monitor
- Touch API - OTMUT(Optical Touch Monitor Utility Toolkit), 這隻Touch API是我們自行撰寫的dll, 主要用來取得觸控點和手勢的資料, 功能類似Windows 7 Touch SDK
視窗和控制項的設定:
開啟一個WPF專案, 然後從Toolbox中將一個Image的控制項拉到視窗中, 如下圖所示:
在專案中新增一個Image的資料夾,並把要顯示圖片放進去, 然後在XAML檔中設定圖片的路徑, 如下所示:
<Grid Background="Beige"> <Image Margin="150" Name="image1" Stretch="Fill" Source="Image\Koala.jpg"> </Image> </Grid>
設定Image 2D Transform:
我們在XAML檔中, 先設定Image的RotaeTransform, ScaleTransform和TranslateTransform, 程式碼如下所示:
<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] 翻轉
沒有留言:
張貼留言