c# - Modify image programmatically using Caliburn.Micro -
i want apply effect/filter image displayed in view, in memory (without saving image file).
i using caliburn.micro mvvm framework.
i have view:
<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>
and 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 filter using factory // todo: use processed image } } } } }
in applyfilter method, need bind processed system.drawing.image
view's image source, have absolutely no idea how (i'm not familiar wpf aspects yet).
using @charleh's comments , various other posts, have been able find how how should work :
<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; } } } }
Comments
Post a Comment