2014-12-05 2 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> 

И это ViewModel:

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' вместо« Image »или установки источника в виде строки. Вы можете нарисовать отфильтрованное изображение на объект «Рисование» - проверьте документы: http://msdn.microsoft.com/en-us/library/ms753308(v=vs.110).aspx – Charleh

+0

Подробнее здесь: http : //msdn.microsoft.com/en-us/library/ms753315 (v = vs.110) .aspx – Charleh

ответ

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; 
      } 
     } 
    } 
} 
Смежные вопросы