老師最近讓做個小研究,其中有一部分是實現圖片的縮放功能,由於要在Web中實現,silverlight在圖形影像處理方面有很強的支援功能,索性就研究了一下,弄了個小Demo,分享給大家。還有些疑問向高手請教,先看下效果:
設計介面很簡單:
Code
<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>
<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>
後臺程式碼:
Code
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();
}
private void ChangeShow_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)//根據Soilder的值改變圖片的大小
{
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;
}
}
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();
}
private void ChangeShow_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)//根據Soilder的值改變圖片的大小
{
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製作向量圖)。