2014-12-05 45 views
0

我想将效果/过滤器应用于显示在我的视图中的图像,在内存中(不保存图像文件)。使用Caliburn.Micro以编程方式修改图像

我使用Caliburn.Micro作为MVVM框架。

我有这样的看法:

<UserControl x:Class="TestApplication.Views.MainView" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" 
      d:DesignHeight="300" 
      d:DesignWidth="300"> 
    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="*" /> 
      <ColumnDefinition Width="0.3*" /> 
     </Grid.ColumnDefinitions> 

     <Image 
      Grid.Column="0" 
      Stretch="Uniform" 
      Source="{Binding PreviewUrl}" 
      Margin="5" 
      x:Name="Preview" /> 

     <ContentControl 
      Grid.Column="1" 
      Margin="5" 
      x:Name="ImageManagement" /> 
    </Grid> 
</UserControl> 

而这个视图模型:

namespace TestApplication.ViewModels 
{ 
    using System; 
    using System.ComponentModel.Composition; 
    using System.Linq; 
    using Caliburn.Micro; 
    using ImageProcessor; 
    using ImageProcessor.Plugins.Popart; 
    using PropertyChanged; 
    using TestApplication.Events; 
    using TestApplication.Models; 

    [ImplementPropertyChanged] 
    [Export(typeof(MainViewModel))] 
    public class MainViewModel : PropertyChangedBase, IHandle<FileSelectedEvent>, IHandle<FilterChangedEvent> 
    { 
     private readonly IEventAggregator events; 

     private bool hasCustomImage = false; 

     [ImportingConstructor] 
     public MainViewModel(IEventAggregator events) 
     { 
      this.events = events; 
      this.events.Subscribe(this); 

      this.ImageManagement = new ImageManagementViewModel(events); 
      this.ImageManagement.SettingsEnabled = false; 
      this.PreviewUrl = "pack://application:,,,/Resources/placeholder.jpg"; 
     } 

     public ImageManagementViewModel ImageManagement { get; set; } 

     public String PreviewUrl { get; set; } 

     public void Handle(FilterChangedEvent message) 
     { 
      this.ApplyFilter(new Filter(message)); 
     } 

     public void Handle(FileSelectedEvent message) 
     { 
      this.PreviewUrl = message.FilePath; 
      this.hasCustomImage = true; 
      this.ImageManagement.SettingsEnabled = true; 

      this.ApplyFilter(Filter.Default); 
     } 

     private void ApplyFilter(Filter filter) 
     { 
      if (this.hasCustomImage) 
      { 
       using (ImageFactory factory = new ImageFactory()) 
       { 
        factory.Load(this.PreviewUrl); 
        // TODO: apply a filter using factory 

        // TODO: use this processed image 
       } 
      } 
     } 
    } 
} 

在确定applyFilter方法,我需要绑定的处理System.Drawing.Image到视图的图像源,但我绝对没有想法该怎么做(我还不熟悉所有wpf方面)。

+0

不知道,但你也许可以做到这一点通过结合'绘制'对象而不是'图像'或将源设置为字符串。您可以将过滤图像绘制到“Drawing”对象上 - 查看文档:http://msdn.microsoft.com/en-us/library/ms753308(v=vs.110).aspx – Charleh 2014-12-05 17:54:22

+0

更多信息:http ://msdn.microsoft.com/en-us/library/ms753315(v = vs.110)的.aspx – Charleh 2014-12-05 17:54:47

回答

1

使用@ Charleh的意见和各种other posts,我已经能够找到如何应该如何工作的:

<Image 
    Grid.Column="0" 
    Stretch="Uniform" 
    Margin="5" 
    Source="{Binding Preview}" /> 

public class MainViewModel : PropertyChangedBase, IHandle<FileSelectedEvent>, IHandle<WarholFilterChangedEvent> 
{ 
    private readonly IEventAggregator events; 

    private bool hasCustomImage = false; 

    private string sourceUrl; 

    [ImportingConstructor] 
    public MainViewModel(IEventAggregator events) 
    { 
     this.events = events; 
     this.events.Subscribe(this); 

     this.ImageManagement = new ImageManagementViewModel(events); 
     this.ImageManagement.WarholSettingsEnabled = false; 

     this.Preview = new BitmapImage(new Uri("pack://application:,,,/Resources/placeholder.jpg")); 
    } 

    public ImageManagementViewModel ImageManagement { get; set; } 

    public BitmapImage Preview { get; set; } 

    public void Handle(WarholFilterChangedEvent message) 
    { 
     this.ApplyFilter(new WarholFilter(message)); 
    } 

    public void Handle(FileSelectedEvent message) 
    { 
     this.sourceUrl = message.FilePath; 
     this.hasCustomImage = true; 
     this.ImageManagement.WarholSettingsEnabled = true; 

     this.ApplyFilter(WarholFilter.Default); 
    } 

    private void ApplyFilter(WarholFilter filter) 
    { 
     if (this.hasCustomImage) 
     { 
      using (ImageFactory factory = new ImageFactory()) 
      { 
       factory.Load(this.sourceUrl); 
       PolychromaticParameters parameters = new PolychromaticParameters(); 
       parameters.Number = filter.ColorsNumber; 
       parameters.Colors = filter.Colors.Select(c => System.Drawing.Color.FromArgb(c.R, c.G, c.B)).ToArray(); 
       parameters.Thresholds = filter.Thresholds.ToArray(); 
       factory.Polychromatic(parameters); 

       BitmapImage img = new BitmapImage(); 
       using (MemoryStream str = new MemoryStream()) 
       { 
        img.BeginInit(); 
        img.CacheOption = BitmapCacheOption.OnLoad; 
        factory.Save(str); 
        str.Seek(0, SeekOrigin.Begin); 
        img.StreamSource = str; 
        img.EndInit(); 
       } 

       this.Preview = img; 
      } 
     } 
    } 
}