关于c#:放大大图片?

Pinch-to-zoom on huge images?

我在http://forums.create.msdn.com

上找到了"捏到缩放"示例

这是xaml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <StackPanel>
                <TextBlock Text="Tap to center" Style="{StaticResource PhoneTextNormalStyle}"/>
                <TextBlock Text="Tap and hold to reset" Style="{StaticResource PhoneTextNormalStyle}"/>
                <TextBlock Text="Touch and move to drag" Style="{StaticResource PhoneTextNormalStyle}"/>
                <TextBlock Text="Pinch (touch with two fingers) to scale and rotate" Style="{StaticResource PhoneTextNormalStyle}" TextWrapping="Wrap"/>
                <TextBlock Text="Flick (drag and release the touch while still moving) will show flick data on bottom of screen." Style="{StaticResource PhoneTextNormalStyle}" TextWrapping="Wrap"/>
            </StackPanel>
            <TextBlock x:Name="flickData" Text="Flick:" Style="{StaticResource PhoneTextNormalStyle}" VerticalAlignment="Bottom"/>
            <Image x:Name="image" Source="/map.jpg" RenderTransformOrigin="0.5,0.5" CacheMode="BitmapCache">
                <Image.RenderTransform>
                    <CompositeTransform x:Name="transform"/>
                </Image.RenderTransform>
                <toolkit:GestureService.GestureListener>
                    <toolkit:GestureListener  
                        Tap="OnTap" Hold="OnHold"
                        DragStarted="OnDragStarted" DragDelta="OnDragDelta" DragCompleted="OnDragCompleted"
                        Flick="OnFlick"
                        PinchStarted="OnPinchStarted" PinchDelta="OnPinchDelta" PinchCompleted="OnPinchCompleted"/>
                </toolkit:GestureService.GestureListener>
            </Image>
        </Grid>

和cs源:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
public partial class GestureSample : PhoneApplicationPage
    {
        double initialAngle;
        double initialScale;

        public GestureSample()
        {
            InitializeComponent();
        }

        private void OnTap(object sender, GestureEventArgs e)
        {
            transform.TranslateX = transform.TranslateY = 0;
        }

        private void OnDoubleTap(object sender, GestureEventArgs e)
        {
            transform.ScaleX = transform.ScaleY = 1;
        }

        private void OnHold(object sender, GestureEventArgs e)
        {
            transform.TranslateX = transform.TranslateY = 0;
            transform.ScaleX = transform.ScaleY = 1;
            transform.Rotation = 0;
        }

        private void OnDragStarted(object sender, DragStartedGestureEventArgs e)
        {
            image.Opacity = 0.3;
        }

        private void OnDragDelta(object sender, DragDeltaGestureEventArgs e)
        {
            transform.TranslateX += e.HorizontalChange;
            transform.TranslateY += e.VerticalChange;
        }

        private void OnDragCompleted(object sender, DragCompletedGestureEventArgs e)
        {
            image.Opacity = 1.0;
        }

        private void OnPinchStarted(object sender, PinchStartedGestureEventArgs e)
        {
            Point point0 = e.GetPosition(image, 0);
            Point point1 = e.GetPosition(image, 1);
            Point midpoint = new Point((point0.X + point1.X) / 2, (point0.Y + point1.Y) / 2);
            image.RenderTransformOrigin = new Point(midpoint.X / image.ActualWidth, midpoint.Y / image.ActualHeight);
            initialAngle = transform.Rotation;
            initialScale = transform.ScaleX;
            image.Opacity = 0.8;
        }

        private void OnPinchDelta(object sender, PinchGestureEventArgs e)
        {
            transform.Rotation = initialAngle + e.TotalAngleDelta;
            transform.ScaleX = transform.ScaleY = initialScale * e.DistanceRatio;
        }

        private void OnPinchCompleted(object sender, PinchGestureEventArgs e)
        {
            image.Opacity = 1.0;
        }

        private void OnFlick(object sender, FlickGestureEventArgs e)
        {
            flickData.Text = string.Format("{0} Flick: Angle {1} Velocity {2},{3}",
                e.Direction, Math.Round(e.Angle), e.HorizontalVelocity, e.VerticalVelocity);
        }
    }

它对于小图像(小于2000x2000像素)效果很好。但在我的示例中,我有一张巨大的地铁地图(http://www.vasttrafik.se/upload/Linjekartor_hogupplost/Goteborg2010/Linjen?tskarta-101212.png或矢量http://www.vasttrafik.se/upload/Linjekartor_hogupplost/Goteborg2010 /Linjen?tskarta-101212.pdf)。如果用户可以缩放矢量图像,那就更好了,但是即使导入这么大的矢量也是一个严重的性能问题。

也许我可以将图像分成几个"多比例图像",并使用此http://dotnetbyexample.blogspot.com/2010/08/windows-phone-7-multi-touch-panzoom.html,但是我真的不知道如何使用他的课程:(

有什么想法吗?你们将如何解决这个问题?

谢谢

理查德


您的解决方案的理想方法是使用MultiScaleImage,它专门用于显示大图像数据。但是,为了使用MultiScaleImage,您需要以正确的格式准备好iamge数据。基本上,您需要对图像进行切片和重新缩放等操作,以便用户在放大和缩小图像时加载尽可能少的信息。

DeepZoom文档描述了该过程,并具有指向DeepZoom Composer工具的链接,您可以使用该工具来准备图像数据。

一旦您使用了MultiScaleImage方法,就可以使用Laurent的Multitouch Behavior(如果需要)来提供其他用户交互。


电话上的Silverlight UIElements有大小限制。如您所知,这是2000x2000像素。因此,任何一个控件都不能超出此范围。

如果必须使用大于此图像的图像,请查看MultiScaleImage

如果您使用的图像文件非常大,请注意潜在的内存问题。


您听说过Silverlight Deep-Zoom吗?

http://msdn.microsoft.com/zh-cn/library/cc645050(v = vs.95).aspx