zoukankan      html  css  js  c++  java
  • 【全面解析DeepZoom 之三】建立DeepZoom应用

                            【全面解析DeepZoom 之三】建立DeepZoom应用
                                                周银辉

    今天介绍一下如何建立一个DeepZoom应用。如果你用过DeepZoomComposer,你会发现在DeepZoomComposer中导出的时候“CreateCollection ”选项。这里决定了你导出的是一张整图还是一个图片集合,关于导出整图,你可以参考大V初试Deep Zoom Composer(Step by Step|More Pictures)(超酷+必试) 这篇文章,写得很不错(建议你阅读一下,因为与其重复的内容我将省略了)。关于图片集合下面会讲到。
    与导出整图不一样,你不能这样使用:
    <MultiScaleImage
                  x:Name="msi"
                  ViewportWidth="1.0"
                  Source="/XXXX/info.bin" MouseLeftButtonDown="msi_MouseLeftButtonDown" MouseLeftButtonUp="msi_MouseLeftButtonUp" MouseMove="msi_MouseMove"/>
    而应该将info.bin替换成:items.bin,在导出的文件中你会找到该文件,这表示你导出的是一个集合。
    这时运行你的程序你变可以看到一个图片集合显示在那里了,但可惜的是没有任何交互。在那之前我们先了解一下MultiScaleImage的几个重要属性(我不知道是不是我的Silverlight SDK版本不对,在MultiScaleImage中其关键的几个属性、方法与事件没有相关注释,所以有必要将我对这几个属性、方法、事件的理解列举一下)
    Source:即DeepZoomComposer导出的文件(单个文件为Info.Bin,集合为Items.Bin)
    SubImages:子图片,如果DeepZoomComposer导出的为集合的话,其将集合中每个元素作为一个MultiScaleSubImage对象存储在这个集合中。对子图片的操作就全靠它了。
    UsingSprings:是否启用其默认动画(就是那中很飘逸的感觉,取消则比较生硬了)
    Viewport: 视口位置(可以简单理解成眼睛所在位置,有过3D编程经验的比较容易理解)
    ViewportWidth:视口宽度,视口越宽看到的东西越到(感觉上离图片越远,或图片缩小了)
    AspectRatio:宽高比。
    ElementToLogicPoint():从元素坐标(物理坐标)转换为逻辑坐标 (元素坐标则是我们平时所说的普通坐标,逻辑坐标则是指元素左上角为0,0点,右下角为1,1点而言的相对坐标)
    LogicToElementPoint():与上述相反。
    ZoomAboutLogicPoint(double, double, double):按逻辑坐标缩放,第一个参数指定缩放增量,后两个参数指定缩放中心。
    MotionFinished事件:动画结束(或者说当你操作图片或子图后其运动结束)

    关于子图:
    每个子图是一个MultiScaleSubImage对象,其在MultiScaleImage的SubImages属性中

    如何移动子图位置:
    你可以通过指定该子图的ViportOrgin属性来指定它的位置,比如
    subImage.ViportOrgin  = new Point(x,y);
    所以如果你想将子图像WPF中一样排列成Grid元素一样,没办法,一个一个计算x,y然后指定吧。

    如何缩放子图:
    你可以通过子图的ViewportWidth属性来控制,值越大子图就越小。

    如何显示或隐藏子图:
    没有visibility或相关属性,但你可以通过设置其Opacity(不透明度)来实现。

    如何获取指定子图的位置和大小(Rect)
    参考这个方法:
            private Rect GetSubImageRect(MultiScaleImage msi, int index)
            
    {
                
    if (index < 0 || index >= msi.SubImages.Count)
                
    {
                    
    return Rect.Empty;
                }


                MultiScaleSubImage image 
    = msi.SubImages[index];
                
    double scaleBy = 1 / image.ViewportWidth;

                
    return new Rect(-image.ViewportOrigin.X * scaleBy,
                    
    -image.ViewportOrigin.Y * scaleBy,
                    scaleBy,
                    (
    1 / image.AspectRatio) * scaleBy);
            }


    如何根据X,Y坐标得到相应位置处的子图:
    参考这个方法:
            private int GetImageIndexFromPosition(MultiScaleImage msi, Point pt)
            
    {
                pt 
    = msi.ElementToLogicalPoint(pt);

                
    for (int i = 0; i < msi.SubImages.Count; i++)
                
    {
                    MultiScaleSubImage image 
    = msi.SubImages[i];
                    
    double scaleBy = 1 / image.ViewportWidth;
                    Rect imageRect 
    = this.GetSubImageRect(msi, i);
                    
    if (imageRect.Contains(pt))
                    
    {
                        
    return i;
                    }

                }


                
    return -1;
            }


    相信有了这些知识就已经能做出不错的效果了哈:)关于如何分组子图将在本系列的后续随笔中讲解,谢谢



                 
  • 相关阅读:
    11.2---字符串数组排序,删除变位词(CC150)
    9.10---堆箱子问题(CC150)
    9.9---n皇后问题(CC150)
    11.1---有序数组合并(CC150)
    9.8---硬币问题(CC150)
    7.7---找只含3,5,7的数(CC150)
    17.1---编写一个函数交换两个变量的值(CC150)
    7.6--找过点最多的直线(CC150)
    7.5---两个正方形分成对半的直线(CC150)
    9.5---括号是否有效(CC150)
  • 原文地址:https://www.cnblogs.com/zhouyinhui/p/1153371.html
Copyright © 2011-2022 走看看