無論什麼東西,但凡太大了,老是讓人又愛又恨啊!(頗有道理的樣子,你們鼓掌└( ̄  ̄└)(┘ ̄  ̄)┘)async
猿:老闆,如今這社會啊,真是浮躁啊,以前仍是什麼1080P,而後就到了2K,如今又到了4K……他們是想把毛孔都看清楚?ide
老闆:能不能作?spa
猿:已經作好了啊,可是……反正此次咱們能說會道的X經理也沒能忽……說服客戶。線程
老闆:是什麼問題嘛,說出來我幫你想一想辦法。(老闆真是好人啊,語重心長)調試
猿(ノへ ̄、):客戶不是升級了4K攝像機嗎,哎喲,那玩意兒,老長了,就跟火箭筒似的,扛起來那感受(ง •̀_•́)ง,真是拉風……code
老闆:咳咳……orm
猿:嗯,4K,拍出來的照片分辨率4096x2160,一張圖片就有30多M,而後……咱們的程序掛了,內存崩了。╮( ̄▽ ̄")╭blog
老闆:嗯,這個問題嘛……圖片
猿:昨晚我加班到凌晨三點,各類調試,各類查資料,終於搞定了,今天早上讓小X過去更換了,而後……內存
老闆:辛苦了,辦公室裏有吃的,晚上加班儘管吃!
猿:( ̄▽ ̄")……
猿:而後內存是沒爆了,可是大圖出來的使用有2~3秒的空白……也不能操做……X經理正在給咱們爭取時間……
老闆:這樣啊,我給你一個我朋友的電話,他也是搞軟件的,很牛X的……
嗯,各位童鞋,看到這裏就應該明白,對話已經結束。這就開始咱們的代碼……
XAML咱們就簡單點:用ListView作個列表,一個用於顯示大圖的Image,一個遮罩層Border
1 <Grid> 2 <Grid.ColumnDefinitions> 3 <ColumnDefinition Width="420"/> 4 <ColumnDefinition Width="*"/> 5 </Grid.ColumnDefinitions> 6 <ListView x:Name="lvImages" ScrollViewer.CanContentScroll="False" SelectionChanged="lvImages_SelectionChanged"> 7 <ListView.ItemTemplate> 8 <DataTemplate> 9 <Image Source="{Binding Converter={StaticResource ImageSourceConverter}, Mode=OneTime,ConverterParameter=400}" Width="400" /> 10 </DataTemplate> 11 </ListView.ItemTemplate> 12 </ListView> 13 <ScrollViewer Grid.Column="1" > 14 <ScrollViewer.Background> 15 <ImageBrush ImageSource="{Binding SelectedItem, ElementName=lvImages,Converter={StaticResource ImageSourceConverter}}" Stretch="Uniform"/> 16 </ScrollViewer.Background> 17 <Image Name="bigImage" MouseWheel="bigImage_MouseWheel" RenderTransformOrigin="0.5,0.5"> 18 <Image.RenderTransform> 19 <ScaleTransform x:Name="scale"/> 20 </Image.RenderTransform> 21 </Image> 22 </ScrollViewer> 23 <Border Name="conver" Background="#60000000" Visibility="Hidden" Grid.ColumnSpan="2"> 24 <Path Data="M30.330999,48.228C31.299783,48.422099 32.299767,48.531501 33.330949,48.531501 34.360932,48.531501 35.363415,48.422099 36.335999,48.228L36.335999,66.659003 30.330999,66.659003z M43.268281,44.750998L52.394999,60.832034 47.175917,63.796996 38.038999,47.713359C39.994767,47.070048,41.753928,46.067427,43.268281,44.750998z M23.209264,44.598998C24.700174,45.940215,26.447487,46.971526,28.389,47.638133L19.002135,63.568 13.824999,60.518466z M47.700966,38.078002L63.757998,47.260428 60.782928,52.473998 44.726998,43.300773C46.044784,41.78905,47.055174,40.028529,47.700966,38.078002z M18.923298,37.936999C19.546999,39.89281,20.5418,41.665007,21.844,43.188594L5.7032509,52.206 2.7709999,46.960906z M18.4298,30.342997C18.240998,31.305102 18.131697,32.306304 18.131697,33.328299 18.131697,34.360797 18.237098,35.373698 18.435,36.3502L0.0077514648,36.370997 0,30.365096z M66.659098,30.285998L66.666998,36.294497 48.231798,36.313998C48.4272,35.347804 48.531301,34.352805 48.531301,33.328002 48.531301,32.294097 48.4272,31.284898 48.227999,30.308202z M60.963728,14.451999L63.895998,19.696799 47.743868,28.718999C47.120075,26.764499,46.123985,24.996299,44.817999,23.474099z M5.8831024,14.181999L21.936999,23.357735C20.616765,24.868125,19.607615,26.627213,18.960647,28.578999L2.9039993,19.403264z M47.663984,3.0889991L52.839998,6.1383522 43.456712,22.064999C41.96595,20.723838,40.213178,19.687466,38.276999,19.020785z M19.487081,2.8649989L28.617,18.94893C26.66778,19.585601,24.902254,20.590758,23.394619,21.910998L14.261999,5.8297189z M30.330999,0L36.335999,0 36.335999,18.430999C35.363416,18.2357 34.36093,18.127599 33.330949,18.127599 32.299765,18.127599 31.299782,18.2357 30.330999,18.430999z" 25 Stretch="Uniform" Margin="200" Fill="Red" RenderTransformOrigin="0.5,0.5"> 26 <Path.RenderTransform> 27 <RotateTransform x:Name="rotate" Angle="0"/> 28 </Path.RenderTransform> 29 </Path> 30 </Border> 31 </Grid>
後臺代碼:
1 private void Window_Loaded(object sender, RoutedEventArgs e) 2 { 3 //高清大圖,你懂的。 4 var path = Combine(AppDomain.CurrentDomain.BaseDirectory, "images");//using static System.IO.Path; 5 var files = Directory.GetFiles(path); 6 lvImages.ItemsSource = files; 7 } 8 9 10 private async void lvImages_SelectionChanged(object sender, SelectionChangedEventArgs e) 11 { 12 //在選中項更改時進行處理, 13 if (lvImages.SelectedIndex > -1) 14 { 15 //選中的項 16 var current = e.AddedItems[0]; 17 18 bigImage.Source = null; 19 20 //坐和放寬,很快就好。 21 conver.Visibility = Visibility.Visible; 22 rotate.BeginAnimation(RotateTransform.AngleProperty, new DoubleAnimation(360, TimeSpan.FromMilliseconds(1000)) 23 { RepeatBehavior = RepeatBehavior.Forever }); 24 25 //await一下 26 try 27 { 28 var source = await Task.Run<ImageSource>(() => 29 { 30 var p = current.ToString(); 31 var s = new BitmapImage(); 32 s.BeginInit(); 33 s.CacheOption = BitmapCacheOption.OnLoad; 34 //打開文件流 35 using (var stream = File.OpenRead(p)) 36 { 37 s.StreamSource = stream; 38 s.EndInit(); 39 //這一句很重要,少了UI線程就不認了。 40 s.Freeze(); 41 } 42 return s; 43 }); 44 //出爐 45 bigImage.Source = source; 46 } 47 catch { } 48 //好了,不用轉了 49 rotate.BeginAnimation(RotateTransform.AngleProperty, null); 50 conver.Visibility = Visibility.Hidden; 51 } 52 else 53 { 54 var s = bigImage.Source; 55 s = null; 56 bigImage.Source = null; 57 } 58 } 59 60 private void bigImage_MouseWheel(object sender, MouseWheelEventArgs e) 61 { 62 //高清大圖嘛,固然要放大了仔細看看 63 var d = e.Delta / 1000.0; 64 if (scale.ScaleX + d < 1) 65 { 66 scale.ScaleX = scale.ScaleY = 1; 67 return; 68 } 69 scale.ScaleX += d; 70 scale.ScaleY += d; 71 }
一個簡單的ImageSourceConverter:
1 public class ImageSourceConverter : IValueConverter 2 { 3 public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 4 { 5 if (value == null) 6 return value; 7 var source = new BitmapImage(); 8 source.BeginInit(); 9 source.UriSource = new Uri(value.ToString(), UriKind.Absolute); 10 //設置解碼的分辨率大小,也就是搞個縮略圖 11 source.DecodePixelWidth = parameter != null ? int.Parse(parameter.ToString()) : 100; 12 source.EndInit(); 13 return source; 14 15 } 16 17 public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 18 { 19 throw new NotImplementedException(); 20 } 21 }
看圖: