• 青春赌徒   2014/8/19 13:25:00
  • Silverlight开发实践--实现图片缩放功能
  • 关键字: Silverlight 图片 缩放
  • 老师最近让做个小研究,其中有一部分是实现图片的缩放功能,由于要在Web中实现,silverlight在图形图像处理方面有很强的支持功能,索性就研究了一下,弄了个小Demo,分享给大家。还有些疑问向高手请教,先看下效果:


     设计界面很简单:

    <UserControl x:Class="PicShowZoom.Page"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        Width="1000" Height="600">
        <Grid x:Name="LayoutRoot" Background="White">
            <Grid.RowDefinitions>
                <RowDefinition Height="50"></RowDefinition>
                <RowDefinition Height="*"></RowDefinition>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>

            <Canvas x:Name="Show" Background="Black" Width="900" Height="500" Grid.Row="1" Grid.Column="0">
                <ScrollViewer Height="430" Width="880" Canvas.Left="8" Canvas.Top="20" x:Name="img_Scroll" HorizontalScrollBarVisibility="Hidden"  VerticalScrollBarVisibility="Hidden" TabNavigation="Local">
                    <Image Stretch="Uniform" MouseLeftButtonDown="img_c_MouseLeftButtonDown"  MouseLeftButtonUp="img_c_MouseLeftButtonUp"  RenderTransformOrigin="0.5,0.5" x:Name="img_c" Source="78_104606.jpg" Cursor="Hand" Loaded="img_c_Loaded">
                        <Image.RenderTransform>
                            <TransformGroup>
                                <ScaleTransform x:Name="img_scale" ScaleX="1" ScaleY="1"/>
                                <SkewTransform/>
                                <RotateTransform Angle="0"/>
                                <TranslateTransform X="0" x:Name="img_translate"/>
                            </TransformGroup>
                        </Image.RenderTransform>
                    </Image>
                </ScrollViewer>
            </Canvas>
            <Slider x:Name="ChangeShow" Height="20" Width="500" Grid.Row="0" Grid.Column="0" ValueChanged="ChangeShow_ValueChanged" Maximum="1000" Minimum="0"></Slider>
        </Grid>
    </UserControl>


    后台代码:

    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
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    public partial class Page : UserControl
        {
            MouseEventHandler meh;//声明一个事件委托
            Point MouseDownAt;//二维空间内的X,Y的坐标对
            double img_actualWidth = 0;//图片宽度
            double img_actualHeight = 0;//图片高度
     
            public Page()
            {
                meh = new MouseEventHandler(img_c_MouseMove);
                InitializeComponent();
            }
    //根据Soilder的值改变图片的大小
            private void ChangeShow_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
            {
                if (img_scale != null)
                {
                    string t = e.NewValue.ToString();
    //获取Soilder的值,并根据值算出放大或缩小图片的大小
                    img_c.Width = (ChangeShow.Value / 500) * img_actualWidth;
                    img_c.Height = (ChangeShow.Value / 500) * img_actualHeight;
     
                    string LeftT = "";
                    string RightT = "";
                    int index = t.IndexOf('.');
     
                    if (index != -1)//根据图片的大小计算出图片所在的位置
                    {
                        LeftT = t.Substring(0, index);
                        RightT = t.Substring(index + 1, t.Length - index - 1);
                        if (RightT.Length > 1)
                        {
                            RightT = RightT.Substring(0, 1);
                        }
                    }
                    else
                    {
                        LeftT = t;
                        RightT = "0";
                    }
                }
            }
            /// <summary>
            /// 通过编写鼠标按下,抬起,移动事件实现图片的拖动。
            /// </summary>
            private void img_c_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                img_c.MouseMove += meh;
                MouseDownAt = e.GetPosition(null);//获取鼠标当前坐标的位置
                img_c.CaptureMouse();//在此元素上强制捕获鼠标。如果成功捕获了鼠标,
    //则为 true;否则为 false。这句话可以没有,但是建议加上。
            }
     
            private void img_c_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
            {
                img_c.MouseMove -= meh;
                img_c.ReleaseMouseCapture();//移出对鼠标的捕获
            }
     
            void img_c_MouseMove(object sender, MouseEventArgs e)
            {
                Point p = e.GetPosition(null);
                img_Scroll.ScrollToVerticalOffset(img_Scroll.VerticalOffset -
     ((p.Y - MouseDownAt.Y) * 1.2));
    //将 ScrollViewer 内的内容滚动到指定的垂直偏移量位置。
                img_Scroll.ScrollToHorizontalOffset(img_Scroll.HorizontalOffset -
     ((p.X - MouseDownAt.X) * 1.2));
    //将 ScrollViewer 内的内容滚动到指定的水平偏移量位置。
                MouseDownAt = p;
            }
            /// <summary>
            /// 初始化变量
            /// </summary>
            private void img_c_Loaded(object sender, RoutedEventArgs e)
            {
                Stretch s = img_c.Stretch;
                img_c.Stretch = Stretch.None;
                img_actualHeight = img_c.ActualHeight;
                img_actualWidth = img_c.ActualWidth;
                img_c.Stretch = s;
     
                ChangeShow.Value = 500;
            }
        }
     
    代码中我作了解释,不是很难。毕竟这个实现的算法比较简单。大致的效果就是这样,小弟还有些问题请教高手,希望大虾们多多指导。

    (1)如果图片的大小超过了显示区域,或者图片的大小已经超过了实际的大小,那么没有显示的部分显示在了哪里?是放在内存中吗?如果无限的增大图片,会不会导致IE的瘫掉?Silverlight内部对图像作了什么处理吗?

    (2)现在的增大图片,只是将图片拉伸,求一个更好的算法,实现矢量图形最大。(如何实现矢量图形的放大,如何用SL制作矢量图)。