none
C# + XAML 图片的放大和缩小 RRS feed

  • 问题

  • 用flipview浏览图片时,想要实现手指控制图片的放大和缩小(即手指分开放大,手指聚合缩小),这个应该怎么操作?

    有没有什么可以参考的东西呢?

    2012年8月7日 3:53

答案

  • 可以参考下:

    <Grid RenderTransformOrigin="0.5,0.5">
                <Grid.RenderTransform>
                    <CompositeTransform x:Name="PhotoTransform" />
                </Grid.RenderTransform>
                <Image x:Name="Photo" Margin="20" Width="600"/>
            </Grid>

       private void Photo_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
            {
                // Translate the photo
                PhotoTransform.TranslateX += e.Delta.Translation.X;
                PhotoTransform.TranslateY += e.Delta.Translation.Y;

                // Scale the photo
                PhotoTransform.ScaleX *= e.Delta.Scale;
                PhotoTransform.ScaleY *= e.Delta.Scale;

                // Constrain scale factor
                PhotoTransform.ScaleX = Math.Min(PhotoTransform.ScaleX, 4.0);
                PhotoTransform.ScaleY = Math.Min(PhotoTransform.ScaleY, 4.0);
                PhotoTransform.ScaleX = Math.Max(PhotoTransform.ScaleX, 1.0);
                PhotoTransform.ScaleY = Math.Max(PhotoTransform.ScaleY, 1.0);
            }


    2012年8月7日 13:37
  • Hi,

    第一个问题,我不知道你看两个图片的时候是在两个不同的页面通过导航的方式进行切换的还是其他的方式,如果通过导航的话,默认NavigationCacheMode=diable每次无论是一开始进入还是返回都回调用LoadState,所以不会有还放大的情况,如果是放大的话你可以检查一下你NavigationCacheMode的选项。

    如果是其他情况比如一个页面下,那我建议你可以把初始数据存储在LocalSetting中,每次观看图片的时候调用(Loaded方法)。

    第二个缩略图的问题,同样的我不太清楚你的做法,但我个人推荐的是通过导航的方法,即缩略图在一个页面,大图在另一个,通过导航的方式过去。导航用this.Frame.Navigate来做,不要用比如直接设置Window.Current.Content来做,容易出现一些无法预料的问题。

    Navigate可以传一个对象过去(object),在这里我比较推荐的做法是,把资源存储在App.Resources中,然后把图片的索引穿过去,比如一个数字,一个字符串等等。这样的优点有两个,第一,图片内存占的很多,如果读进去之后通过页面直接传浪费很多内存,这样把缩略图读进去传个索引过去,需要的时候读大图,很节约内存。第二,传一个复杂的类(除了数字,string,guid一些基本类型)或者你自己定义的类,虽然另一个页面能够接到,但是在Suspend的时候会出现错误,大意是无法存储一个不能序列化的类。这个时候传递过去的东西就需要你来自己序列化了,虽然不是很麻烦,但这样并不推荐。

    当然如果你想传一个类过去并且自己序列化的话,方法可以参考下面这个帖子:

    http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/46b19d4a-60a6-48d3-875d-1ce00993760d

    Hope this helps


    Aaron Xue [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2012年8月9日 11:08
    版主

全部回复

  • 来个人回答下嘛~TT
    2012年8月7日 8:59
  • 可以参考下:

    <Grid RenderTransformOrigin="0.5,0.5">
                <Grid.RenderTransform>
                    <CompositeTransform x:Name="PhotoTransform" />
                </Grid.RenderTransform>
                <Image x:Name="Photo" Margin="20" Width="600"/>
            </Grid>

       private void Photo_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
            {
                // Translate the photo
                PhotoTransform.TranslateX += e.Delta.Translation.X;
                PhotoTransform.TranslateY += e.Delta.Translation.Y;

                // Scale the photo
                PhotoTransform.ScaleX *= e.Delta.Scale;
                PhotoTransform.ScaleY *= e.Delta.Scale;

                // Constrain scale factor
                PhotoTransform.ScaleX = Math.Min(PhotoTransform.ScaleX, 4.0);
                PhotoTransform.ScaleY = Math.Min(PhotoTransform.ScaleY, 4.0);
                PhotoTransform.ScaleX = Math.Max(PhotoTransform.ScaleX, 1.0);
                PhotoTransform.ScaleY = Math.Max(PhotoTransform.ScaleY, 1.0);
            }


    2012年8月7日 13:37
  • 感谢John厦门给出的方法,这是一种,还有一种比较简单但有局限性的方法,如果你只想放大缩小可以使用。

    ScrollViewer已经实现了手势放大或者缩小只要将ZoomMode设为Enabled即可:

    例如:

      <ScrollViewer ZoomMode="Enabled">
                <Image Name="Photo" Height="600" Width="600" Margin="20" Source="./image/test1.jpg" />
            </ScrollViewer>
    Hope this helps
     

    Aaron Xue [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已建议为答案 john_shen 2012年8月9日 7:49
    • 已标记为答案 neal_young 2012年8月9日 8:34
    • 取消答案标记 neal_young 2012年8月9日 10:05
    2012年8月9日 7:22
    版主
  • 感谢John厦门给出的方法,这是一种,还有一种比较简单但有局限性的方法,如果你只想放大缩小可以使用。

    ScrollViewer已经实现了手势放大或者缩小只要将ZoomMode设为Enabled即可:

    例如:

      <ScrollViewer ZoomMode="Enabled">
                <Image Name="Photo" Height="600" Width="600" Margin="20" Source="./image/test1.jpg" />
            </ScrollViewer>
    Hope this helps
     

    Aaron Xue [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    感谢楼上两位的回答!

    我用FlipView和ScrollViewer这两个控件配合来实现浏览图片集,并且可以缩放。

    但是有一个问题就是当我看完图片1,并且放大之后,点击看图片2,再返回看图片1,这个时候图片1还是处于放大的状态。

    我想变成返回重新看图片1的时候,图片1是原本的大小,这个应该怎么解决呢??

    2012年8月9日 8:31
  • 对了,还有一个问题,当我有一个图片集的缩略图,比如图片1、2、3、4、5等等,

    然后我点击图片2想进入图片浏览页,但是每次总是要从1开始看起。就是说不管点击哪一个照片,FlipView.SelectedIndex总是0开始。我想点击2的时候就从2开始看起。

    还是用的FlipView和ScrollViewer这两个控件实现的。这个问题怎么解决呢?

    2012年8月9日 8:34
  • 贴一下代码吧……

       <FlipView
                x:Name="imageFlipView" Grid.Row="0" Grid.RowSpan="2" Grid.Column="1" Grid.ColumnSpan="1" Height="700" Width="1246"
                SelectionChanged="imageFlipView_SelectionChanged_1" 
                VerticalAlignment="Center" HorizontalAlignment="Center" IsHitTestVisible="True"  >
                    <FlipView.ItemTemplate>
                        <DataTemplate>
                         <ScrollViewer x:Name="imageScrollViewer" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" HorizontalScrollMode="Enabled"
                                       VerticalScrollMode="Enabled" HorizontalAlignment="Stretch"  VerticalAlignment="Stretch"
                                       MinZoomFactor="0.5" MaxZoomFactor="5" >
                                <Image Tapped="Image_Tapped_1"  Source="{Binding AURL}"    Stretch="None" />
                         </ScrollViewer>
                        </DataTemplate>
                    </FlipView.ItemTemplate>
          </FlipView>
    Aaron Xue来给我解答一下嘛~



    2012年8月9日 9:28
  • Hi,

    第一个问题,我不知道你看两个图片的时候是在两个不同的页面通过导航的方式进行切换的还是其他的方式,如果通过导航的话,默认NavigationCacheMode=diable每次无论是一开始进入还是返回都回调用LoadState,所以不会有还放大的情况,如果是放大的话你可以检查一下你NavigationCacheMode的选项。

    如果是其他情况比如一个页面下,那我建议你可以把初始数据存储在LocalSetting中,每次观看图片的时候调用(Loaded方法)。

    第二个缩略图的问题,同样的我不太清楚你的做法,但我个人推荐的是通过导航的方法,即缩略图在一个页面,大图在另一个,通过导航的方式过去。导航用this.Frame.Navigate来做,不要用比如直接设置Window.Current.Content来做,容易出现一些无法预料的问题。

    Navigate可以传一个对象过去(object),在这里我比较推荐的做法是,把资源存储在App.Resources中,然后把图片的索引穿过去,比如一个数字,一个字符串等等。这样的优点有两个,第一,图片内存占的很多,如果读进去之后通过页面直接传浪费很多内存,这样把缩略图读进去传个索引过去,需要的时候读大图,很节约内存。第二,传一个复杂的类(除了数字,string,guid一些基本类型)或者你自己定义的类,虽然另一个页面能够接到,但是在Suspend的时候会出现错误,大意是无法存储一个不能序列化的类。这个时候传递过去的东西就需要你来自己序列化了,虽然不是很麻烦,但这样并不推荐。

    当然如果你想传一个类过去并且自己序列化的话,方法可以参考下面这个帖子:

    http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/46b19d4a-60a6-48d3-875d-1ce00993760d

    Hope this helps


    Aaron Xue [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2012年8月9日 11:08
    版主
  • Hi,

    第一个问题,我不知道你看两个图片的时候是在两个不同的页面通过导航的方式进行切换的还是其他的方式,如果通过导航的话,默认NavigationCacheMode=diable每次无论是一开始进入还是返回都回调用LoadState,所以不会有还放大的情况,如果是放大的话你可以检查一下你NavigationCacheMode的选项。

    如果是其他情况比如一个页面下,那我建议你可以把初始数据存储在LocalSetting中,每次观看图片的时候调用(Loaded方法)。

    第二个缩略图的问题,同样的我不太清楚你的做法,但我个人推荐的是通过导航的方法,即缩略图在一个页面,大图在另一个,通过导航的方式过去。导航用this.Frame.Navigate来做,不要用比如直接设置Window.Current.Content来做,容易出现一些无法预料的问题。

    Navigate可以传一个对象过去(object),在这里我比较推荐的做法是,把资源存储在App.Resources中,然后把图片的索引穿过去,比如一个数字,一个字符串等等。这样的优点有两个,第一,图片内存占的很多,如果读进去之后通过页面直接传浪费很多内存,这样把缩略图读进去传个索引过去,需要的时候读大图,很节约内存。第二,传一个复杂的类(除了数字,string,guid一些基本类型)或者你自己定义的类,虽然另一个页面能够接到,但是在Suspend的时候会出现错误,大意是无法存储一个不能序列化的类。这个时候传递过去的东西就需要你来自己序列化了,虽然不是很麻烦,但这样并不推荐。

    当然如果你想传一个类过去并且自己序列化的话,方法可以参考下面这个帖子:

    http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/46b19d4a-60a6-48d3-875d-1ce00993760d

    Hope this helps


    Aaron Xue [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    没有特别看明白诶~

    我用的方法就是上面代码中帖出来的那样,C#文件中传递一个图像合集的uri到flipview.sources就好了……

    没有用到导航的方法。

    说起来导航的方法适合用来显示图像库吗

    2012年8月13日 2:56